243 lines
6.9 KiB
TypeScript
243 lines
6.9 KiB
TypeScript
import type { Route } from './+types/route'
|
|
|
|
import { formatCEP } from '@brazilian-utils/brazilian-utils'
|
|
import { CalendarClockIcon, CalendarIcon, UserIcon } from 'lucide-react'
|
|
import { useEffect } from 'react'
|
|
import { Link } from 'react-router'
|
|
|
|
import { Currency } from '@repo/ui/components/currency'
|
|
import { DateTime } from '@repo/ui/components/datetime'
|
|
import {
|
|
Breadcrumb,
|
|
BreadcrumbItem,
|
|
BreadcrumbLink,
|
|
BreadcrumbList,
|
|
BreadcrumbPage,
|
|
BreadcrumbSeparator
|
|
} from '@repo/ui/components/ui/breadcrumb'
|
|
import {
|
|
Card,
|
|
CardContent,
|
|
CardDescription,
|
|
CardFooter,
|
|
CardHeader,
|
|
CardTitle
|
|
} from '@repo/ui/components/ui/card'
|
|
import {
|
|
Item,
|
|
ItemContent,
|
|
ItemDescription,
|
|
ItemGroup,
|
|
ItemTitle
|
|
} from '@repo/ui/components/ui/item'
|
|
import {
|
|
Table,
|
|
TableBody,
|
|
TableCell,
|
|
TableFooter,
|
|
TableHead,
|
|
TableHeader,
|
|
TableRow
|
|
} from '@repo/ui/components/ui/table'
|
|
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 [
|
|
{
|
|
title: 'Detalhes do pagamento'
|
|
}
|
|
]
|
|
}
|
|
|
|
export async function loader({ context, request, params }: Route.LoaderArgs) {
|
|
const order = await req({
|
|
url: `/orders/${params.id}`,
|
|
context,
|
|
request
|
|
}).then((r) => r.json())
|
|
|
|
return { order }
|
|
}
|
|
|
|
export default function Route({ loaderData: { order } }: Route.ComponentProps) {
|
|
const { reset } = useWizardStore()
|
|
const {
|
|
status,
|
|
address,
|
|
total,
|
|
credit_card,
|
|
payment_method,
|
|
due_date,
|
|
created_at,
|
|
invoice,
|
|
installments,
|
|
interest_amount,
|
|
discount,
|
|
subtotal,
|
|
items = [],
|
|
created_by
|
|
} = order
|
|
|
|
useEffect(() => {
|
|
reset()
|
|
}, [])
|
|
|
|
return (
|
|
<div className="space-y-2.5">
|
|
<Breadcrumb>
|
|
<BreadcrumbList>
|
|
<BreadcrumbItem>
|
|
<BreadcrumbLink asChild>
|
|
<Link to="../payments">Pagamentos</Link>
|
|
</BreadcrumbLink>
|
|
</BreadcrumbItem>
|
|
<BreadcrumbSeparator />
|
|
<BreadcrumbItem>
|
|
<BreadcrumbPage>Detalhes do pagamento</BreadcrumbPage>
|
|
</BreadcrumbItem>
|
|
</BreadcrumbList>
|
|
</Breadcrumb>
|
|
|
|
<Card className="lg:max-w-4xl mx-auto">
|
|
<CardHeader>
|
|
<CardTitle className="text-2xl">Detalhes do pagamento</CardTitle>
|
|
{status}
|
|
<CardDescription>
|
|
<ul className="flex gap-2.5 *:flex *:gap-1 *:items-center [&_svg]:size-3.5">
|
|
<li>
|
|
<CalendarClockIcon /> <DateTime>{due_date}</DateTime>
|
|
</li>
|
|
</ul>
|
|
</CardDescription>
|
|
</CardHeader>
|
|
|
|
<CardContent className="space-y-4">
|
|
<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>*/}
|
|
|
|
<Table className="pointer-events-none">
|
|
<TableHeader>
|
|
<TableRow>
|
|
<TableHead>Curso</TableHead>
|
|
<TableHead>Quantidade</TableHead>
|
|
<TableHead>Valor unit.</TableHead>
|
|
<TableHead>Total</TableHead>
|
|
</TableRow>
|
|
</TableHeader>
|
|
<TableBody>
|
|
{items?.map(({ name, unit_price, quantity }, index) => {
|
|
return (
|
|
<TableRow key={index}>
|
|
<TableCell>{name}</TableCell>
|
|
<TableCell>{quantity}</TableCell>
|
|
<TableCell>
|
|
<Currency>{unit_price}</Currency>
|
|
</TableCell>
|
|
<TableCell>
|
|
<Currency>{unit_price * quantity}</Currency>
|
|
</TableCell>
|
|
</TableRow>
|
|
)
|
|
})}
|
|
</TableBody>
|
|
|
|
{/* Summary */}
|
|
<TableFooter>
|
|
<TableRow>
|
|
<TableCell className="text-right" colSpan={3}>
|
|
Subtotal
|
|
</TableCell>
|
|
<TableCell>
|
|
<Currency>{subtotal}</Currency>
|
|
</TableCell>
|
|
</TableRow>
|
|
{/* Discount */}
|
|
<TableRow>
|
|
<TableCell className="text-right" colSpan={3}>
|
|
Descontos
|
|
</TableCell>
|
|
<TableCell>
|
|
<Currency>{discount}</Currency>
|
|
</TableCell>
|
|
</TableRow>
|
|
{/* Interest */}
|
|
{interest_amount ? (
|
|
<TableRow>
|
|
<TableCell className="text-right" colSpan={3}>
|
|
Juros
|
|
</TableCell>
|
|
<TableCell>
|
|
<Currency>{interest_amount}</Currency>
|
|
</TableCell>
|
|
</TableRow>
|
|
) : (
|
|
<></>
|
|
)}
|
|
{/* Total */}
|
|
<TableRow>
|
|
<TableCell className="text-right" colSpan={3}>
|
|
Total
|
|
</TableCell>
|
|
<TableCell>
|
|
<Currency>{total}</Currency>
|
|
</TableCell>
|
|
</TableRow>
|
|
</TableFooter>
|
|
</Table>
|
|
</CardContent>
|
|
|
|
{/* <CardFooter>
|
|
<ul className="flex gap-2.5 *:flex *:gap-1 *:items-center [&_svg]:size-3.5">
|
|
<li>
|
|
<CalendarIcon /> <DateTime>{created_at}</DateTime>
|
|
</li>{' '}
|
|
<li>
|
|
<UserIcon /> {created_by.name}
|
|
</li>
|
|
</ul>
|
|
</CardFooter>*/}
|
|
</Card>
|
|
</div>
|
|
)
|
|
}
|