import type { Route } from './+types/route' import { formatCEP } from '@brazilian-utils/brazilian-utils' import { zodResolver } from '@hookform/resolvers/zod' import { useRequest } from 'ahooks' import { AlertCircleIcon, ArrowLeftRightIcon, HelpCircleIcon } from 'lucide-react' import { useEffect } from 'react' import { useForm } from 'react-hook-form' import { Link } from 'react-router' import { z } from 'zod' import { Currency } from '@repo/ui/components/currency' import { Breadcrumb, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator } from '@repo/ui/components/ui/breadcrumb' import { Card, CardContent, CardHeader, CardTitle } from '@repo/ui/components/ui/card' import { Item, ItemContent, ItemGroup, ItemTitle } from '@repo/ui/components/ui/item' import { Table, TableBody, TableCell, TableFooter, TableHead, TableHeader, TableRow } from '@repo/ui/components/ui/table' 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 { Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger } from '@repo/ui/components/ui/dialog' import { Separator } from '@repo/ui/components/ui/separator' import { Spinner } from '@repo/ui/components/ui/spinner' import { CreditCard, creditCardSchema, type CreditCard as CreditCardProps } from '../_.$orgid.enrollments.buy/payment' import type { Address } from '../_.$orgid.enrollments.buy/review' import { useWizardStore } from '../_.$orgid.enrollments.buy/store' export function meta() { return [ { title: 'Detalhes do pagamento' } ] } const PaymentMethodComponent = { PIX: PixPaymentMethod, BANK_SLIP: BankSlipPaymentMethod, CREDIT_CARD: CreditCardPaymentMethod } type Item = { id: string name: string unit_price: number quantity: number } type User = { id: string name: string } type Invoice = { invoice_id: string secure_url: string } type Order = Order_ & { items: Item[] interest_amount: number due_date: string created_at: string subtotal: number discount: number address: Address credit_card?: CreditCardProps coupon?: string installments?: number created_by?: User invoice: Invoice } export async function loader({ context, request, params }: Route.LoaderArgs) { const order = (await req({ url: `/orders/${params.id}`, context, request }).then((r) => r.json())) as Order return { order } } export default function Route({ loaderData: { order } }: Route.ComponentProps) { const { reset } = useWizardStore() const { coupon, address, total, payment_method, interest_amount, discount, invoice, subtotal, items = [] } = order const Component = (PaymentMethodComponent as Record>)[ payment_method ] ?? UnknownPaymentMethod useEffect(() => { reset() }, []) return (
Pagamentos Detalhes do pagamento Detalhes do pagamento Endereço de cobrança
    {address?.address1} {address?.address2 ? <>, {address?.address2} : null}
    {address?.neighborhood}
    {address?.city}, {address?.state}
    {formatCEP(address?.postcode)}
Forma de pagamento
{Component && ( )}
Curso Quantidade Valor unit. Total {items?.map(({ name, unit_price, quantity }, index) => { return ( {name} {quantity} {unit_price} {unit_price * quantity} ) })} {/* Summary */} Subtotal {subtotal} {/* Discount */} Descontos {coupon && ( {coupon} )} {discount} {/* Interest */} {interest_amount ? ( Juros {interest_amount} ) : ( <> )} {/* Total */} Total {total}
{/*
{JSON.stringify(order, null, 2)}
*/}
) } function Status({ status: s }: { status: string }) { const status = labels[s] ?? s const { icon: Icon, color } = statuses?.[s] ?? { icon: HelpCircleIcon } return ( {status} ) } type PaymentMethodProps = { id: string status: string total: number invoice_id: string installments: number } type BankSlipPaymentMethodProps = PaymentMethodProps & {} function BankSlipPaymentMethod({ status }: BankSlipPaymentMethodProps) { return ( ) } type PixPaymentMethodrops = PaymentMethodProps & {} function PixPaymentMethod({}: PixPaymentMethodrops) { return <>Pix } function UnknownPaymentMethod() { return <>Deposito bancário } type CreditCardPaymentMethodProps = PaymentMethodProps & { stats: { last_attempt_succeeded: boolean } credit_card: { last4: string; brand: string } } function CreditCardPaymentMethod({ id, status, total, credit_card, installments, invoice_id, stats }: CreditCardPaymentMethodProps) { return ( <>

{installments}x {total / Number(installments)}

{stats.last_attempt_succeeded === false ? (
) : null} ) } const formSchema = z.object({ credit_card: creditCardSchema }) type Schema = z.input function CreditCardPaymentDialog({ children, id, installments, invoice_id, total }) { const { runAsync } = useRequest( async ({ credit_card }) => { return await fetch(`/~/api/orders/${id}/payment-retries`, { method: 'POST', headers: new Headers({ 'Content-Type': 'application/json' }), body: JSON.stringify({ credit_card, installments, invoice_id }) }) }, { manual: true } ) const { control, handleSubmit, formState } = useForm({ resolver: zodResolver(formSchema) }) const onSubmit = async ({ credit_card }: Schema) => { const r = await runAsync({ credit_card }) console.log(r.ok) console.log(await r.json()) } return ( {children} Novo cartão de crédito Use um novo cartão para concluir o pagamento. Nenhuma cobrança foi realizada no cartão anterior.
) }