update credit card mask
This commit is contained in:
@@ -339,11 +339,7 @@ export function Bulk({
|
|||||||
|
|
||||||
type SummaryProps = {
|
type SummaryProps = {
|
||||||
subtotal: number
|
subtotal: number
|
||||||
coupon?: {
|
coupon?: Coupon
|
||||||
code: string
|
|
||||||
type: 'FIXED' | 'PERCENT'
|
|
||||||
amount: number
|
|
||||||
}
|
|
||||||
setValue: UseFormSetValue<any>
|
setValue: UseFormSetValue<any>
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -411,7 +407,7 @@ export function Summary({ subtotal, coupon, setValue }: SummaryProps) {
|
|||||||
tabIndex={-1}
|
tabIndex={-1}
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setValue('coupon', undefined)
|
setValue('coupon', null)
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<XIcon />
|
<XIcon />
|
||||||
@@ -420,11 +416,7 @@ export function Summary({ subtotal, coupon, setValue }: SummaryProps) {
|
|||||||
<Discount
|
<Discount
|
||||||
disabled={subtotal === 0}
|
disabled={subtotal === 0}
|
||||||
onChange={(coupon) => {
|
onChange={(coupon) => {
|
||||||
setValue('coupon', {
|
setValue('coupon', coupon)
|
||||||
// code: sk,
|
|
||||||
// amount: discount_amount,
|
|
||||||
// type: discount_type
|
|
||||||
})
|
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -72,6 +72,8 @@ export function Discount({ onChange, ...props }: DiscountProps) {
|
|||||||
discount_type: 'FIXED' | 'PERCENT'
|
discount_type: 'FIXED' | 'PERCENT'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.log(code)
|
||||||
|
|
||||||
onChange?.({ code, amount, type })
|
onChange?.({ code, amount, type })
|
||||||
|
|
||||||
reset()
|
reset()
|
||||||
|
|||||||
@@ -2,8 +2,9 @@ import { useForm, Controller, useWatch, type Control } from 'react-hook-form'
|
|||||||
import { PatternFormat } from 'react-number-format'
|
import { PatternFormat } from 'react-number-format'
|
||||||
import { zodResolver } from '@hookform/resolvers/zod'
|
import { zodResolver } from '@hookform/resolvers/zod'
|
||||||
import { ErrorMessage } from '@hookform/error-message'
|
import { ErrorMessage } from '@hookform/error-message'
|
||||||
import z from 'zod'
|
import { z } from 'zod'
|
||||||
import { ArrowRightIcon, CircleQuestionMarkIcon } from 'lucide-react'
|
import { ArrowRightIcon, CircleQuestionMarkIcon } from 'lucide-react'
|
||||||
|
import valid from 'card-validator'
|
||||||
|
|
||||||
import { Button } from '@repo/ui/components/ui/button'
|
import { Button } from '@repo/ui/components/ui/button'
|
||||||
import { Kbd } from '@repo/ui/components/ui/kbd'
|
import { Kbd } from '@repo/ui/components/ui/kbd'
|
||||||
@@ -19,6 +20,7 @@ import {
|
|||||||
} from '@repo/ui/components/ui/hover-card'
|
} from '@repo/ui/components/ui/hover-card'
|
||||||
import {
|
import {
|
||||||
Field,
|
Field,
|
||||||
|
FieldError,
|
||||||
FieldGroup,
|
FieldGroup,
|
||||||
FieldLabel,
|
FieldLabel,
|
||||||
FieldSet
|
FieldSet
|
||||||
@@ -29,10 +31,21 @@ import {
|
|||||||
} from '@repo/ui/components/ui/native-select'
|
} from '@repo/ui/components/ui/native-select'
|
||||||
|
|
||||||
import { useWizard } from '@/components/wizard'
|
import { useWizard } from '@/components/wizard'
|
||||||
|
import { isName } from '../_.$orgid.users.add/data'
|
||||||
|
|
||||||
const creditCard = z.object({
|
const creditCard = z.object({
|
||||||
holder_name: z.string().min(1),
|
holder_name: z
|
||||||
number: z.string().min(13).max(19),
|
.string()
|
||||||
|
.trim()
|
||||||
|
.nonempty('Digite um nome')
|
||||||
|
.refine(isName, { message: 'Nome inválido' }),
|
||||||
|
number: z.string().refine(
|
||||||
|
(value) => {
|
||||||
|
const numberValidation = valid.number(value)
|
||||||
|
return numberValidation.isValid
|
||||||
|
},
|
||||||
|
{ error: 'Número do cartão inválido' }
|
||||||
|
),
|
||||||
exp_month: z.string().min(2),
|
exp_month: z.string().min(2),
|
||||||
exp_year: z.string().min(4),
|
exp_year: z.string().min(4),
|
||||||
cvv: z.string().min(3).max(4)
|
cvv: z.string().min(3).max(4)
|
||||||
@@ -90,6 +103,8 @@ export function Payment({
|
|||||||
<Controller
|
<Controller
|
||||||
name="payment_method"
|
name="payment_method"
|
||||||
control={control}
|
control={control}
|
||||||
|
// @ts-ignore
|
||||||
|
defaultValue=""
|
||||||
render={({ field: { name, value, onChange }, formState }) => (
|
render={({ field: { name, value, onChange }, formState }) => (
|
||||||
<div className="space-y-1.5">
|
<div className="space-y-1.5">
|
||||||
<RadioGroup
|
<RadioGroup
|
||||||
@@ -143,6 +158,7 @@ export function Payment({
|
|||||||
>
|
>
|
||||||
Voltar
|
Voltar
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
<Button type="submit" variant="secondary">
|
<Button type="submit" variant="secondary">
|
||||||
Continuar <ArrowRightIcon />
|
Continuar <ArrowRightIcon />
|
||||||
</Button>
|
</Button>
|
||||||
@@ -161,6 +177,7 @@ export function CreditCard({ control }: { control: Control<Schema> }) {
|
|||||||
<FieldGroup>
|
<FieldGroup>
|
||||||
<FieldSet>
|
<FieldSet>
|
||||||
<FieldGroup>
|
<FieldGroup>
|
||||||
|
{/* Credir card number */}
|
||||||
<Controller
|
<Controller
|
||||||
control={control}
|
control={control}
|
||||||
name="credit_card.number"
|
name="credit_card.number"
|
||||||
@@ -185,10 +202,14 @@ export function CreditCard({ control }: { control: Control<Schema> }) {
|
|||||||
}}
|
}}
|
||||||
{...field}
|
{...field}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
{fieldState.invalid && (
|
||||||
|
<FieldError errors={[fieldState.error]} />
|
||||||
|
)}
|
||||||
</Field>
|
</Field>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
{/* Holder name */}
|
||||||
<Controller
|
<Controller
|
||||||
control={control}
|
control={control}
|
||||||
name="credit_card.holder_name"
|
name="credit_card.holder_name"
|
||||||
@@ -203,6 +224,9 @@ export function CreditCard({ control }: { control: Control<Schema> }) {
|
|||||||
aria-invalid={fieldState.invalid}
|
aria-invalid={fieldState.invalid}
|
||||||
{...field}
|
{...field}
|
||||||
/>
|
/>
|
||||||
|
{fieldState.invalid && (
|
||||||
|
<FieldError errors={[fieldState.error]} />
|
||||||
|
)}
|
||||||
</Field>
|
</Field>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -1,6 +1,12 @@
|
|||||||
|
import { useToggle } from 'ahooks'
|
||||||
|
import { PencilIcon } from 'lucide-react'
|
||||||
|
import { useForm } from 'react-hook-form'
|
||||||
|
import valid from 'card-validator'
|
||||||
|
|
||||||
import { Currency } from '@repo/ui/components/currency'
|
import { Currency } from '@repo/ui/components/currency'
|
||||||
import { Button } from '@repo/ui/components/ui/button'
|
import { Button } from '@repo/ui/components/ui/button'
|
||||||
import { Separator } from '@repo/ui/components/ui/separator'
|
import { Separator } from '@repo/ui/components/ui/separator'
|
||||||
|
import { Spinner } from '@repo/ui/components/ui/spinner'
|
||||||
import {
|
import {
|
||||||
Table,
|
Table,
|
||||||
TableBody,
|
TableBody,
|
||||||
@@ -10,18 +16,38 @@ import {
|
|||||||
TableHeader,
|
TableHeader,
|
||||||
TableRow
|
TableRow
|
||||||
} from '@repo/ui/components/ui/table'
|
} from '@repo/ui/components/ui/table'
|
||||||
|
import {
|
||||||
|
Item,
|
||||||
|
ItemActions,
|
||||||
|
ItemContent,
|
||||||
|
ItemDescription,
|
||||||
|
ItemGroup,
|
||||||
|
ItemTitle
|
||||||
|
} from '@repo/ui/components/ui/item'
|
||||||
|
import {
|
||||||
|
Dialog,
|
||||||
|
DialogClose,
|
||||||
|
DialogContent,
|
||||||
|
DialogDescription,
|
||||||
|
DialogFooter,
|
||||||
|
DialogHeader,
|
||||||
|
DialogTitle,
|
||||||
|
DialogTrigger
|
||||||
|
} from '@repo/ui/components/ui/dialog'
|
||||||
|
|
||||||
import { useWizard } from '@/components/wizard'
|
import { useWizard } from '@/components/wizard'
|
||||||
|
|
||||||
import { type WizardState } from './route'
|
import { type WizardState } from './route'
|
||||||
import { applyDiscount } from './discount'
|
import { applyDiscount } from './discount'
|
||||||
|
import { paymentMethods } from '@repo/ui/routes/orders/data'
|
||||||
|
|
||||||
type ReviewProps = {
|
type ReviewProps = {
|
||||||
state: WizardState
|
state: WizardState
|
||||||
|
onSubmit: (value: WizardState) => void | Promise<void>
|
||||||
}
|
}
|
||||||
|
|
||||||
export function Review({ state }: ReviewProps) {
|
export function Review({ state, onSubmit }: ReviewProps) {
|
||||||
const wizard = useWizard()
|
const wizard = useWizard()
|
||||||
|
const [loading, { set }] = useToggle()
|
||||||
const { coupon, items } = state || { items: [], coupon: {} }
|
const { coupon, items } = state || { items: [], coupon: {} }
|
||||||
const subtotal =
|
const subtotal =
|
||||||
items?.reduce(
|
items?.reduce(
|
||||||
@@ -36,13 +62,21 @@ export function Review({ state }: ReviewProps) {
|
|||||||
: 0
|
: 0
|
||||||
const total = subtotal > 0 ? subtotal + discount : 0
|
const total = subtotal > 0 ? subtotal + discount : 0
|
||||||
|
|
||||||
console.log(state)
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Table>
|
<Address {...state} />
|
||||||
|
|
||||||
|
<form
|
||||||
|
onSubmit={async (e) => {
|
||||||
|
e.preventDefault()
|
||||||
|
set(true)
|
||||||
|
await onSubmit(state)
|
||||||
|
}}
|
||||||
|
className="space-y-4"
|
||||||
|
>
|
||||||
|
<Table className="pointer-events-none">
|
||||||
<TableHeader>
|
<TableHeader>
|
||||||
<TableRow className="pointer-events-none">
|
<TableRow>
|
||||||
<TableHead>Curso</TableHead>
|
<TableHead>Curso</TableHead>
|
||||||
<TableHead>Quantidade</TableHead>
|
<TableHead>Quantidade</TableHead>
|
||||||
<TableHead>Valor unit.</TableHead>
|
<TableHead>Valor unit.</TableHead>
|
||||||
@@ -66,7 +100,7 @@ export function Review({ state }: ReviewProps) {
|
|||||||
})}
|
})}
|
||||||
</TableBody>
|
</TableBody>
|
||||||
<TableFooter>
|
<TableFooter>
|
||||||
<TableRow className="pointer-events-none">
|
<TableRow>
|
||||||
<TableCell className="text-right" colSpan={3}>
|
<TableCell className="text-right" colSpan={3}>
|
||||||
Subtotal
|
Subtotal
|
||||||
</TableCell>
|
</TableCell>
|
||||||
@@ -74,7 +108,7 @@ export function Review({ state }: ReviewProps) {
|
|||||||
<Currency>{subtotal}</Currency>
|
<Currency>{subtotal}</Currency>
|
||||||
</TableCell>
|
</TableCell>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
<TableRow className="pointer-events-none">
|
<TableRow>
|
||||||
<TableCell className="text-right" colSpan={3}>
|
<TableCell className="text-right" colSpan={3}>
|
||||||
Descontos
|
Descontos
|
||||||
</TableCell>
|
</TableCell>
|
||||||
@@ -82,7 +116,7 @@ export function Review({ state }: ReviewProps) {
|
|||||||
<Currency>{discount}</Currency>
|
<Currency>{discount}</Currency>
|
||||||
</TableCell>
|
</TableCell>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
<TableRow className="pointer-events-none">
|
<TableRow>
|
||||||
<TableCell className="text-right" colSpan={3}>
|
<TableCell className="text-right" colSpan={3}>
|
||||||
Total
|
Total
|
||||||
</TableCell>
|
</TableCell>
|
||||||
@@ -105,10 +139,103 @@ export function Review({ state }: ReviewProps) {
|
|||||||
>
|
>
|
||||||
Voltar
|
Voltar
|
||||||
</Button>
|
</Button>
|
||||||
<Button type="submit">
|
|
||||||
|
<Button type="submit" disabled={loading}>
|
||||||
|
{loading && <Spinner />}
|
||||||
Pagar <Currency>{total}</Currency>
|
Pagar <Currency>{total}</Currency>
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
</form>
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function Address({ payment_method, credit_card }: WizardState) {
|
||||||
|
const numberValidation = valid.number(credit_card?.number)
|
||||||
|
// console.log(numberValidation)
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ItemGroup className="grid lg:grid-cols-2 gap-4">
|
||||||
|
<Item variant="outline" className="items-start">
|
||||||
|
<ItemContent>
|
||||||
|
<ItemTitle>Endereço de cobrança</ItemTitle>
|
||||||
|
<ul className="text-muted-foreground text-sm leading-normal font-normal text-balance">
|
||||||
|
Rua Monsenhor Ivo Zanlorenzi, nº 5190, ap 1802
|
||||||
|
<br />
|
||||||
|
Cidade Industrial
|
||||||
|
<br />
|
||||||
|
Curitiba, Paraná
|
||||||
|
<br />
|
||||||
|
81280-350
|
||||||
|
</ul>
|
||||||
|
</ItemContent>
|
||||||
|
<ItemActions>
|
||||||
|
<DialogDemo />
|
||||||
|
</ItemActions>
|
||||||
|
</Item>
|
||||||
|
|
||||||
|
<Item variant="outline" className="items-start">
|
||||||
|
<ItemContent>
|
||||||
|
<ItemTitle>Forma de pagamento</ItemTitle>
|
||||||
|
<ItemDescription>
|
||||||
|
{payment_method ? paymentMethods[payment_method] : payment_method}
|
||||||
|
{credit_card ? (
|
||||||
|
<>
|
||||||
|
<br />
|
||||||
|
{numberValidation.card?.niceType} ****{' '}
|
||||||
|
{credit_card.number.slice(-4)}
|
||||||
|
</>
|
||||||
|
) : null}
|
||||||
|
</ItemDescription>
|
||||||
|
</ItemContent>
|
||||||
|
</Item>
|
||||||
|
</ItemGroup>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function DialogDemo() {
|
||||||
|
const form = useForm()
|
||||||
|
const { handleSubmit } = form
|
||||||
|
|
||||||
|
const onSubmit = async () => {}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<form onSubmit={handleSubmit(onSubmit)}>
|
||||||
|
<Dialog>
|
||||||
|
<DialogTrigger asChild>
|
||||||
|
<Button
|
||||||
|
variant="ghost"
|
||||||
|
type="button"
|
||||||
|
className="text-muted-foreground cursor-pointer"
|
||||||
|
size="icon-sm"
|
||||||
|
>
|
||||||
|
<PencilIcon />
|
||||||
|
<span className="sr-only">Editar endereço</span>
|
||||||
|
</Button>
|
||||||
|
</DialogTrigger>
|
||||||
|
<DialogContent className="sm:max-w-[425px]">
|
||||||
|
<DialogHeader>
|
||||||
|
<DialogTitle>Editar endereço</DialogTitle>
|
||||||
|
<DialogDescription>
|
||||||
|
Este endereço será utilizado para a emissão da NFS-e.
|
||||||
|
</DialogDescription>
|
||||||
|
</DialogHeader>
|
||||||
|
|
||||||
|
<DialogFooter className="*:cursor-pointer">
|
||||||
|
<DialogClose asChild>
|
||||||
|
<Button
|
||||||
|
variant="link"
|
||||||
|
type="button"
|
||||||
|
className="text-black dark:text-white"
|
||||||
|
>
|
||||||
|
Cancel
|
||||||
|
</Button>
|
||||||
|
</DialogClose>
|
||||||
|
|
||||||
|
<Button type="submit">Atualizar endereço</Button>
|
||||||
|
</DialogFooter>
|
||||||
|
</DialogContent>
|
||||||
|
</Dialog>
|
||||||
|
</form>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ import { createSearch } from '@repo/util/meili'
|
|||||||
import { cloudflareContext } from '@repo/auth/context'
|
import { cloudflareContext } from '@repo/auth/context'
|
||||||
import { Label } from '@repo/ui/components/ui/label'
|
import { Label } from '@repo/ui/components/ui/label'
|
||||||
import { Skeleton } from '@repo/ui/components/skeleton'
|
import { Skeleton } from '@repo/ui/components/skeleton'
|
||||||
|
import type { PaymentMethod } from '@repo/ui/routes/orders/data'
|
||||||
|
|
||||||
import { Wizard, WizardStep } from '@/components/wizard'
|
import { Wizard, WizardStep } from '@/components/wizard'
|
||||||
import { Step, StepItem, StepSeparator } from '@/components/step'
|
import { Step, StepItem, StepSeparator } from '@/components/step'
|
||||||
@@ -34,6 +35,7 @@ import { Bulk, type Item } from './bulk'
|
|||||||
import { Payment, type CreditCard } from './payment'
|
import { Payment, type CreditCard } from './payment'
|
||||||
import { Review } from './review'
|
import { Review } from './review'
|
||||||
import type { Coupon } from './discount'
|
import type { Coupon } from './discount'
|
||||||
|
import { useFetcher } from 'react-router'
|
||||||
|
|
||||||
export type WizardState = {
|
export type WizardState = {
|
||||||
index: number
|
index: number
|
||||||
@@ -41,7 +43,7 @@ export type WizardState = {
|
|||||||
items: Item[]
|
items: Item[]
|
||||||
enrollments: Enrollment[]
|
enrollments: Enrollment[]
|
||||||
coupon?: Coupon
|
coupon?: Coupon
|
||||||
payment_method?: 'PIX' | 'BANK_SLIP' | 'CREDIT_CARD'
|
payment_method?: PaymentMethod
|
||||||
credit_card?: CreditCard
|
credit_card?: CreditCard
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -74,12 +76,14 @@ export async function loader({ context }: Route.LoaderArgs) {
|
|||||||
|
|
||||||
export async function action({ request }: Route.ActionArgs) {
|
export async function action({ request }: Route.ActionArgs) {
|
||||||
const body = (await request.json()) as object
|
const body = (await request.json()) as object
|
||||||
|
|
||||||
console.log(body)
|
console.log(body)
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function Route({
|
export default function Route({
|
||||||
loaderData: { courses }
|
loaderData: { courses }
|
||||||
}: Route.ComponentProps) {
|
}: Route.ComponentProps) {
|
||||||
|
const fetcher = useFetcher()
|
||||||
const [mounted, setMounted] = useState(false)
|
const [mounted, setMounted] = useState(false)
|
||||||
const [state, setState] = useLocalStorageState<WizardState>('wizard_cart', {
|
const [state, setState] = useLocalStorageState<WizardState>('wizard_cart', {
|
||||||
defaultValue: emptyWizard
|
defaultValue: emptyWizard
|
||||||
@@ -96,6 +100,13 @@ export default function Route({
|
|||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const onSubmit = async (data: WizardState) => {
|
||||||
|
await fetcher.submit(JSON.stringify(data), {
|
||||||
|
method: 'post',
|
||||||
|
encType: 'application/json'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
useMount(() => {
|
useMount(() => {
|
||||||
setMounted(true)
|
setMounted(true)
|
||||||
})
|
})
|
||||||
@@ -206,7 +217,7 @@ export default function Route({
|
|||||||
|
|
||||||
{/* Review */}
|
{/* Review */}
|
||||||
<WizardStep name="review">
|
<WizardStep name="review">
|
||||||
<Review state={state} />
|
<Review state={state} onSubmit={onSubmit} />
|
||||||
</WizardStep>
|
</WizardStep>
|
||||||
</Wizard>
|
</Wizard>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import {
|
|||||||
} from 'unique-names-generator'
|
} from 'unique-names-generator'
|
||||||
import { z } from 'zod'
|
import { z } from 'zod'
|
||||||
|
|
||||||
const isName = (name: string) => name && name.includes(' ')
|
export const isName = (name: string) => name && name.includes(' ')
|
||||||
|
|
||||||
function randomEmail() {
|
function randomEmail() {
|
||||||
const numberDict = NumberDictionary.generate({ min: 100, max: 999 })
|
const numberDict = NumberDictionary.generate({ min: 100, max: 999 })
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
"@repo/ui": "*",
|
"@repo/ui": "*",
|
||||||
"@repo/util": "^0.0.0",
|
"@repo/util": "^0.0.0",
|
||||||
"@tanstack/react-table": "^8.21.3",
|
"@tanstack/react-table": "^8.21.3",
|
||||||
|
"card-validator": "^10.0.3",
|
||||||
"cookie": "^1.1.1",
|
"cookie": "^1.1.1",
|
||||||
"date-fns": "^4.1.0",
|
"date-fns": "^4.1.0",
|
||||||
"flat": "^6.0.1",
|
"flat": "^6.0.1",
|
||||||
|
|||||||
16
package-lock.json
generated
16
package-lock.json
generated
@@ -30,6 +30,7 @@
|
|||||||
"@repo/ui": "*",
|
"@repo/ui": "*",
|
||||||
"@repo/util": "^0.0.0",
|
"@repo/util": "^0.0.0",
|
||||||
"@tanstack/react-table": "^8.21.3",
|
"@tanstack/react-table": "^8.21.3",
|
||||||
|
"card-validator": "^10.0.3",
|
||||||
"cookie": "^1.1.1",
|
"cookie": "^1.1.1",
|
||||||
"date-fns": "^4.1.0",
|
"date-fns": "^4.1.0",
|
||||||
"flat": "^6.0.1",
|
"flat": "^6.0.1",
|
||||||
@@ -4783,6 +4784,15 @@
|
|||||||
],
|
],
|
||||||
"license": "CC-BY-4.0"
|
"license": "CC-BY-4.0"
|
||||||
},
|
},
|
||||||
|
"node_modules/card-validator": {
|
||||||
|
"version": "10.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/card-validator/-/card-validator-10.0.3.tgz",
|
||||||
|
"integrity": "sha512-xOEDsK3hojV0OIpmrR64eZGpngnOqRDEP20O+WSRtvjLSW6nyekW4i2N9SzYg679uFO3RyHcFHxb+mml5tXc4A==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"credit-card-type": "^10.0.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/chokidar": {
|
"node_modules/chokidar": {
|
||||||
"version": "4.0.3",
|
"version": "4.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz",
|
||||||
@@ -4905,6 +4915,12 @@
|
|||||||
"url": "https://opencollective.com/express"
|
"url": "https://opencollective.com/express"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/credit-card-type": {
|
||||||
|
"version": "10.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/credit-card-type/-/credit-card-type-10.1.0.tgz",
|
||||||
|
"integrity": "sha512-yd9ebGqWQ9zDvxrvCOkX80GiTvVJ28940uIMqRA58Cu3ReiPkOS4p45d9Y2cmJZtZgp90WdwLSiUtI8lHDgE2g==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/crypto-js": {
|
"node_modules/crypto-js": {
|
||||||
"version": "4.2.0",
|
"version": "4.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.2.0.tgz",
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import { HelpCircleIcon } from 'lucide-react'
|
|||||||
import { cn } from '@repo/ui/lib/utils'
|
import { cn } from '@repo/ui/lib/utils'
|
||||||
import { Badge } from '@repo/ui/components/ui/badge'
|
import { Badge } from '@repo/ui/components/ui/badge'
|
||||||
|
|
||||||
import { labels, methods, statuses, type Order } from './data'
|
import { labels, paymentMethods, statuses, type Order } from './data'
|
||||||
|
|
||||||
export type { Order }
|
export type { Order }
|
||||||
|
|
||||||
@@ -21,7 +21,7 @@ export const columns: ColumnDef<Order>[] = [
|
|||||||
header: 'Forma de pag.',
|
header: 'Forma de pag.',
|
||||||
cell: ({ row }) => {
|
cell: ({ row }) => {
|
||||||
const paymentMethod = row.getValue('payment_method') as string
|
const paymentMethod = row.getValue('payment_method') as string
|
||||||
return <>{methods[paymentMethod] ?? paymentMethod}</>
|
return <>{paymentMethods[paymentMethod] ?? paymentMethod}</>
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -8,13 +8,15 @@ import {
|
|||||||
type LucideIcon
|
type LucideIcon
|
||||||
} from 'lucide-react'
|
} from 'lucide-react'
|
||||||
|
|
||||||
|
export type PaymentMethod = 'PIX' | 'BANK_SLIP' | 'CREDIT_CARD' | 'MANUAL'
|
||||||
|
|
||||||
// This type is used to define the shape of our data.
|
// This type is used to define the shape of our data.
|
||||||
// You can use a Zod schema here if you want.
|
// You can use a Zod schema here if you want.
|
||||||
export type Order = {
|
export type Order = {
|
||||||
id: string
|
id: string
|
||||||
total: number
|
total: number
|
||||||
status: 'PENDING' | 'PAID' | 'DECLINED' | 'EXPIRED' | 'REFUNDED' | 'CANCELED'
|
status: 'PENDING' | 'PAID' | 'DECLINED' | 'EXPIRED' | 'REFUNDED' | 'CANCELED'
|
||||||
payment_method: 'PIX' | 'CREDIT_CARD' | 'BANK_SLIP' | 'MANUAL'
|
payment_method: PaymentMethod
|
||||||
name: string
|
name: string
|
||||||
email: string
|
email: string
|
||||||
}
|
}
|
||||||
@@ -64,7 +66,7 @@ export const labels: Record<string, string> = {
|
|||||||
CANCELED: 'Cancelado'
|
CANCELED: 'Cancelado'
|
||||||
}
|
}
|
||||||
|
|
||||||
export const methods: Record<string, string> = {
|
export const paymentMethods: Record<string, string> = {
|
||||||
PIX: 'Pix',
|
PIX: 'Pix',
|
||||||
CREDIT_CARD: 'Cartão de crédito',
|
CREDIT_CARD: 'Cartão de crédito',
|
||||||
BANK_SLIP: 'Boleto bancário',
|
BANK_SLIP: 'Boleto bancário',
|
||||||
|
|||||||
Reference in New Issue
Block a user