update payment details
This commit is contained in:
@@ -1,12 +1,15 @@
|
||||
import type { Route } from './+types/route'
|
||||
|
||||
import { formatCEP } from '@brazilian-utils/brazilian-utils'
|
||||
import { CalendarClockIcon, CalendarIcon, UserIcon } from 'lucide-react'
|
||||
import {
|
||||
AlertCircleIcon,
|
||||
ArrowLeftRightIcon,
|
||||
HelpCircleIcon
|
||||
} 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,
|
||||
@@ -18,15 +21,12 @@ import {
|
||||
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'
|
||||
@@ -39,8 +39,21 @@ import {
|
||||
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 { Abbr } from '@repo/ui/components/abbr'
|
||||
import { Badge } from '@repo/ui/components/ui/badge'
|
||||
import { Button } from '@repo/ui/components/ui/button'
|
||||
import { Kbd } from '@repo/ui/components/ui/kbd'
|
||||
import { cn } from '@repo/ui/lib/utils'
|
||||
import {
|
||||
labels,
|
||||
statuses,
|
||||
type Order as Order_
|
||||
} from '@repo/ui/routes/orders/data'
|
||||
|
||||
import type { CreditCard as CreditCard_ } from '../_.$orgid.enrollments.buy/payment'
|
||||
import type { Address } from '../_.$orgid.enrollments.buy/review'
|
||||
import { useWizardStore } from '../_.$orgid.enrollments.buy/store'
|
||||
|
||||
export function meta() {
|
||||
@@ -51,12 +64,44 @@ export function meta() {
|
||||
]
|
||||
}
|
||||
|
||||
const PaymentMethodComponent = {
|
||||
PIX: Pix,
|
||||
BANK_SLIP: BankSlip,
|
||||
CREDIT_CARD: CreditCard
|
||||
}
|
||||
|
||||
type Item_ = {
|
||||
id: string
|
||||
name: string
|
||||
unit_price: number
|
||||
quantity: number
|
||||
}
|
||||
|
||||
type User = {
|
||||
id: string
|
||||
name: string
|
||||
}
|
||||
|
||||
type Order = Order_ & {
|
||||
items: Item_[]
|
||||
interest_amount: number
|
||||
due_date: string
|
||||
created_at: string
|
||||
subtotal: number
|
||||
discount: number
|
||||
address: Address
|
||||
credit_card?: CreditCard_
|
||||
coupon?: string
|
||||
installments?: number
|
||||
created_by?: User
|
||||
}
|
||||
|
||||
export async function loader({ context, request, params }: Route.LoaderArgs) {
|
||||
const order = await req({
|
||||
const order = (await req({
|
||||
url: `/orders/${params.id}`,
|
||||
context,
|
||||
request
|
||||
}).then((r) => r.json())
|
||||
}).then((r) => r.json())) as Order
|
||||
|
||||
return { order }
|
||||
}
|
||||
@@ -64,22 +109,18 @@ export async function loader({ context, request, params }: Route.LoaderArgs) {
|
||||
export default function Route({ loaderData: { order } }: Route.ComponentProps) {
|
||||
const { reset } = useWizardStore()
|
||||
const {
|
||||
status,
|
||||
coupon,
|
||||
address,
|
||||
total,
|
||||
credit_card,
|
||||
payment_method,
|
||||
due_date,
|
||||
created_at,
|
||||
invoice,
|
||||
installments,
|
||||
interest_amount,
|
||||
discount,
|
||||
subtotal,
|
||||
items = [],
|
||||
created_by
|
||||
items = []
|
||||
} = order
|
||||
|
||||
const Component = PaymentMethodComponent[payment_method]
|
||||
|
||||
useEffect(() => {
|
||||
reset()
|
||||
}, [])
|
||||
@@ -103,14 +144,6 @@ export default function Route({ loaderData: { order } }: Route.ComponentProps) {
|
||||
<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">
|
||||
@@ -134,26 +167,12 @@ export default function Route({ loaderData: { order } }: Route.ComponentProps) {
|
||||
<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>
|
||||
<div className="text-muted-foreground text-sm leading-normal font-normal text-balance">
|
||||
{Component && <Component {...order} />}
|
||||
</div>
|
||||
</ItemContent>
|
||||
</Item>
|
||||
</ItemGroup>
|
||||
{/*<pre>{JSON.stringify(order, null, 2)}</pre>*/}
|
||||
|
||||
<Table className="pointer-events-none">
|
||||
<TableHeader>
|
||||
@@ -193,8 +212,15 @@ export default function Route({ loaderData: { order } }: Route.ComponentProps) {
|
||||
</TableRow>
|
||||
{/* Discount */}
|
||||
<TableRow>
|
||||
<TableCell className="text-right" colSpan={3}>
|
||||
Descontos
|
||||
<TableCell colSpan={3}>
|
||||
<span className="flex gap-1 justify-end">
|
||||
Descontos
|
||||
{coupon && (
|
||||
<Kbd>
|
||||
<Abbr maxLen={8}>{coupon}</Abbr>
|
||||
</Kbd>
|
||||
)}
|
||||
</span>
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Currency>{discount}</Currency>
|
||||
@@ -225,18 +251,93 @@ export default function Route({ loaderData: { order } }: Route.ComponentProps) {
|
||||
</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>
|
||||
|
||||
{/*<pre>{JSON.stringify(order, null, 2)}</pre>*/}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
function Status({ status: s }: { status: string }) {
|
||||
const status = labels[s] ?? s
|
||||
const { icon: Icon, color } = statuses?.[s] ?? { icon: HelpCircleIcon }
|
||||
|
||||
return (
|
||||
<Badge variant="outline" className={cn(color, ' px-1.5')}>
|
||||
<Icon className={cn('stroke-2', color)} />
|
||||
{status}
|
||||
</Badge>
|
||||
)
|
||||
}
|
||||
|
||||
type PaymentMethodProps = {
|
||||
status: string
|
||||
total: number
|
||||
installments: number
|
||||
}
|
||||
|
||||
type CreditCardProps = PaymentMethodProps & {
|
||||
stats: { last_attempt_succeeded: boolean }
|
||||
credit_card: { last4: string; brand: string }
|
||||
}
|
||||
|
||||
function CreditCard({
|
||||
status,
|
||||
total,
|
||||
credit_card,
|
||||
installments,
|
||||
stats
|
||||
}: CreditCardProps) {
|
||||
return (
|
||||
<>
|
||||
<ul className="flex max-lg:flex-col gap-x-1.5">
|
||||
<li>
|
||||
{credit_card.brand} (Crédito) **** {credit_card.last4}
|
||||
</li>
|
||||
<li>
|
||||
{!stats.last_attempt_succeeded ? (
|
||||
<Badge
|
||||
variant="outline"
|
||||
className="text-red-400 border-red-400 px-1.5"
|
||||
>
|
||||
<AlertCircleIcon /> Transação negada
|
||||
</Badge>
|
||||
) : (
|
||||
<Status status={status} />
|
||||
)}
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
{installments}x <Currency>{total / Number(installments)}</Currency>
|
||||
</p>
|
||||
|
||||
{!stats.last_attempt_succeeded ? (
|
||||
<div className="flex justify-center mt-2">
|
||||
<Button size="sm" variant="secondary" className="cursor-pointer">
|
||||
<ArrowLeftRightIcon /> Tentar com outro cartão
|
||||
</Button>
|
||||
</div>
|
||||
) : null}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
type BankSlipProps = PaymentMethodProps & {}
|
||||
|
||||
function BankSlip({ status }: BankSlipProps) {
|
||||
return (
|
||||
<ul className="flex max-lg:flex-col gap-x-1.5">
|
||||
<li>Boleto bancário</li>
|
||||
<li>
|
||||
<Status status={status} />
|
||||
</li>
|
||||
</ul>
|
||||
)
|
||||
}
|
||||
|
||||
type PixProps = PaymentMethodProps & {}
|
||||
|
||||
function Pix({}: PixProps) {
|
||||
return <>Pix</>
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user