add cep and cnpj to api
This commit is contained in:
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,65 +0,0 @@
|
||||
import type { Route } from './+types/route'
|
||||
|
||||
import { data } from 'react-router'
|
||||
|
||||
export async function loader({ params, context, request }: Route.LoaderArgs) {
|
||||
const url = new URL(request.url)
|
||||
const cnpj = url.searchParams.get('cnpj')
|
||||
|
||||
const r = await fetch(`https://brasilapi.com.br/api/cnpj/v1/${cnpj}`, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'User-Agent':
|
||||
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36',
|
||||
Accept: 'application/json'
|
||||
}
|
||||
})
|
||||
|
||||
if (!r.ok) {
|
||||
throw new Response(await r.text(), { status: r.status })
|
||||
}
|
||||
|
||||
return data({})
|
||||
}
|
||||
|
||||
// export const prerender = false
|
||||
// import type { APIRoute } from 'astro'
|
||||
// import lodash from 'lodash'
|
||||
|
||||
// export const GET: APIRoute = async ({ params }) => {
|
||||
// // await new Promise((r) => setTimeout(r, 2000))
|
||||
|
||||
// const cnpj = params.cnpj
|
||||
// const res = await fetch(`https://brasilapi.com.br/api/cnpj/v1/${cnpj}`, {
|
||||
// method: 'GET',
|
||||
// headers: {
|
||||
// 'User-Agent':
|
||||
// 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36',
|
||||
// Accept: 'application/json'
|
||||
// }
|
||||
// })
|
||||
|
||||
// if (!res.ok) {
|
||||
// return new Response(null, {
|
||||
// status: 404
|
||||
// })
|
||||
// }
|
||||
|
||||
// const json = await res.json()
|
||||
// const addr = lodash.startCase(
|
||||
// lodash.toLower(`${json.descricao_tipo_de_logradouro} ${json.logradouro}`)
|
||||
// )
|
||||
|
||||
// return new Response(
|
||||
// JSON.stringify({
|
||||
// name: json.razao_social,
|
||||
// address: {
|
||||
// postcode: json.cep,
|
||||
// address1: `${addr}, ${json.numero}`,
|
||||
// neighborhood: lodash.capitalize(json.bairro),
|
||||
// city: lodash.capitalize(json.municipio),
|
||||
// state: json.uf
|
||||
// }
|
||||
// })
|
||||
// )
|
||||
// }
|
||||
@@ -0,0 +1,23 @@
|
||||
import { data } from 'react-router'
|
||||
import type { Route } from './+types/route'
|
||||
|
||||
export async function loader({ params }: Route.LoaderArgs) {
|
||||
const r = await fetch(`https://opencep.com/v1/${params.cep}`, {
|
||||
method: 'GET'
|
||||
})
|
||||
|
||||
if (!r.ok) {
|
||||
throw new Response(await r.text(), { status: r.status })
|
||||
}
|
||||
|
||||
const json = (await r.json()) as any
|
||||
|
||||
return data({
|
||||
postcode: json.cep.replace(/\D/g, ''),
|
||||
address1: json.logradouro,
|
||||
address2: json.complemento,
|
||||
neighborhood: json.bairro,
|
||||
city: json.localidade,
|
||||
state: json.uf
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
import type { Route } from './+types/route'
|
||||
|
||||
import { data } from 'react-router'
|
||||
import lodash from 'lodash'
|
||||
|
||||
export async function loader({ params }: Route.LoaderArgs) {
|
||||
const r = await fetch(`https://minhareceita.org/${params.cnpj}`, {
|
||||
method: 'GET'
|
||||
})
|
||||
|
||||
if (!r.ok) {
|
||||
throw new Response(await r.text(), { status: r.status })
|
||||
}
|
||||
|
||||
const json = (await r.json()) as any
|
||||
const addr = lodash.startCase(
|
||||
lodash.toLower(`${json.descricao_tipo_de_logradouro} ${json.logradouro}`)
|
||||
)
|
||||
|
||||
return data({
|
||||
name: json.razao_social,
|
||||
address: {
|
||||
postcode: json.cep,
|
||||
address1: `${addr}, ${json.numero}`,
|
||||
neighborhood: lodash.capitalize(json.bairro),
|
||||
city: lodash.capitalize(json.municipio),
|
||||
state: json.uf
|
||||
}
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user