add dialog
This commit is contained in:
@@ -1,6 +1,9 @@
|
||||
import { useToggle } from 'ahooks'
|
||||
import { PencilIcon } from 'lucide-react'
|
||||
import { useForm } from 'react-hook-form'
|
||||
import { PatternFormat } from 'react-number-format'
|
||||
import { ExternalLinkIcon, PencilIcon, SearchIcon } from 'lucide-react'
|
||||
import { Controller, useForm } from 'react-hook-form'
|
||||
import { zodResolver } from '@hookform/resolvers/zod'
|
||||
import { z } from 'zod'
|
||||
import valid from 'card-validator'
|
||||
|
||||
import { Currency } from '@repo/ui/components/currency'
|
||||
@@ -39,6 +42,21 @@ import { useWizard } from '@/components/wizard'
|
||||
import { type WizardState } from './route'
|
||||
import { applyDiscount } from './discount'
|
||||
import { paymentMethods } from '@repo/ui/routes/orders/data'
|
||||
import {
|
||||
Field,
|
||||
FieldDescription,
|
||||
FieldError,
|
||||
FieldGroup,
|
||||
FieldLabel,
|
||||
FieldSet
|
||||
} from '@repo/ui/components/ui/field'
|
||||
import { Input } from '@repo/ui/components/ui/input'
|
||||
import {
|
||||
InputGroup,
|
||||
InputGroupAddon,
|
||||
InputGroupButton,
|
||||
InputGroupInput
|
||||
} from '@repo/ui/components/ui/input-group'
|
||||
|
||||
type ReviewProps = {
|
||||
state: WizardState
|
||||
@@ -64,7 +82,7 @@ export function Review({ state, onSubmit }: ReviewProps) {
|
||||
|
||||
return (
|
||||
<>
|
||||
<Address {...state} />
|
||||
<Address total={total} {...state} />
|
||||
|
||||
<form
|
||||
onSubmit={async (e) => {
|
||||
@@ -150,9 +168,12 @@ export function Review({ state, onSubmit }: ReviewProps) {
|
||||
)
|
||||
}
|
||||
|
||||
export function Address({ payment_method, credit_card }: WizardState) {
|
||||
export function Address({
|
||||
total,
|
||||
payment_method,
|
||||
credit_card
|
||||
}: WizardState & { total: number }) {
|
||||
const numberValidation = valid.number(credit_card?.number)
|
||||
// console.log(numberValidation)
|
||||
|
||||
return (
|
||||
<ItemGroup className="grid lg:grid-cols-2 gap-4">
|
||||
@@ -170,7 +191,7 @@ export function Address({ payment_method, credit_card }: WizardState) {
|
||||
</ul>
|
||||
</ItemContent>
|
||||
<ItemActions>
|
||||
<DialogDemo />
|
||||
<AddressDialog />
|
||||
</ItemActions>
|
||||
</Item>
|
||||
|
||||
@@ -178,14 +199,20 @@ export function Address({ payment_method, credit_card }: WizardState) {
|
||||
<ItemContent>
|
||||
<ItemTitle>Forma de pagamento</ItemTitle>
|
||||
<ItemDescription>
|
||||
{payment_method ? paymentMethods[payment_method] : payment_method}
|
||||
{credit_card ? (
|
||||
<>
|
||||
<br />
|
||||
{numberValidation.card?.niceType} ****{' '}
|
||||
{numberValidation.card?.niceType} (Crédito) ****{' '}
|
||||
{credit_card.number.slice(-4)}
|
||||
<br />
|
||||
1x <Currency>{total}</Currency>
|
||||
</>
|
||||
) : null}
|
||||
) : (
|
||||
<>
|
||||
{payment_method
|
||||
? paymentMethods[payment_method]
|
||||
: payment_method}
|
||||
</>
|
||||
)}
|
||||
</ItemDescription>
|
||||
</ItemContent>
|
||||
</Item>
|
||||
@@ -193,27 +220,41 @@ export function Address({ payment_method, credit_card }: WizardState) {
|
||||
)
|
||||
}
|
||||
|
||||
export function DialogDemo() {
|
||||
const form = useForm()
|
||||
const { handleSubmit } = form
|
||||
const formSchema = z.object({
|
||||
postcode: z.string().min(1, 'Digite um CEP'),
|
||||
address1: z.string().min(1, 'Digite um endereço'),
|
||||
address2: z.string().optional(),
|
||||
neighborhood: z.string().min(1, 'Digite o bairro'),
|
||||
city: z.string().min(1, 'Digite a cidade'),
|
||||
state: z.string().min(1, 'Digite o estado')
|
||||
})
|
||||
|
||||
const onSubmit = async () => {}
|
||||
type Schema = z.infer<typeof formSchema>
|
||||
|
||||
export function AddressDialog() {
|
||||
const { handleSubmit, control } = useForm({
|
||||
resolver: zodResolver(formSchema)
|
||||
})
|
||||
|
||||
const onSubmit = async (data: Schema) => {
|
||||
console.log(data)
|
||||
}
|
||||
|
||||
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]">
|
||||
<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]">
|
||||
<form onSubmit={handleSubmit(onSubmit)} className="space-y-4">
|
||||
<DialogHeader>
|
||||
<DialogTitle>Editar endereço</DialogTitle>
|
||||
<DialogDescription>
|
||||
@@ -221,6 +262,170 @@ export function DialogDemo() {
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
|
||||
<FieldGroup>
|
||||
<FieldSet>
|
||||
<Controller
|
||||
control={control}
|
||||
name="postcode"
|
||||
defaultValue=""
|
||||
render={({
|
||||
field: { onChange, ref, ...field },
|
||||
fieldState
|
||||
}) => (
|
||||
<Field data-invalid={fieldState.invalid}>
|
||||
<FieldLabel htmlFor={field.name}>CEP</FieldLabel>
|
||||
<InputGroup>
|
||||
{/*<InputGroupInput
|
||||
id={field.name}
|
||||
aria-invalid={fieldState.invalid}
|
||||
{...field}
|
||||
/>*/}
|
||||
|
||||
<PatternFormat
|
||||
id={field.name}
|
||||
format="#####-###"
|
||||
mask="_"
|
||||
placeholder="_____-___"
|
||||
customInput={InputGroupInput}
|
||||
getInputRef={ref}
|
||||
aria-invalid={fieldState.invalid}
|
||||
onValueChange={({ value }) => {
|
||||
onChange(value)
|
||||
}}
|
||||
{...field}
|
||||
/>
|
||||
<InputGroupAddon align="inline-end">
|
||||
<InputGroupButton type="button" variant="secondary">
|
||||
<SearchIcon />
|
||||
</InputGroupButton>
|
||||
</InputGroupAddon>
|
||||
</InputGroup>
|
||||
<FieldDescription>
|
||||
<a
|
||||
href="https://buscacepinter.correios.com.br/app/endereco/index.php"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="inline-flex gap-1 items-center "
|
||||
>
|
||||
Não sei o CEP <ExternalLinkIcon className="size-4" />
|
||||
</a>
|
||||
</FieldDescription>
|
||||
|
||||
{fieldState.invalid && (
|
||||
<FieldError errors={[fieldState.error]} />
|
||||
)}
|
||||
</Field>
|
||||
)}
|
||||
/>
|
||||
|
||||
<Controller
|
||||
control={control}
|
||||
name="address1"
|
||||
defaultValue=""
|
||||
render={({ field, fieldState }) => (
|
||||
<Field data-invalid={fieldState.invalid}>
|
||||
<FieldLabel htmlFor={field.name}>Endereço</FieldLabel>
|
||||
<Input
|
||||
id={field.name}
|
||||
aria-invalid={fieldState.invalid}
|
||||
{...field}
|
||||
/>
|
||||
|
||||
{fieldState.invalid && (
|
||||
<FieldError errors={[fieldState.error]} />
|
||||
)}
|
||||
</Field>
|
||||
)}
|
||||
/>
|
||||
|
||||
<Controller
|
||||
control={control}
|
||||
name="address2"
|
||||
defaultValue=""
|
||||
render={({ field, fieldState }) => (
|
||||
<Field data-invalid={fieldState.invalid}>
|
||||
<FieldLabel htmlFor={field.name}>
|
||||
Complemento{' '}
|
||||
<span className="text-muted-foreground">(opcional)</span>
|
||||
</FieldLabel>
|
||||
<Input
|
||||
id={field.name}
|
||||
aria-invalid={fieldState.invalid}
|
||||
{...field}
|
||||
/>
|
||||
|
||||
{fieldState.invalid && (
|
||||
<FieldError errors={[fieldState.error]} />
|
||||
)}
|
||||
</Field>
|
||||
)}
|
||||
/>
|
||||
</FieldSet>
|
||||
|
||||
<FieldSet className="grid grid-cols-3">
|
||||
{/* Neighborhood */}
|
||||
<Controller
|
||||
control={control}
|
||||
name="neighborhood"
|
||||
defaultValue=""
|
||||
render={({ field, fieldState }) => (
|
||||
<Field data-invalid={fieldState.invalid}>
|
||||
<FieldLabel htmlFor={field.name}>Bairro</FieldLabel>
|
||||
<Input
|
||||
id={field.name}
|
||||
aria-invalid={fieldState.invalid}
|
||||
{...field}
|
||||
/>
|
||||
|
||||
{fieldState.invalid && (
|
||||
<FieldError errors={[fieldState.error]} />
|
||||
)}
|
||||
</Field>
|
||||
)}
|
||||
/>
|
||||
{/* City */}
|
||||
<Controller
|
||||
control={control}
|
||||
name="city"
|
||||
defaultValue=""
|
||||
render={({ field, fieldState }) => (
|
||||
<Field data-invalid={fieldState.invalid}>
|
||||
<FieldLabel htmlFor={field.name}>Cidade</FieldLabel>
|
||||
<Input
|
||||
id={field.name}
|
||||
aria-invalid={fieldState.invalid}
|
||||
{...field}
|
||||
/>
|
||||
|
||||
{fieldState.invalid && (
|
||||
<FieldError errors={[fieldState.error]} />
|
||||
)}
|
||||
</Field>
|
||||
)}
|
||||
/>
|
||||
{/* State */}
|
||||
<Controller
|
||||
control={control}
|
||||
name="state"
|
||||
defaultValue=""
|
||||
render={({ field, fieldState }) => (
|
||||
<Field data-invalid={fieldState.invalid}>
|
||||
<FieldLabel htmlFor={field.name}>Estado</FieldLabel>
|
||||
<Input
|
||||
id={field.name}
|
||||
aria-invalid={fieldState.invalid}
|
||||
{...field}
|
||||
/>
|
||||
|
||||
{fieldState.invalid && (
|
||||
<FieldError errors={[fieldState.error]} />
|
||||
)}
|
||||
</Field>
|
||||
)}
|
||||
/>
|
||||
</FieldSet>
|
||||
</FieldGroup>
|
||||
|
||||
<DialogFooter className="*:cursor-pointer">
|
||||
<DialogClose asChild>
|
||||
<Button
|
||||
@@ -234,8 +439,8 @@ export function DialogDemo() {
|
||||
|
||||
<Button type="submit">Atualizar endereço</Button>
|
||||
</DialogFooter>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
</form>
|
||||
</form>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user