reditect to order

This commit is contained in:
2026-01-14 21:08:23 -03:00
parent d893114e38
commit a3e4fe887d
22 changed files with 1105 additions and 1157 deletions

View File

@@ -56,6 +56,7 @@ app.include_router(orgs.billing, prefix='/orgs')
app.include_router(orgs.custom_pricing, prefix='/orgs')
app.include_router(orgs.scheduled, prefix='/orgs')
app.include_router(orgs.submissions, prefix='/orgs')
app.include_router(orgs.seats, prefix='/orgs')
app.include_router(orgs.users, prefix='/orgs')
app.include_router(orgs.batch_jobs, prefix='/orgs')

View File

@@ -24,6 +24,7 @@ def get_order(order_id: str):
TransactKey(order_id)
+ SortKey('0')
+ SortKey('ITEMS', rename_key='items')
+ SortKey('CREATED_BY', rename_key='created_by')
+ SortKey('ADDRESS', rename_key='address')
+ SortKey('CREDIT_CARD', rename_key='credit_card')
+ SortKey('INVOICE', rename_key='invoice')
@@ -38,7 +39,11 @@ def get_order(order_id: str):
attempts = dyn.collection.query(KeyPair(order_id, 'TRANSACTION#ATTEMPT#'))
enrollments = dyn.collection.query(KeyPair(order_id, 'ENROLLMENT#'))
return order | {
'attempts': attempts['items'],
'enrollments': enrollments['items'],
}
return (
order
| {
'payment_attempts': attempts['items'],
'enrollments': enrollments['items'],
}
| ({'paid_at': order['payment_date']} if 'payment_date' in order else {})
)

View File

