add payment retries
This commit is contained in:
@@ -6,6 +6,9 @@ import { useRequest } from 'ahooks'
|
||||
import {
|
||||
AlertCircleIcon,
|
||||
ArrowLeftRightIcon,
|
||||
CircleCheckIcon,
|
||||
CircleXIcon,
|
||||
EllipsisIcon,
|
||||
HelpCircleIcon
|
||||
} from 'lucide-react'
|
||||
import { useEffect } from 'react'
|
||||
@@ -28,8 +31,16 @@ import {
|
||||
CardHeader,
|
||||
CardTitle
|
||||
} from '@repo/ui/components/ui/card'
|
||||
import {
|
||||
Command,
|
||||
CommandEmpty,
|
||||
CommandGroup,
|
||||
CommandItem,
|
||||
CommandList
|
||||
} from '@repo/ui/components/ui/command'
|
||||
import {
|
||||
Item,
|
||||
ItemActions,
|
||||
ItemContent,
|
||||
ItemGroup,
|
||||
ItemTitle
|
||||
@@ -46,16 +57,9 @@ import {
|
||||
import { request as req } from '@repo/util/request'
|
||||
|
||||
import { Abbr } from '@repo/ui/components/abbr'
|
||||
import { DateTime } from '@repo/ui/components/datetime'
|
||||
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,
|
||||
@@ -66,8 +70,20 @@ import {
|
||||
DialogTitle,
|
||||
DialogTrigger
|
||||
} from '@repo/ui/components/ui/dialog'
|
||||
import { Kbd } from '@repo/ui/components/ui/kbd'
|
||||
import {
|
||||
Popover,
|
||||
PopoverContent,
|
||||
PopoverTrigger
|
||||
} from '@repo/ui/components/ui/popover'
|
||||
import { Separator } from '@repo/ui/components/ui/separator'
|
||||
import { Spinner } from '@repo/ui/components/ui/spinner'
|
||||
import { cn } from '@repo/ui/lib/utils'
|
||||
import {
|
||||
labels,
|
||||
statuses,
|
||||
type Order as Order_
|
||||
} from '@repo/ui/routes/orders/data'
|
||||
import {
|
||||
CreditCard,
|
||||
creditCardSchema,
|
||||
@@ -107,6 +123,13 @@ type Invoice = {
|
||||
secure_url: string
|
||||
}
|
||||
|
||||
type Attempts = {
|
||||
sk: string
|
||||
status: string
|
||||
brand: string
|
||||
last4: string
|
||||
}
|
||||
|
||||
type Order = Order_ & {
|
||||
items: Item[]
|
||||
interest_amount: number
|
||||
@@ -115,6 +138,7 @@ type Order = Order_ & {
|
||||
subtotal: number
|
||||
discount: number
|
||||
address: Address
|
||||
payment_attempts: Attempts[]
|
||||
credit_card?: CreditCardProps
|
||||
coupon?: string
|
||||
installments?: number
|
||||
@@ -142,8 +166,9 @@ export default function Route({ loaderData: { order } }: Route.ComponentProps) {
|
||||
interest_amount,
|
||||
discount,
|
||||
invoice,
|
||||
subtotal,
|
||||
items = []
|
||||
payment_attempts = [],
|
||||
items = [],
|
||||
subtotal
|
||||
} = order
|
||||
|
||||
const Component =
|
||||
@@ -203,6 +228,12 @@ export default function Route({ loaderData: { order } }: Route.ComponentProps) {
|
||||
)}
|
||||
</div>
|
||||
</ItemContent>
|
||||
|
||||
{payment_attempts.length > 0 ? (
|
||||
<ItemActions>
|
||||
<PaymentAttemptsMenu payment_attempts={payment_attempts} />
|
||||
</ItemActions>
|
||||
) : null}
|
||||
</Item>
|
||||
</ItemGroup>
|
||||
|
||||
@@ -462,3 +493,60 @@ function CreditCardPaymentDialog({
|
||||
</Dialog>
|
||||
)
|
||||
}
|
||||
|
||||
function PaymentAttemptsMenu({
|
||||
payment_attempts
|
||||
}: {
|
||||
payment_attempts: Attempts[]
|
||||
}) {
|
||||
return (
|
||||
<Popover>
|
||||
<PopoverTrigger asChild>
|
||||
<Button variant="ghost" className="cursor-pointer">
|
||||
<EllipsisIcon />
|
||||
</Button>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent align="end" className="w-76">
|
||||
{/* <div className="border-b p-2 text-xs text-muted-foreground font-medium">
|
||||
Transações
|
||||
</div>*/}
|
||||
<div className="p-2 space-y-1.5">
|
||||
{payment_attempts.map(
|
||||
({ sk, brand, last4, status, ...props }, index) => {
|
||||
const [, , created_at] = sk.split('#')
|
||||
|
||||
return (
|
||||
<ul key={index} className="text-sm flex gap-1.5">
|
||||
<li>
|
||||
<Kbd>
|
||||
<DateTime
|
||||
options={{
|
||||
year: '2-digit',
|
||||
hour: '2-digit',
|
||||
minute: '2-digit'
|
||||
}}
|
||||
>
|
||||
{created_at}
|
||||
</DateTime>
|
||||
</Kbd>
|
||||
</li>
|
||||
<li>
|
||||
<Abbr maxLen={6}>{brand}</Abbr>
|
||||
</li>
|
||||
<li className="ml-auto">**** {last4}</li>
|
||||
<li className="flex items-center">
|
||||
{status === 'FAILED' ? (
|
||||
<CircleXIcon className="size-4 text-red-500" />
|
||||
) : (
|
||||
<CircleCheckIcon className="size-4 text-green-500" />
|
||||
)}
|
||||
</li>
|
||||
</ul>
|
||||
)
|
||||
}
|
||||
)}
|
||||
</div>
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -3,8 +3,8 @@ import type { Route } from './+types/route'
|
||||
import { MeiliSearchFilterBuilder } from 'meilisearch-helper'
|
||||
import { data } from 'react-router'
|
||||
|
||||
import { createSearch } from '@repo/util/meili'
|
||||
import { cloudflareContext } from '@repo/auth/context'
|
||||
import { createSearch } from '@repo/util/meili'
|
||||
|
||||
export async function loader({ params, context, request }: Route.LoaderArgs) {
|
||||
const cloudflare = context.get(cloudflareContext)
|
||||
|
||||
Reference in New Issue
Block a user