add cep and cnpj to api

This commit is contained in:
2025-12-28 18:48:55 -03:00
parent 8b81d5c245
commit f7d1854309
7 changed files with 185 additions and 151 deletions

View File

@@ -32,6 +32,7 @@ import {
import { useWizard } from '@/components/wizard'
import { isName } from '../_.$orgid.users.add/data'
import type { PaymentMethod } from '@repo/ui/routes/orders/data'
const creditCard = z.object({
holder_name: z
@@ -60,6 +61,9 @@ const formSchema = z.discriminatedUnion(
z.object({
payment_method: z.literal('BANK_SLIP')
}),
z.object({
payment_method: z.literal('MANUAL')
}),
z.object({
payment_method: z.literal('CREDIT_CARD'),
credit_card: creditCard
@@ -74,7 +78,7 @@ export type CreditCard = z.infer<typeof creditCard>
type PaymentProps = {
onSubmit: (value: any) => void | Promise<void>
payment_method?: 'PIX' | 'BANK_SLIP' | 'CREDIT_CARD'
payment_method?: PaymentMethod
credit_card?: CreditCard
}

View File

@@ -1,4 +1,4 @@
import { useToggle } from 'ahooks'
import { useRequest, useToggle } from 'ahooks'
import { PatternFormat } from 'react-number-format'
import { ExternalLinkIcon, PencilIcon, SearchIcon } from 'lucide-react'
import { Controller, useForm } from 'react-hook-form'
@@ -229,19 +229,21 @@ const formSchema = z.object({
state: z.string().min(1, 'Digite o estado')
})
type Schema = z.infer<typeof formSchema>
type Address = z.infer<typeof formSchema>
export function AddressDialog() {
const { handleSubmit, control } = useForm({
const [open, { toggle, set }] = useToggle()
const { handleSubmit, control, reset } = useForm({
resolver: zodResolver(formSchema)
})
const onSubmit = async (data: Schema) => {
const onSubmit = async (data: Address) => {
set(false)
console.log(data)
}
return (
<Dialog>
<Dialog open={open} onOpenChange={toggle}>
<DialogTrigger asChild>
<Button
variant="ghost"
@@ -254,70 +256,18 @@ export function AddressDialog() {
</Button>
</DialogTrigger>
<DialogContent className="sm:max-w-[425px]">
<form onSubmit={handleSubmit(onSubmit)} className="space-y-4">
<DialogHeader>
<DialogTitle>Editar endereço</DialogTitle>
<DialogDescription>
Este endereço será utilizado para a emissão da NFS-e.
</DialogDescription>
</DialogHeader>
<DialogHeader>
<DialogTitle>Editar endereço</DialogTitle>
<DialogDescription>
Este endereço será utilizado para a emissão da NFS-e.
</DialogDescription>
</DialogHeader>
<PostcodeForm onChange={reset} />
<form onSubmit={handleSubmit(onSubmit)} className="space-y-4">
<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"
@@ -431,6 +381,7 @@ export function AddressDialog() {
<Button
variant="link"
type="button"
tabIndex={-1}
className="text-black dark:text-white"
>
Cancel
@@ -444,3 +395,93 @@ export function AddressDialog() {
</Dialog>
)
}
type PostcodeFormProps = {
onChange: (value: Address) => void
}
function PostcodeForm({ onChange }: PostcodeFormProps) {
const formSchema = z.object({
postcode: z.string().min(1, 'Digite um CEP')
})
type Schema = z.infer<typeof formSchema>
const { control, handleSubmit, setError } = useForm({
resolver: zodResolver(formSchema)
})
const { runAsync, loading } = useRequest(
async (cep: string) => {
return await fetch(`/~/api/cep/${cep}.json`)
},
{ manual: true }
)
const onSubmit = async ({ postcode }: Schema) => {
const r = await runAsync(postcode)
if (r.ok) {
onChange?.((await r.json()) as Address)
return
}
setError('postcode', { message: 'CEP não encontrado' })
}
return (
<form onSubmit={handleSubmit(onSubmit)}>
<FieldGroup>
<Controller
control={control}
name="postcode"
defaultValue=""
render={({ field: { onChange, ref, ...field }, fieldState }) => (
<Field data-invalid={fieldState.invalid}>
{/* CEP */}
<FieldLabel htmlFor={field.name}>CEP</FieldLabel>
<InputGroup>
<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="submit"
variant="secondary"
className="cursor-pointer"
>
{loading ? <Spinner /> : <SearchIcon />}
</InputGroupButton>
</InputGroupAddon>
</InputGroup>
{fieldState.invalid && <FieldError errors={[fieldState.error]} />}
<FieldDescription>
<a
href="https://buscacepinter.correios.com.br/app/endereco/index.php"
target="_blank"
rel="noopener noreferrer"
className="inline-flex gap-1 items-center "
tabIndex={-1}
>
Não sei o CEP <ExternalLinkIcon className="size-4" />
</a>
</FieldDescription>
</Field>
)}
/>
</FieldGroup>
</form>
)
}