add cep and cnpj to api
This commit is contained in:
@@ -32,6 +32,7 @@ import {
|
|||||||
|
|
||||||
import { useWizard } from '@/components/wizard'
|
import { useWizard } from '@/components/wizard'
|
||||||
import { isName } from '../_.$orgid.users.add/data'
|
import { isName } from '../_.$orgid.users.add/data'
|
||||||
|
import type { PaymentMethod } from '@repo/ui/routes/orders/data'
|
||||||
|
|
||||||
const creditCard = z.object({
|
const creditCard = z.object({
|
||||||
holder_name: z
|
holder_name: z
|
||||||
@@ -60,6 +61,9 @@ const formSchema = z.discriminatedUnion(
|
|||||||
z.object({
|
z.object({
|
||||||
payment_method: z.literal('BANK_SLIP')
|
payment_method: z.literal('BANK_SLIP')
|
||||||
}),
|
}),
|
||||||
|
z.object({
|
||||||
|
payment_method: z.literal('MANUAL')
|
||||||
|
}),
|
||||||
z.object({
|
z.object({
|
||||||
payment_method: z.literal('CREDIT_CARD'),
|
payment_method: z.literal('CREDIT_CARD'),
|
||||||
credit_card: creditCard
|
credit_card: creditCard
|
||||||
@@ -74,7 +78,7 @@ export type CreditCard = z.infer<typeof creditCard>
|
|||||||
|
|
||||||
type PaymentProps = {
|
type PaymentProps = {
|
||||||
onSubmit: (value: any) => void | Promise<void>
|
onSubmit: (value: any) => void | Promise<void>
|
||||||
payment_method?: 'PIX' | 'BANK_SLIP' | 'CREDIT_CARD'
|
payment_method?: PaymentMethod
|
||||||
credit_card?: CreditCard
|
credit_card?: CreditCard
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { useToggle } from 'ahooks'
|
import { useRequest, useToggle } from 'ahooks'
|
||||||
import { PatternFormat } from 'react-number-format'
|
import { PatternFormat } from 'react-number-format'
|
||||||
import { ExternalLinkIcon, PencilIcon, SearchIcon } from 'lucide-react'
|
import { ExternalLinkIcon, PencilIcon, SearchIcon } from 'lucide-react'
|
||||||
import { Controller, useForm } from 'react-hook-form'
|
import { Controller, useForm } from 'react-hook-form'
|
||||||
@@ -229,19 +229,21 @@ const formSchema = z.object({
|
|||||||
state: z.string().min(1, 'Digite o estado')
|
state: z.string().min(1, 'Digite o estado')
|
||||||
})
|
})
|
||||||
|
|
||||||
type Schema = z.infer<typeof formSchema>
|
type Address = z.infer<typeof formSchema>
|
||||||
|
|
||||||
export function AddressDialog() {
|
export function AddressDialog() {
|
||||||
const { handleSubmit, control } = useForm({
|
const [open, { toggle, set }] = useToggle()
|
||||||
|
const { handleSubmit, control, reset } = useForm({
|
||||||
resolver: zodResolver(formSchema)
|
resolver: zodResolver(formSchema)
|
||||||
})
|
})
|
||||||
|
|
||||||
const onSubmit = async (data: Schema) => {
|
const onSubmit = async (data: Address) => {
|
||||||
|
set(false)
|
||||||
console.log(data)
|
console.log(data)
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Dialog>
|
<Dialog open={open} onOpenChange={toggle}>
|
||||||
<DialogTrigger asChild>
|
<DialogTrigger asChild>
|
||||||
<Button
|
<Button
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
@@ -254,7 +256,6 @@ export function AddressDialog() {
|
|||||||
</Button>
|
</Button>
|
||||||
</DialogTrigger>
|
</DialogTrigger>
|
||||||
<DialogContent className="sm:max-w-[425px]">
|
<DialogContent className="sm:max-w-[425px]">
|
||||||
<form onSubmit={handleSubmit(onSubmit)} className="space-y-4">
|
|
||||||
<DialogHeader>
|
<DialogHeader>
|
||||||
<DialogTitle>Editar endereço</DialogTitle>
|
<DialogTitle>Editar endereço</DialogTitle>
|
||||||
<DialogDescription>
|
<DialogDescription>
|
||||||
@@ -262,62 +263,11 @@ export function AddressDialog() {
|
|||||||
</DialogDescription>
|
</DialogDescription>
|
||||||
</DialogHeader>
|
</DialogHeader>
|
||||||
|
|
||||||
|
<PostcodeForm onChange={reset} />
|
||||||
|
|
||||||
|
<form onSubmit={handleSubmit(onSubmit)} className="space-y-4">
|
||||||
<FieldGroup>
|
<FieldGroup>
|
||||||
<FieldSet>
|
<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
|
<Controller
|
||||||
control={control}
|
control={control}
|
||||||
name="address1"
|
name="address1"
|
||||||
@@ -431,6 +381,7 @@ export function AddressDialog() {
|
|||||||
<Button
|
<Button
|
||||||
variant="link"
|
variant="link"
|
||||||
type="button"
|
type="button"
|
||||||
|
tabIndex={-1}
|
||||||
className="text-black dark:text-white"
|
className="text-black dark:text-white"
|
||||||
>
|
>
|
||||||
Cancel
|
Cancel
|
||||||
@@ -444,3 +395,93 @@ export function AddressDialog() {
|
|||||||
</Dialog>
|
</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
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -1,4 +1,3 @@
|
|||||||
import json
|
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
from typing import NotRequired, TypedDict
|
from typing import NotRequired, TypedDict
|
||||||
|
|
||||||
@@ -135,8 +134,7 @@ def _generate_cert(
|
|||||||
# Send template URI and data to Paperforge API to generate a PDF
|
# Send template URI and data to Paperforge API to generate a PDF
|
||||||
r = requests.post(
|
r = requests.post(
|
||||||
PAPERFORGE_API,
|
PAPERFORGE_API,
|
||||||
data=json.dumps(
|
json={
|
||||||
{
|
|
||||||
'template_uri': cert['s3_uri'],
|
'template_uri': cert['s3_uri'],
|
||||||
'args': {
|
'args': {
|
||||||
'name': user['name'],
|
'name': user['name'],
|
||||||
@@ -151,8 +149,7 @@ def _generate_cert(
|
|||||||
else None,
|
else None,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
),
|
timeout=(1, 3),
|
||||||
timeout=6,
|
|
||||||
)
|
)
|
||||||
r.raise_for_status()
|
r.raise_for_status()
|
||||||
|
|
||||||
|
|||||||
@@ -369,7 +369,7 @@ Resources:
|
|||||||
Properties:
|
Properties:
|
||||||
Handler: events.issue_cert.lambda_handler
|
Handler: events.issue_cert.lambda_handler
|
||||||
Tracing: Active
|
Tracing: Active
|
||||||
Timeout: 12
|
# Timeout: 12
|
||||||
LoggingConfig:
|
LoggingConfig:
|
||||||
LogGroup: !Ref EventLog
|
LogGroup: !Ref EventLog
|
||||||
Policies:
|
Policies:
|
||||||
@@ -443,6 +443,10 @@ Resources:
|
|||||||
sk: ['0']
|
sk: ['0']
|
||||||
new_image:
|
new_image:
|
||||||
status: [COMPLETED]
|
status: [COMPLETED]
|
||||||
|
# Post-migration: uncomment the following line
|
||||||
|
# cert:
|
||||||
|
# expires_at:
|
||||||
|
# - exists: true
|
||||||
cert_expires_at:
|
cert_expires_at:
|
||||||
- exists: true
|
- exists: true
|
||||||
org_id:
|
org_id:
|
||||||
|
|||||||
Reference in New Issue
Block a user