@@ -7,6 +7,7 @@ from http import HTTPStatus
from typing import Any, Literal
from uuid import uuid4
from aws_lambda_powertools import Logger
from aws_lambda_powertools.event_handler.api_gateway import Router
from aws_lambda_powertools.event_handler.exceptions import (
NotFoundError,
@@ -30,6 +31,7 @@ from config import DUE_DAYS, ORDER_TABLE
from routes.enrollments.enroll import Enrollment
router = Router()
logger = Logger(__name__)
dyn = DynamoDBPersistenceLayer(ORDER_TABLE, dynamodb_client)
@@ -138,6 +140,7 @@ def checkout(payload: Checkout):
org_id = payload.org_id
address = payload.address
credit_card = payload.credit_card
created_by = payload.created_by
items = payload.items
enrollments = payload.enrollments
coupon = payload.coupon
@@ -201,6 +204,17 @@ def checkout(payload: Checkout):
| address.model_dump()
)
if created_by:
transact.put(
item={
'id': order_id,
'sk': 'CREATED_BY',
'user_id': created_by.id,
'name': created_by.name,
'created_at': now_,
}
)
if credit_card:
transact.put(
item={

View File

@@ -5,6 +5,7 @@ from .billing import router as billing
from .custom_pricing import router as custom_pricing
from .enrollments.scheduled import router as scheduled
from .enrollments.submissions import router as submissions
from .seats import router as seats
from .users.add import router as users
from .users.batch_jobs import router as batch_jobs
@@ -16,6 +17,7 @@ __all__ = [
'custom_pricing',
'scheduled',
'submissions',
'seats',
'users',
'batch_jobs',
]

View File

@@ -102,7 +102,6 @@ def test_checkout_coupon(
lambda_context,
)
body = json.loads(r['body'])
print(body)
assert r['statusCode'] == HTTPStatus.CREATED
r = dynamodb_persistence_layer.collection.query(PartitionKey(body['id']))
@@ -125,7 +124,7 @@ def test_checkout_from_user(
'cpf': '07879819908',
'name': 'Sérgio R Siqueira',
'email': 'sergio@somosbeta.com.br',
'payment_method': 'MANUAL',
'payment_method': 'BANK_SLIP',
'address': {
'sk': 'METADATA#ADDRESS',
'address1': 'Rua Monsenhor Ivo Zanlorenzi',

View File

@@ -1,11 +1,11 @@
import { BellIcon } from 'lucide-react'
import { Button } from '@repo/ui/components/ui/button'
import {
Popover,
PopoverContent,
PopoverTrigger
} from '@repo/ui/components/ui/popover'
import { Button } from '@repo/ui/components/ui/button'
export function Notification() {
return (

View File

@@ -1,5 +1,5 @@
import { type ReactNode, createContext, useContext } from 'react'
import { type LucideIcon } from 'lucide-react'
import { createContext, useContext, type ReactNode } from 'react'
import { cn } from '@repo/ui/lib/utils'

View File

@@ -4,8 +4,8 @@ import React, {
useContext,
useMemo,
useState,
type ReactNode,
type ReactElement
type ReactElement,
type ReactNode
} from 'react'
type WizardContextProps = (name: string) => void

View File

@@ -1,13 +1,13 @@
'use client'
import { formatCNPJ } from '@brazilian-utils/brazilian-utils'
import { IconRosetteDiscountCheckFilled } from '@tabler/icons-react'
import {
CheckIcon,
BadgeCheckIcon,
CheckIcon,
ChevronsUpDownIcon,
PlusIcon
} from 'lucide-react'
import { IconRosetteDiscountCheckFilled } from '@tabler/icons-react'
import { createContext, use } from 'react'
import { useLocation } from 'react-router'

View File

@@ -1,4 +1,4 @@
import { type LoaderFunctionArgs, createContext } from 'react-router'
import { createContext, type LoaderFunctionArgs } from 'react-router'
import { userContext } from '@repo/auth/context'
import { request as req } from '@repo/util/request'

View File

@@ -1,15 +1,15 @@
import { useSearchParams } from 'react-router'
import { ChevronRightIcon, ChevronLeftIcon } from 'lucide-react'
import { subMonths, addMonths } from 'date-fns'
import { addMonths, subMonths } from 'date-fns'
import { ChevronLeftIcon, ChevronRightIcon } from 'lucide-react'
import { DateTime as LuxonDateTime } from 'luxon'
import { useSearchParams } from 'react-router'
import { TZ } from '@/conf'
import { DateTime } from '@repo/ui/components/datetime'
import { Badge } from '@repo/ui/components/ui/badge'
import { Button } from '@repo/ui/components/ui/button'
import { ButtonGroup } from '@repo/ui/components/ui/button-group'
import { Badge } from '@repo/ui/components/ui/badge'
import { DateTime } from '@repo/ui/components/datetime'
import { formatDate, billingPeriod } from './util'
import { billingPeriod, formatDate } from './util'
type RangePeriodProps = {
startDate: Date

View File

@@ -1,15 +1,26 @@
import type { Route } from './+types/route'
import Fuse from 'fuse.js'
import { BanIcon } from 'lucide-react'
import { DateTime as LuxonDateTime } from 'luxon'
import { Suspense, useMemo } from 'react'
import { BanIcon } from 'lucide-react'
import { Await, useSearchParams } from 'react-router'
import { cn } from '@repo/ui/lib/utils'
import { request as req } from '@repo/util/request'
import { Abbr } from '@repo/ui/components/abbr'
import { Currency } from '@repo/ui/components/currency'
import { DateTime } from '@repo/ui/components/datetime'
import { SearchForm } from '@repo/ui/components/search-form'
import { Skeleton } from '@repo/ui/components/skeleton'
import { Button } from '@repo/ui/components/ui/button'
import { Card, CardContent } from '@repo/ui/components/ui/card'
import {
Empty,
EmptyDescription,
EmptyHeader,
EmptyMedia,
EmptyTitle
} from '@repo/ui/components/ui/empty'
import { Kbd } from '@repo/ui/components/ui/kbd'
import {
Table,
TableBody,
@@ -19,24 +30,13 @@ import {
TableHeader,
TableRow
} from '@repo/ui/components/ui/table'
import { Abbr } from '@repo/ui/components/abbr'
import { Button } from '@repo/ui/components/ui/button'
import { SearchForm } from '@repo/ui/components/search-form'
import {
Empty,
EmptyDescription,
EmptyHeader,
EmptyMedia,
EmptyTitle
} from '@repo/ui/components/ui/empty'
import { Kbd } from '@repo/ui/components/ui/kbd'
import { Currency } from '@repo/ui/components/currency'
import { DateTime } from '@repo/ui/components/datetime'
import { cn } from '@repo/ui/lib/utils'
import { request as req } from '@repo/util/request'
import { TZ } from '@/conf'
import { billingPeriod, formatDate } from './util'
import { RangePeriod } from './range-period'
import { statuses } from './data'
import { RangePeriod } from './range-period'
import { billingPeriod, formatDate } from './util'
export function meta({}) {
return [{ title: 'Resumo de cobranças' }]

View File

@@ -2,27 +2,36 @@ import type { Route } from './+types/route'
import {
AlertCircleIcon,
BanIcon,
CalendarIcon,
CheckCircle2Icon,
ClockIcon,
CalendarIcon,
UserIcon,
BanIcon,
PlusIcon,
EllipsisIcon,
RotateCcw
PlusIcon,
RotateCcw,
UserIcon
} from 'lucide-react'
import { Link, useParams } from 'react-router'
import { Suspense } from 'react'
import { DateTime as LuxonDateTime } from 'luxon'
import { Suspense } from 'react'
import { Link, useParams } from 'react-router'
import { Abbr } from '@repo/ui/components/abbr'
import { DateTime } from '@repo/ui/components/datetime'
import { Skeleton } from '@repo/ui/components/skeleton'
import {
Empty,
EmptyContent,
EmptyDescription,
EmptyHeader,
EmptyMedia,
EmptyTitle
} from '@repo/ui/components/ui/empty'
Alert,
AlertDescription,
AlertTitle
} from '@repo/ui/components/ui/alert'
import {
Breadcrumb,
BreadcrumbItem,
BreadcrumbLink,
BreadcrumbList,
BreadcrumbPage,
BreadcrumbSeparator
} from '@repo/ui/components/ui/breadcrumb'
import { Button } from '@repo/ui/components/ui/button'
import {
Card,
CardContent,
@@ -31,31 +40,22 @@ import {
CardHeader,
CardTitle
} from '@repo/ui/components/ui/card'
import {
Breadcrumb,
BreadcrumbItem,
BreadcrumbLink,
BreadcrumbList,
BreadcrumbPage,
BreadcrumbSeparator
} from '@repo/ui/components/ui/breadcrumb'
import {
Alert,
AlertDescription,
AlertTitle
} from '@repo/ui/components/ui/alert'
import { request as req } from '@repo/util/request'
import { Skeleton } from '@repo/ui/components/skeleton'
import { Await } from 'react-router'
import { Abbr } from '@repo/ui/components/abbr'
import { Button } from '@repo/ui/components/ui/button'
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger
} from '@repo/ui/components/ui/dropdown-menu'
import { DateTime } from '@repo/ui/components/datetime'
import {
Empty,
EmptyContent,
EmptyDescription,
EmptyHeader,
EmptyMedia,
EmptyTitle
} from '@repo/ui/components/ui/empty'
import { request as req } from '@repo/util/request'
import { Await } from 'react-router'
export function meta({}: Route.MetaArgs) {
return [{ title: 'Relatório de matrículas' }]
@@ -69,9 +69,7 @@ export async function loader({ context, request, params }: Route.LoaderArgs) {
request
}).then((r) => r.json())
return {
submission
}
return { submission }
}
export default function Route({

View File

@@ -1,17 +1,12 @@
import type { Route } from './+types/route'
import { useEffect, useState } from 'react'
import { useFetcher, Link } from 'react-router'
import { useMount } from 'ahooks'
import { BookSearchIcon, CircleCheckBigIcon, WalletIcon } from 'lucide-react'
import { use, useEffect, useState } from 'react'
import { Link, redirect, useFetcher } from 'react-router'
import {
Card,
CardContent,
CardHeader,
CardDescription,
CardTitle
} from '@repo/ui/components/ui/card'
import { cloudflareContext, userContext } from '@repo/auth/context'
import { Skeleton } from '@repo/ui/components/skeleton'
import {
Breadcrumb,
BreadcrumbItem,
@@ -20,22 +15,27 @@ import {
BreadcrumbPage,
BreadcrumbSeparator
} from '@repo/ui/components/ui/breadcrumb'
import {
Card,
CardContent,
CardDescription,
CardHeader,
CardTitle
} from '@repo/ui/components/ui/card'
import { Label } from '@repo/ui/components/ui/label'
import { Switch } from '@repo/ui/components/ui/switch'
import { createSearch } from '@repo/util/meili'
import { cloudflareContext, userContext } from '@repo/auth/context'
import { Label } from '@repo/ui/components/ui/label'
import { Skeleton } from '@repo/ui/components/skeleton'
import { request as req, HttpMethod } from '@repo/util/request'
import { HttpMethod, request as req } from '@repo/util/request'
import { INTERNAL_EMAIL_DOMAIN } from '@/conf'
import { workspaceContext } from '@/middleware/workspace'
import { useWorksapce } from '@/components/workspace-switcher'
import { Step, StepItem, StepSeparator } from '@/components/step'
import { Wizard, WizardStep } from '@/components/wizard'
import { useWorksapce } from '@/components/workspace-switcher'
import { INTERNAL_EMAIL_DOMAIN } from '@/conf'
import { workspaceContext } from '@/middleware/workspace'
import type { Course } from '../_.$orgid.enrollments.add/data'
import { Assigned } from './assigned'
import { Bulk } from './bulk'
import { Payment } from './payment'
import { Assigned } from './assigned'
import { Review } from './review'
import { useWizardStore } from './store'
@@ -43,7 +43,7 @@ export function meta({}: Route.MetaArgs) {
return [{ title: 'Comprar matrículas' }]
}
export async function loader({ context }: Route.LoaderArgs) {
export async function loader({ context, params, request }: Route.LoaderArgs) {
const cloudflare = context.get(cloudflareContext)
const courses = createSearch<Course>({
index: 'saladeaula_courses',
@@ -53,10 +53,16 @@ export async function loader({ context }: Route.LoaderArgs) {
env: cloudflare.env
})
return { courses }
const seats = req({
url: `/orgs/${params.orgid}/seats`,
request,
context
}).then((r) => r.json() as any)
return { courses, seats }
}
export async function action({ params, request, context }: Route.ActionArgs) {
export async function action({ request, context }: Route.ActionArgs) {
const body = (await request.json()) as object
const user = context.get(userContext)!
const { activeWorkspace } = context.get(workspaceContext)
@@ -83,13 +89,12 @@ export async function action({ params, request, context }: Route.ActionArgs) {
return { ok: false, error }
}
console.log(await r.json())
return { ok: true }
const { id } = (await r.json()) as { id: string }
throw redirect(`../payments/${id}`)
}
export default function Route({
loaderData: { courses }
loaderData: { courses, seats: seats_ }
}: Route.ComponentProps) {
const fetcher = useFetcher()
const [mounted, setMounted] = useState(false)
@@ -97,6 +102,9 @@ export default function Route({
const { index, kind, setIndex, setKind, reset, update, ...state } =
useWizardStore()
// @TODO
const seats = use(seats_)
const onSubmit = async () => {
const items = state.items.map(({ course, quantity }) => ({
...course,
@@ -119,14 +127,12 @@ export default function Route({
}
}, [address])
useEffect(() => {
console.log(fetcher.data)
}, [fetcher.data])
if (!mounted) {
return <Skeleton />
}
console.log(seats)
return (
<div className="space-y-2.5">
<Breadcrumb>

View File

@@ -1,8 +1,11 @@
import type { Route } from './+types/route'
import { Link } from 'react-router'
import { formatCEP } from '@brazilian-utils/brazilian-utils'
import { Suspense, useEffect } from 'react'
import { Await, Link } from 'react-router'
import { request as req } from '@repo/util/request'
import { Currency } from '@repo/ui/components/currency'
import { Skeleton } from '@repo/ui/components/skeleton'
import {
Breadcrumb,
BreadcrumbItem,
@@ -11,6 +14,22 @@ import {
BreadcrumbPage,
BreadcrumbSeparator
} from '@repo/ui/components/ui/breadcrumb'
import {
Card,
CardContent,
CardHeader,
CardTitle
} from '@repo/ui/components/ui/card'
import {
Item,
ItemContent,
ItemDescription,
ItemGroup,
ItemTitle
} from '@repo/ui/components/ui/item'
import { paymentMethods } from '@repo/ui/routes/orders/data'
import { request as req } from '@repo/util/request'
import { useWizardStore } from '../_.$orgid.enrollments.buy/store'
export function meta() {
return [
@@ -20,28 +39,32 @@ export function meta() {
]
}
export async function loader({ params, request, context }: Route.LoaderArgs) {
const r = await req({
export async function loader({ context, request, params }: Route.LoaderArgs) {
const order = await req({
url: `/orders/${params.id}`,
request,
context
})
context,
request
}).then((r) => r.json())
if (!r.ok) {
throw new Response(null, { status: r.status })
}
return { order: await r.json() }
return { order }
}
export default function Route({ loaderData: { order } }: Route.ComponentProps) {
const { reset } = useWizardStore()
const { address, total, credit_card, payment_method, invoice, installments } =
order
useEffect(() => {
reset()
}, [])
return (
<div className="space-y-2.5">
<Breadcrumb>
<BreadcrumbList>
<BreadcrumbItem>
<BreadcrumbLink asChild>
<Link to="../payments">Histórico de pagamentos</Link>
<Link to="../payments">Pagamentos</Link>
</BreadcrumbLink>
</BreadcrumbItem>
<BreadcrumbSeparator />
@@ -50,7 +73,55 @@ export default function Route({ loaderData: { order } }: Route.ComponentProps) {
</BreadcrumbItem>
</BreadcrumbList>
</Breadcrumb>
<pre>{JSON.stringify(order, null, 2)}</pre>
<Card className="lg:max-w-4xl mx-auto space-y-2.5">
<CardHeader>
<CardTitle className="text-2xl">Detalhes do pagamento</CardTitle>
</CardHeader>
<CardContent>
<ItemGroup className="grid lg:grid-cols-2 gap-4">
<Item variant="outline">
<ItemContent>
<ItemTitle>Endereço de cobrança</ItemTitle>
<ul className="text-muted-foreground text-sm leading-normal font-normal text-balance">
{address?.address1}
{address?.address2 ? <>, {address?.address2}</> : null}
<br />
{address?.neighborhood}
<br />
{address?.city}, {address?.state}
<br />
{formatCEP(address?.postcode)}
</ul>
</ItemContent>
</Item>
<Item variant="outline" className="items-start">
<ItemContent>
<ItemTitle>Forma de pagamento</ItemTitle>
<ItemDescription>
{credit_card ? (
<>
{credit_card.brand} (Crédito) **** {credit_card.last4}
<br />
{installments}x{' '}
<Currency>{total / Number(installments)}</Currency>
</>
) : (
<>
{payment_method
? paymentMethods[payment_method]
: payment_method}
</>
)}
</ItemDescription>
</ItemContent>
</Item>
</ItemGroup>
{/*<pre>{JSON.stringify(order, null, 2)}</pre>*/}
</CardContent>
</Card>
</div>
)
}

View File

@@ -12,7 +12,7 @@
"typecheck": "npm run cf-typegen && react-router typegen && tsc -b"
},
"dependencies": {
"@react-router/fs-routes": "^7.10.1",
"@react-router/fs-routes": "^7.12.0",
"@repo/auth": "*",
"@repo/ui": "*",
"@repo/util": "^0.0.0",
@@ -24,31 +24,31 @@
"fuse.js": "^7.1.0",
"isbot": "^5.1.32",
"luxon": "^3.7.2",
"meilisearch": "^0.54.0",
"meilisearch": "^0.55.0",
"meilisearch-helper": "github:sergiors/meilisearch-helper",
"ramda": "^0.32.0",
"react": "^19.2.1",
"react-dom": "^19.2.1",
"react-router": "^7.10.1",
"react": "^19.2.3",
"react-dom": "^19.2.3",
"react-router": "^7.12.0",
"unique-names-generator": "^4.7.1",
"zod": "^4.1.13",
"zustand": "^5.0.9"
"zod": "^4.3.5",
"zustand": "^5.0.10"
},
"devDependencies": {
"@cloudflare/vite-plugin": "^1.17.0",
"@tailwindcss/vite": "^4.1.17",
"@cloudflare/vite-plugin": "^1.20.3",
"@tailwindcss/vite": "^4.1.18",
"@types/file-saver": "^2.0.7",
"@types/luxon": "^3.7.1",
"@types/node": "^24.10.1",
"@types/react": "^19.2.7",
"@types/node": "^25.0.8",
"@types/react": "^19.2.8",
"@types/react-dom": "^19.2.3",
"prettier": "^3.7.4",
"remix-flat-routes": "^0.8.5",
"tailwindcss": "^4.1.17",
"tailwindcss": "^4.1.18",
"tw-animate-css": "^1.4.0",
"typescript": "^5.9.3",
"vite": "^7.2.6",
"vite-tsconfig-paths": "^5.1.4",
"wrangler": "^4.53.0"
"vite": "^7.3.1",
"vite-tsconfig-paths": "^6.0.4",
"wrangler": "^4.59.1"
}
}

View File

@@ -4,6 +4,7 @@ export default {
ssr: true,
future: {
v8_viteEnvironmentApi: true,
v8_splitRouteModules: true,
v8_middleware: true
}
} satisfies Config

View File

@@ -1,6 +1,6 @@
/* eslint-disable */
// Generated by Wrangler by running `wrangler types` (hash: 58c6149f238624e8945df7f87e575516)
// Runtime types generated with workerd@1.20251202.0 2025-04-04
// Runtime types generated with workerd@1.20260111.0 2025-04-04
declare namespace Cloudflare {
interface GlobalProps {
mainModule: typeof import("./workers/app");
@@ -500,8 +500,10 @@ interface DurableObjectNamespaceNewUniqueIdOptions {
jurisdiction?: DurableObjectJurisdiction;
}
type DurableObjectLocationHint = "wnam" | "enam" | "sam" | "weur" | "eeur" | "apac" | "oc" | "afr" | "me";
type DurableObjectRoutingMode = "primary-only";
interface DurableObjectNamespaceGetDurableObjectOptions {
locationHint?: DurableObjectLocationHint;
routingMode?: DurableObjectRoutingMode;
}
interface DurableObjectClass<_T extends Rpc.DurableObjectBranded | undefined = undefined> {
}
@@ -2085,6 +2087,8 @@ interface Transformer<I = any, O = any> {
expectedLength?: number;
}
interface StreamPipeOptions {
preventAbort?: boolean;
preventCancel?: boolean;
/**
* Pipes this readable stream to a given writable stream destination. The way in which the piping process behaves under various error conditions can be customized with a number of passed options. It returns a promise that fulfills when the piping process completes successfully, or rejects if any errors were encountered.
*
@@ -2103,8 +2107,6 @@ interface StreamPipeOptions {
* The signal option can be set to an AbortSignal to allow aborting an ongoing pipe operation via the corresponding AbortController. In this case, this source readable stream will be canceled, and destination aborted, unless the respective options preventCancel or preventAbort are set.
*/
preventClose?: boolean;
preventAbort?: boolean;
preventCancel?: boolean;
signal?: AbortSignal;
}
type ReadableStreamReadResult<R = any> = {
@@ -2379,13 +2381,13 @@ declare abstract class TransformStreamDefaultController<O = any> {
terminate(): void;
}
interface ReadableWritablePair<R = any, W = any> {
readable: ReadableStream<R>;
/**
* Provides a convenient, chainable way of piping this readable stream through a transform stream (or any other { writable, readable } pair). It simply pipes the stream into the writable side of the supplied pair, and returns the readable side for further use.
*
* Piping a stream will lock it for the duration of the pipe, preventing any other consumer from acquiring a reader.
*/
writable: WritableStream<W>;
readable: ReadableStream<R>;
}
/**
* The **`WritableStream`** interface of the Streams API provides a standard abstraction for writing streaming data to a destination, known as a sink.
@@ -3261,7 +3263,7 @@ interface WorkerStubEntrypointOptions {
props?: any;
}
interface WorkerLoader {
get(name: string, getCode: () => WorkerLoaderWorkerCode | Promise<WorkerLoaderWorkerCode>): WorkerStub;
get(name: string | null, getCode: () => WorkerLoaderWorkerCode | Promise<WorkerLoaderWorkerCode>): WorkerStub;
}
interface WorkerLoaderModule {
js?: string;
@@ -8443,7 +8445,7 @@ type AiOptions = {
* Maximum 5 tags are allowed each request.
* Duplicate tags will removed.
*/
tags: string[];
tags?: string[];
gateway?: GatewayOptions;
returnRawResponse?: boolean;
prefix?: string;

View File

@@ -50,6 +50,7 @@ export default function Route({ loaderData: { order } }: Route.ComponentProps) {
</BreadcrumbItem>
</BreadcrumbList>
</Breadcrumb>
<pre>{JSON.stringify(order, null, 2)}</pre>
</div>
)

1880
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -9,18 +9,18 @@
},
"devDependencies": {
"prettier": "^3.7.4",
"turbo": "^2.6.3",
"turbo": "^2.7.4",
"typescript": "5.9.3"
},
"optionalDependencies": {
"@rollup/rollup-linux-x64-gnu": "^4.53.3",
"@tailwindcss/oxide-linux-x64-gnu": "^4.1.17",
"@rollup/rollup-linux-x64-gnu": "^4.55.1",
"@tailwindcss/oxide-linux-x64-gnu": "^4.1.18",
"lightningcss-linux-x64-gnu": "^1.30.2"
},
"engines": {
"node": ">=18"
},
"packageManager": "npm@11.6.4",
"packageManager": "npm@11.7.0",
"workspaces": [
"apps/*",
"packages/*"

View File

@@ -55,7 +55,7 @@ export const columns: ColumnDef<Order>[] = [
{
accessorKey: 'due_date',
enableSorting: true,
meta: { title: 'Vence em' },
meta: { title: 'Vencimento em' },
header: DataTableColumnHeaderSort,
cell: DataTableColumnDatetime
},