Created
August 4, 2025 18:15
-
-
Save cbfranca/7087008e10cff4f4b5becaf2df056be4 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import { useEffect } from "react"; | |
| import { Controller, useFormContext, useWatch } from "react-hook-form"; | |
| import { PersonRequestDTO } from "~/application/dtos"; | |
| import { AccountType, MaritalStatus } from "~/domain/enums"; | |
| import { Input, Select } from "~/presentation/components"; | |
| import { useAddressFromCep, useAuth, useIBGELocations } from "~/presentation/hooks"; | |
| import { GroupProps } from "./types"; | |
| function Group({ className = '', title, children }: GroupProps) { | |
| return ( | |
| <div className={`flex flex-col gap-6 text-concrete-500 ${className}`}> | |
| <h5 className="text-lg leading-5 font-bold">{title}</h5> | |
| {children} | |
| </div> | |
| ); | |
| } | |
| export function Form() { | |
| const { isAuthenticated } = useAuth(); | |
| const { | |
| control, | |
| formState: { errors, isSubmitting }, | |
| watch, | |
| setValue, | |
| } = useFormContext<PersonRequestDTO>(); | |
| const { maritalStatus } = useWatch({ control }); | |
| useEffect(() => { | |
| console.log('maritalStatus', maritalStatus); | |
| }, [maritalStatus]); | |
| const { isLoading: isLoadingAddress, error: addressError, fetchAddress } = useAddressFromCep(); | |
| const { | |
| states, | |
| cities, | |
| isLoadingStates, | |
| isLoadingCities, | |
| statesError, | |
| citiesError, | |
| fetchCitiesByState, | |
| clearCities | |
| } = useIBGELocations(); | |
| const postalCodeValue = watch('postalCode'); | |
| const stateValue = watch('state'); | |
| useEffect(() => { | |
| const handleCepAutoFill = async () => { | |
| const cleanCep = postalCodeValue?.replace(/\D/g, '') || ''; | |
| if (cleanCep.length === 8) { | |
| const addressResult = await fetchAddress(cleanCep); | |
| console.log('addressResult', addressResult); | |
| if (addressResult) { | |
| setValue('street', addressResult.street, { shouldValidate: true }); | |
| setValue('neighborhood', addressResult.neighborhood, { shouldValidate: true }); | |
| setValue('city', addressResult.cityName, { shouldValidate: true }); | |
| setValue('state', addressResult.stateName, { shouldValidate: true }); | |
| if (addressResult.complement) { | |
| setValue('complement', addressResult.complement, { shouldValidate: true }); | |
| } | |
| const selectedState = states.find(s => s.value === addressResult.stateName); | |
| console.log('selectedState', selectedState); | |
| if (selectedState) { | |
| await fetchCitiesByState(selectedState.id); | |
| } | |
| } | |
| } | |
| }; | |
| if (postalCodeValue) { | |
| handleCepAutoFill(); | |
| } | |
| }, [postalCodeValue, fetchAddress, setValue, states, fetchCitiesByState]); | |
| useEffect(() => { | |
| if (stateValue) { | |
| const selectedState = states.find(s => s.value === stateValue); | |
| if (selectedState) { | |
| fetchCitiesByState(selectedState.id); | |
| } else { | |
| clearCities(); | |
| } | |
| } else { | |
| clearCities(); | |
| } | |
| }, [stateValue, states, fetchCitiesByState, clearCities]); | |
| const stateOptions = [ | |
| ...(statesError ? [] : states) | |
| ]; | |
| const cityOptions = [ | |
| ...(citiesError ? [] : cities) | |
| ]; | |
| const countryOptions = [ | |
| { label: 'Brasil', value: 'Brasil' }, | |
| ]; | |
| return ( | |
| <div className="flex flex-col gap-[34px]"> | |
| <div className="flex-1 max-w-[960px] mx-auto flex flex-col gap-10 p-14 bg-white shadow-[2px_2px_4px_0px_rgba(140,140,140,0.08),4px_4px_16px_1px_rgba(107,109,112,0.06),8px_8px_32px_0px_rgba(131,138,136,0.12)]"> | |
| <h3 className="text-[26px] font-bold leading-[30px]">Dados necessários</h3> | |
| <Group title="1. Dados Pessoais:"> | |
| <fieldset className="p-0! m-0 flex flex-col gap-[6px]"> | |
| <label className="text-base leading-lg font-semibold ">Informe seu nome completo.</label> | |
| <label className="text-xs leading-sm font-semibold">Utilize o nome como registrado em documentos oficiais.</label> | |
| <Controller | |
| name="name" | |
| control={control} | |
| render={({ field }) => ( | |
| <Input {...field} value={field.value || ''} error={errors.name?.message} isLocked={isAuthenticated && !!field.value} /> | |
| )} | |
| /> | |
| </fieldset> | |
| <div className="flex gap-6"> | |
| <fieldset className="p-0! flex-1 m-0 flex flex-col gap-[6px]"> | |
| <label className="text-base leading-lg font-semibold ">E-mail:</label> | |
| <Controller | |
| name="email" | |
| control={control} | |
| render={({ field }) => ( | |
| <Input {...field} value={field.value || ''} error={errors.email?.message} isLocked={isAuthenticated && !!field.value} /> | |
| )} | |
| /> | |
| </fieldset> | |
| <fieldset className="p-0! flex-1 m-0 flex flex-col gap-[6px]"> | |
| <label className="text-base leading-lg font-semibold ">Telefone celular:</label> | |
| <Controller | |
| name="phoneNumber" | |
| control={control} | |
| render={({ field }) => ( | |
| <Input | |
| {...field} | |
| value={field.value || ''} | |
| error={errors.phoneNumber?.message} placeholder="(00) 99999-9999" | |
| mask="(99) 99999-9999" | |
| /> | |
| )} | |
| /> | |
| </fieldset> | |
| </div> | |
| <fieldset className="p-0! m-0 flex flex-col gap-[6px]"> | |
| <label className="text-base leading-lg font-semibold ">Nome da mãe.</label> | |
| <label className="text-xs leading-sm font-semibold">Utilize o nome como registrado em documentos oficiais.</label> | |
| <Controller | |
| name="motherName" | |
| control={control} | |
| render={({ field }) => ( | |
| <Input {...field} value={field.value || ''} placeholder="Digite aqui..." error={errors.motherName?.message} /> | |
| )} | |
| /> | |
| </fieldset> | |
| <div className="flex gap-6"> | |
| <fieldset className="p-0! m-0 flex-1 flex flex-col gap-[6px]"> | |
| <label className="text-base leading-lg font-semibold ">Data de nascimento</label> | |
| <label className="text-xs leading-sm font-semibold">Precisamos validar sua idade.</label> | |
| <Controller | |
| name="birthDate" | |
| control={control} | |
| render={({ field }) => ( | |
| <Input {...field} value={field.value || ''} placeholder="Digite aqui..." error={errors.birthDate?.message} mask="99/99/9999" /> | |
| )} | |
| /> | |
| </fieldset> | |
| <fieldset className="p-0! m-0 flex-1 flex flex-col gap-[6px]"> | |
| <label className="text-base leading-lg font-semibold ">Nacionalidade</label> | |
| <label className="text-xs leading-sm font-semibold">Precisamos dessa informação.</label> | |
| <Controller | |
| name="nationality" | |
| control={control} | |
| render={({ field }) => ( | |
| <Input {...field} value={field.value || ''} placeholder="Digite aqui..." error={errors.nationality?.message} /> | |
| )} | |
| /> | |
| </fieldset> | |
| <fieldset className="p-0! m-0 flex-1 flex flex-col gap-[6px]"> | |
| <label className="text-base leading-lg font-semibold ">Pessoa politicamente exposta?</label> | |
| <label className="text-xs leading-sm font-semibold">Precisamos validar seu perfil.</label> | |
| <Controller | |
| name="politicallyExposed" | |
| control={control} | |
| render={({ field }) => ( | |
| <Select {...field} value={field.value || ''} options={[ | |
| { label: 'Não', value: false }, | |
| { label: 'Sim', value: true }, | |
| ]} error={errors.politicallyExposed?.message} /> | |
| )} | |
| /> | |
| </fieldset> | |
| </div> | |
| <div className="flex gap-6"> | |
| <fieldset className="p-0! m-0 flex flex-col gap-[6px]"> | |
| <label className="text-base leading-lg font-semibold ">Estado civil</label> | |
| <label className="text-xs leading-sm font-semibold">Selecione seu estado civil atual.</label> | |
| <Controller | |
| name="maritalStatus" | |
| control={control} | |
| render={({ field }) => ( | |
| <Select {...field} value={field.value || ''} options={[ | |
| { label: 'Selecione', value: '' }, | |
| { label: 'Solteiro(a)', value: 'Single' }, | |
| { label: 'Casado(a)', value: 'Married' }, | |
| { label: 'Divorciado(a)', value: 'Divorced' }, | |
| { label: 'Viúvo(a)', value: 'Widowed' }, | |
| { label: 'União estável', value: 'DomesticPartnership' }, | |
| ]} error={errors.maritalStatus?.message} /> | |
| )} | |
| /> | |
| </fieldset> | |
| <fieldset className="p-0! m-0 flex-1 flex flex-col gap-[6px]"> | |
| <label className="text-base leading-lg font-semibold ">Quantas pessoas dependem financeiramente de você?</label> | |
| <label className="text-xs leading-sm font-semibold">Precisamos validar seu perfil.</label> | |
| <Controller | |
| name="numberOfDependents" | |
| control={control} | |
| render={({ field }) => ( | |
| <Input {...field} value={field.value || ''} placeholder="Digite aqui..." error={errors.numberOfDependents?.message} /> | |
| )} | |
| /> | |
| </fieldset> | |
| </div> | |
| <div className="flex gap-6"> | |
| <fieldset className="p-0! flex-1 m-0 flex flex-col gap-[6px]"> | |
| <label className="text-base leading-lg font-semibold ">CPF</label> | |
| <label className="text-xs leading-sm font-semibold">Digite apenas os números do seu CPF.</label> | |
| <Controller | |
| name="identification" | |
| control={control} | |
| render={({ field }) => ( | |
| <Input {...field} value={field.value || ''} placeholder="Digite aqui..." error={errors.identification?.message} isLocked={isAuthenticated && !!field.value} /> | |
| )} | |
| /> | |
| </fieldset> | |
| <fieldset className="p-0! flex-1 m-0 flex flex-col gap-[6px]"> | |
| <label className="text-base leading-lg font-semibold ">RG (opcional)</label> | |
| <label className="text-xs leading-sm font-semibold">Digite apenas os números do seu RG.</label> | |
| <Controller | |
| name="rg" | |
| control={control} | |
| render={({ field }) => ( | |
| <Input {...field} value={field.value || ''} placeholder="Digite aqui..." error={errors.rg?.message} /> | |
| )} | |
| /> | |
| </fieldset> | |
| </div> | |
| </Group> | |
| <Group title="3. Dados Residenciais:"> | |
| <div className="flex gap-6"> | |
| <fieldset className="p-0! min-w-[267px] m-0 flex flex-col gap-[6px]"> | |
| <label className="text-base leading-lg font-semibold ">CEP</label> | |
| <label className="text-xs leading-sm font-semibold"> | |
| Digite o CEP do seu endereço. | |
| {isLoadingAddress && " (Buscando...)"} | |
| </label> | |
| <Controller | |
| name="postalCode" | |
| control={control} | |
| render={({ field }) => ( | |
| <Input | |
| {...field} | |
| value={field.value || ''} | |
| placeholder="Digite aqui..." | |
| error={errors.postalCode?.message || (addressError || undefined)} | |
| maxLength={9} | |
| /> | |
| )} | |
| /> | |
| </fieldset> | |
| <fieldset className="p-0! flex-1 m-0 flex flex-col gap-[6px]"> | |
| <label className="text-base leading-lg font-semibold ">Rua</label> | |
| <label className="text-xs leading-sm font-semibold">Informe o nome da rua.</label> | |
| <Controller | |
| name="street" | |
| control={control} | |
| render={({ field }) => ( | |
| <Input | |
| {...field} | |
| value={field.value || ''} | |
| placeholder="Digite aqui..." | |
| error={errors.street?.message} | |
| readOnly={isLoadingAddress} | |
| /> | |
| )} | |
| /> | |
| </fieldset> | |
| </div> | |
| <div className="flex gap-6"> | |
| <fieldset className="p-0! flex-1 m-0 flex flex-col gap-[6px]"> | |
| <label className="text-base leading-lg font-semibold ">Complemento</label> | |
| <label className="text-xs leading-sm font-semibold">Bloco, apartamento ou outra informação (opcional).</label> | |
| <Controller | |
| name="complement" | |
| control={control} | |
| render={({ field }) => ( | |
| <Input {...field} value={field.value || ''} placeholder="Digite aqui..." error={errors.complement?.message} /> | |
| )} | |
| /> | |
| </fieldset> | |
| <fieldset className="p-0! min-w-[267px] m-0 flex flex-col gap-[6px]"> | |
| <label className="text-base leading-lg font-semibold ">Número</label> | |
| <label className="text-xs leading-sm font-semibold">Adicione o número da residência.</label> | |
| <Controller | |
| name="number" | |
| control={control} | |
| render={({ field }) => ( | |
| <Input {...field} value={field.value || ''} placeholder="Digite aqui..." error={errors.number?.message} /> | |
| )} | |
| /> | |
| </fieldset> | |
| </div> | |
| <div className="flex flex-wrap gap-6"> | |
| <fieldset className="p-0! flex-1 m-0 flex flex-col gap-[6px]"> | |
| <label className="text-base leading-lg font-semibold ">Bairro</label> | |
| <label className="text-xs leading-sm font-semibold">Informe o bairro.</label> | |
| <Controller | |
| name="neighborhood" | |
| control={control} | |
| render={({ field }) => ( | |
| <Input {...field} value={field.value || ''} placeholder="Digite aqui..." error={errors.neighborhood?.message} /> | |
| )} | |
| /> | |
| </fieldset> | |
| <fieldset className="p-0! flex-1 m-0 flex flex-col gap-[6px]"> | |
| <label className="text-base leading-lg font-semibold ">Cidade</label> | |
| <label className="text-xs leading-sm font-semibold"> | |
| Selecione a cidade. | |
| {isLoadingCities && " (Carregando...)"} | |
| </label> | |
| <Controller | |
| name="city" | |
| control={control} | |
| render={({ field }) => ( | |
| <Select | |
| {...field} | |
| value={field.value || ''} | |
| options={cityOptions} | |
| error={errors.city?.message || (citiesError || undefined)} | |
| disabled={isLoadingCities || !stateValue} | |
| /> | |
| )} | |
| /> | |
| </fieldset> | |
| </div> | |
| <div className="flex flex-wrap gap-6"> | |
| <fieldset className="p-0! flex-1 m-0 flex flex-col gap-[6px]"> | |
| <label className="text-base leading-lg font-semibold ">Estado</label> | |
| <label className="text-xs leading-sm font-semibold"> | |
| Selecione o estado. | |
| {isLoadingStates && " (Carregando...)"} | |
| </label> | |
| <Controller | |
| name="state" | |
| control={control} | |
| render={({ field }) => ( | |
| <Select | |
| {...field} | |
| value={field.value || ''} | |
| options={stateOptions} | |
| error={errors.state?.message || (statesError || undefined)} | |
| disabled={isLoadingStates} | |
| /> | |
| )} | |
| /> | |
| </fieldset> | |
| <fieldset className="p-0! flex-1 m-0 flex flex-col gap-[6px]"> | |
| <label className="text-base leading-lg font-semibold ">País</label> | |
| <label className="text-xs leading-sm font-semibold">Selecione o país.</label> | |
| <Controller | |
| name="country" | |
| control={control} | |
| render={({ field }) => ( | |
| <Select | |
| {...field} | |
| value={field.value || ''} | |
| options={countryOptions} | |
| error={errors.country?.message} | |
| /> | |
| )} | |
| /> | |
| </fieldset> | |
| </div> | |
| </Group> | |
| <Group title="4. Dados bancários:"> | |
| <div className="flex gap-6"> | |
| <fieldset className="p-0! flex-1 m-0 flex flex-col gap-[6px]"> | |
| <label className="text-base leading-lg font-semibold ">Código do banco:</label> | |
| <Controller | |
| name="bankCode" | |
| control={control} | |
| render={({ field }) => ( | |
| <Input {...field} value={field.value || ''} placeholder="Digite aqui..." error={errors.bankCode?.message} /> | |
| )} | |
| /> | |
| </fieldset> | |
| <fieldset className="p-0! flex-1 m-0 flex flex-col gap-[6px]"> | |
| <label className="text-base leading-lg font-semibold ">Agência:</label> | |
| <Controller | |
| name="agencyNumber" | |
| control={control} | |
| render={({ field }) => ( | |
| <Input {...field} value={field.value || ''} placeholder="Digite aqui..." error={errors.agencyNumber?.message} /> | |
| )} | |
| /> | |
| </fieldset> | |
| <fieldset className="p-0! flex-1 m-0 flex flex-col gap-[6px]"> | |
| <label className="text-base leading-lg font-semibold ">Conta bancária c/ dígito:</label> | |
| <Controller | |
| name="accountNumber" | |
| control={control} | |
| render={({ field }) => ( | |
| <Input {...field} value={field.value || ''} placeholder="Digite aqui..." error={errors.accountNumber?.message} /> | |
| )} | |
| /> | |
| </fieldset> | |
| <fieldset className="p-0! flex-1 m-0 flex flex-col gap-[6px]"> | |
| <label className="text-base leading-lg font-semibold ">Tipo de conta:</label> | |
| <Controller | |
| name="accountType" | |
| control={control} | |
| render={({ field }) => ( | |
| <Select {...field} value={field.value || ''} options={[ | |
| { label: 'Selecione', value: '' }, | |
| { label: 'Conta corrente', value: AccountType.CHECKING }, | |
| { label: 'Conta poupança', value: AccountType.SAVINGS }, | |
| ]} error={errors.accountType?.message} /> | |
| )} | |
| /> | |
| </fieldset> | |
| </div> | |
| </Group> | |
| <Group title="5. Dados de Renda:"> | |
| <fieldset className="p-0! flex-1 m-0 flex flex-col gap-[6px]"> | |
| <label className="text-base leading-lg font-semibold ">Valor da renda mensal.</label> | |
| <label className="text-xs leading-sm font-semibold">Este dado é necessário para calcular as melhores condições de pagamento para você.</label> | |
| <Controller | |
| name="monthlyIncome" | |
| control={control} | |
| render={({ field }) => ( | |
| <Input {...field} value={field.value || ''} placeholder="Digite aqui..." mask="currency" error={errors.monthlyIncome?.message} /> | |
| )} | |
| /> | |
| </fieldset> | |
| </Group> | |
| <Group title="6. Dados de Emprego:"> | |
| <div className="flex items-end gap-6"> | |
| <fieldset className="p-0! flex-1 m-0 flex flex-col gap-[6px]"> | |
| <label className="text-base leading-lg font-semibold ">Empregador atual?</label> | |
| <label className="text-xs leading-sm font-semibold">Inclua o nome e o segmento da empresa.</label> | |
| <Controller | |
| name="companyName" | |
| control={control} | |
| render={({ field }) => ( | |
| <Input {...field} value={field.value || ''} placeholder="Nome da empresa" error={errors.companyName?.message} /> | |
| )} | |
| /> | |
| </fieldset> | |
| <fieldset className="p-0! min-w-[267px] m-0 flex flex-col gap-[6px]"> | |
| <Controller | |
| name="industry" | |
| control={control} | |
| render={({ field }) => ( | |
| <Input {...field} value={field.value || ''} placeholder="Segmento da empresa" error={errors.industry?.message} /> | |
| )} | |
| /> | |
| </fieldset> | |
| </div> | |
| <fieldset className="p-0! flex-1 m-0 flex flex-col gap-[6px]"> | |
| <label className="text-base leading-lg font-semibold ">Há quanto tempo trabalha nesse emprego?</label> | |
| <label className="text-xs leading-sm font-semibold">Informe em meses para análise de estabilidade.</label> | |
| <Controller | |
| name="serviceTimeInMonths" | |
| control={control} | |
| render={({ field }) => ( | |
| <Input {...field} value={field.value?.toString() || ''} placeholder="Digite aqui..." error={errors.serviceTimeInMonths?.message} /> | |
| )} | |
| /> | |
| </fieldset> | |
| </Group> | |
| <Group title="7. Patrimônio" className="gap-4!"> | |
| <div className="flex items-end gap-6"> | |
| <fieldset className="p-0! flex-1 m-0 flex flex-col gap-[6px]"> | |
| <label className="text-base leading-lg font-semibold ">Liste seus bens.</label> | |
| <label className="text-xs leading-sm font-semibold">Inclua imóveis, veículos e investimentos, com valores aproximados.</label> | |
| <Controller | |
| name="assets.0.description" | |
| control={control} | |
| render={({ field }) => ( | |
| <Input {...field} value={field.value || ''} placeholder="Digite o bem" error={errors.assets?.[0]?.description?.message} /> | |
| )} | |
| /> | |
| </fieldset> | |
| <fieldset className="p-0! min-w-[256px] m-0 flex flex-col gap-[6px]"> | |
| <Controller | |
| name="assets.0.value" | |
| control={control} | |
| render={({ field }) => ( | |
| <Input {...field} value={field.value?.toString() || ''} placeholder="Digite o valor" error={errors.assets?.[0]?.value?.message} mask="currency" /> | |
| )} | |
| /> | |
| </fieldset> | |
| </div> | |
| <div className="flex items-end gap-6"> | |
| <fieldset className="p-0! flex-1 m-0 flex flex-col gap-[6px]"> | |
| <Controller | |
| name="assets.1.description" | |
| control={control} | |
| render={({ field }) => ( | |
| <Input {...field} value={field.value || ''} placeholder="Digite o bem" error={errors.assets?.[1]?.description?.message} /> | |
| )} | |
| /> | |
| </fieldset> | |
| <fieldset className="p-0! min-w-[256px] m-0 flex flex-col gap-[6px]"> | |
| <Controller | |
| name="assets.1.value" | |
| control={control} | |
| render={({ field }) => ( | |
| <Input {...field} value={field.value?.toString() || ''} placeholder="Digite o valor" error={errors.assets?.[1]?.value?.message} mask="currency" /> | |
| )} | |
| /> | |
| </fieldset> | |
| </div> | |
| <div className="flex items-end gap-6"> | |
| <fieldset className="p-0! flex-1 m-0 flex flex-col gap-[6px]"> | |
| <Controller | |
| name="assets.2.description" | |
| control={control} | |
| render={({ field }) => ( | |
| <Input {...field} value={field.value || ''} placeholder="Digite o bem" error={errors.assets?.[2]?.description?.message} /> | |
| )} | |
| /> | |
| </fieldset> | |
| <fieldset className="p-0! min-w-[256px] m-0 flex flex-col gap-[6px]"> | |
| <Controller | |
| name="assets.2.value" | |
| control={control} | |
| render={({ field }) => ( | |
| <Input {...field} value={field.value?.toString() || ''} placeholder="Digite o valor" error={errors.assets?.[2]?.value?.message} mask="currency" /> | |
| )} | |
| /> | |
| </fieldset> | |
| </div> | |
| <div className="flex items-end gap-6"> | |
| <fieldset className="p-0! flex-1 m-0 flex flex-col gap-[6px]"> | |
| <Controller | |
| name="assets.3.description" | |
| control={control} | |
| render={({ field }) => ( | |
| <Input {...field} value={field.value || ''} placeholder="Digite o bem" error={errors.assets?.[3]?.description?.message} /> | |
| )} | |
| /> | |
| </fieldset> | |
| <fieldset className="p-0! min-w-[256px] m-0 flex flex-col gap-[6px]"> | |
| <Controller | |
| name="assets.3.value" | |
| control={control} | |
| render={({ field }) => ( | |
| <Input {...field} value={field.value?.toString() || ''} placeholder="Digite o valor" error={errors.assets?.[3]?.value?.message} mask="currency" /> | |
| )} | |
| /> | |
| </fieldset> | |
| </div> | |
| <div className="flex items-end gap-6"> | |
| <fieldset className="p-0! flex-1 m-0 flex flex-col gap-[6px]"> | |
| <label className="text-base leading-lg font-semibold ">Quais são suas dívidas atuais?</label> | |
| <label className="text-xs leading-sm font-semibold">Financiamentos, empréstimos ou dívidas de cartão de crédito.</label> | |
| <Controller | |
| name="debts.0.description" | |
| control={control} | |
| render={({ field }) => ( | |
| <Input {...field} value={field.value || ''} placeholder="Digite o bem" error={errors.debts?.[0]?.description?.message} /> | |
| )} | |
| /> | |
| </fieldset> | |
| <fieldset className="p-0! min-w-[256px] m-0 flex flex-col gap-[6px]"> | |
| <Controller | |
| name="debts.0.value" | |
| control={control} | |
| render={({ field }) => ( | |
| <Input {...field} value={field.value?.toString() || ''} placeholder="Digite o valor" error={errors.debts?.[0]?.value?.message} /> | |
| )} | |
| /> | |
| </fieldset> | |
| </div> | |
| </Group> | |
| </div> | |
| {maritalStatus === MaritalStatus.MARRIED && ( | |
| <div className="flex-1 max-w-[960px] mx-auto flex flex-col gap-10 p-14 bg-white shadow-[2px_2px_4px_0px_rgba(140,140,140,0.08),4px_4px_16px_1px_rgba(107,109,112,0.06),8px_8px_32px_0px_rgba(131,138,136,0.12)]"> | |
| <h3 className="text-[26px] font-bold leading-[30px]">Dados complementares</h3> | |
| <Group title="1. Dados do cônjugue:"> | |
| <fieldset className="p-0! m-0 flex flex-col gap-[6px]"> | |
| <label className="text-base leading-lg font-semibold ">Nome completo do cônjuge.</label> | |
| <label className="text-xs leading-sm font-semibold">Utilize o nome como registrado em documentos oficiais.</label> | |
| <Controller | |
| name="spouse.name" | |
| control={control} | |
| render={({ field }) => ( | |
| <Input {...field} value={field.value || ''} placeholder="Digite aqui..." error={errors.spouse?.name?.message} /> | |
| )} | |
| /> | |
| </fieldset> | |
| <div className="flex gap-6"> | |
| <fieldset className="p-0! flex-1 m-0 flex flex-col gap-[6px]"> | |
| <label className="text-base leading-lg font-semibold ">E-mail:</label> | |
| <Controller | |
| name="spouse.email" | |
| control={control} | |
| render={({ field }) => ( | |
| <Input {...field} value={field.value || ''} error={errors.spouse?.email?.message} /> | |
| )} | |
| /> | |
| </fieldset> | |
| <fieldset className="p-0! flex-1 m-0 flex flex-col gap-[6px]"> | |
| <label className="text-base leading-lg font-semibold ">Telefone celular:</label> | |
| <Controller | |
| name="spouse.phoneNumber" | |
| control={control} | |
| render={({ field }) => ( | |
| <Input {...field} value={field.value || ''} error={errors.spouse?.phoneNumber?.message} /> | |
| )} | |
| /> | |
| </fieldset> | |
| </div> | |
| <div className="flex gap-6"> | |
| <fieldset className="p-0! flex-1 m-0 flex flex-col gap-[6px]"> | |
| <label className="text-base leading-lg font-semibold ">Data de nascimento:</label> | |
| <label className="text-xs leading-sm font-semibold">Precisamos validar sua idade.</label> | |
| <Controller | |
| name="spouse.birthDate" | |
| control={control} | |
| render={({ field }) => ( | |
| <Input {...field} value={field.value || ''} placeholder="Digite aqui..." error={errors.spouse?.birthDate?.message} mask="99/99/9999" /> | |
| )} | |
| /> | |
| </fieldset> | |
| <fieldset className="p-0! flex-1 m-0 flex flex-col gap-[6px]"> | |
| <label className="text-base leading-lg font-semibold ">Nacionalidade:</label> | |
| <label className="text-xs leading-sm font-semibold">Precisamos dessa informação.</label> | |
| <Controller | |
| name="spouse.nationality" | |
| control={control} | |
| render={({ field }) => ( | |
| <Input {...field} value={field.value || ''} placeholder="Digite aqui..." error={errors.spouse?.nationality?.message} /> | |
| )} | |
| /> | |
| </fieldset> | |
| <fieldset className="p-0! flex-1 m-0 flex flex-col gap-[6px]"> | |
| <label className="text-base leading-lg font-semibold ">Pessoa politicamente exposta?:</label> | |
| <label className="text-xs leading-sm font-semibold">Precisamos validar seu perfil.</label> | |
| <Controller | |
| name="spouse.politicallyExposed" | |
| control={control} | |
| render={({ field }) => ( | |
| <Select | |
| {...field} | |
| value={field.value ?? undefined} | |
| options={[ | |
| { label: 'Sim', value: true }, | |
| { label: 'Não', value: false }, | |
| ]} | |
| error={errors.spouse?.politicallyExposed?.message} | |
| /> | |
| )} | |
| /> | |
| </fieldset> | |
| </div> | |
| </Group> | |
| <Group title="2. Dados de Identificação do cônjugue:"> | |
| <div className="flex gap-6"> | |
| <fieldset className="p-0! flex-1 m-0 flex flex-col gap-[6px]"> | |
| <label className="text-base leading-lg font-semibold ">Informe o CPF:</label> | |
| <label className="text-xs leading-sm font-semibold">Utilizaremos para análise de crédito e validação dos dados.</label> | |
| <Controller | |
| name="spouse.identification" | |
| control={control} | |
| render={({ field }) => ( | |
| <Input {...field} placeholder="999.999.999-99" error={errors.spouse?.identification?.message} mask="999.999.999-99" /> | |
| )} | |
| /> | |
| </fieldset> | |
| <fieldset className="p-0! flex-1 m-0 flex flex-col gap-[6px]"> | |
| <label className="text-base leading-lg font-semibold ">Documento de Identificação:</label> | |
| <label className="text-xs leading-sm font-semibold">Número do RG, CNH ou outro documento oficial com foto.</label> | |
| <Controller | |
| name="spouse.rg" | |
| control={control} | |
| render={({ field }) => ( | |
| <Input {...field} value={field.value || ''} placeholder="Digite aqui..." error={errors.spouse?.rg?.message} /> | |
| )} | |
| /> | |
| </fieldset> | |
| </div> | |
| </Group> | |
| <Group title="3. Dados de Renda do cônjuge:"> | |
| <fieldset className="p-0! flex-1 m-0 flex flex-col gap-[6px]"> | |
| <label className="text-base leading-lg font-semibold ">Valor da renda mensal.</label> | |
| <label className="text-xs leading-sm font-semibold">Este dado é necessário para calcular as melhores condições de pagamento para você.</label> | |
| <Controller | |
| name="spouse.monthlyIncome" | |
| control={control} | |
| render={({ field }) => ( | |
| <Input {...field} value={field.value?.toString() || ''} placeholder="Digite aqui..." mask="currency" error={errors.spouse?.monthlyIncome?.message} /> | |
| )} | |
| /> | |
| </fieldset> | |
| </Group> | |
| <Group title="4. Dados de Emprego do cônjuge:"> | |
| <div className="flex items-end gap-6"> | |
| <fieldset className="p-0! flex-1 m-0 flex flex-col gap-[6px]"> | |
| <label className="text-base leading-lg font-semibold ">Empregador atual?</label> | |
| <label className="text-xs leading-sm font-semibold">Inclua o nome e o segmento da empresa.</label> | |
| <Controller | |
| name="spouse.companyName" | |
| control={control} | |
| render={({ field }) => ( | |
| <Input {...field} value={field.value || ''} placeholder="Nome da empresa" error={errors.spouse?.companyName?.message} /> | |
| )} | |
| /> | |
| </fieldset> | |
| <fieldset className="p-0! min-w-[267px] m-0 flex flex-col gap-[6px]"> | |
| <Controller | |
| name="spouse.industry" | |
| control={control} | |
| render={({ field }) => ( | |
| <Input {...field} value={field.value || ''} placeholder="Segmento da empresa" error={errors.spouse?.industry?.message} /> | |
| )} | |
| /> | |
| </fieldset> | |
| </div> | |
| <fieldset className="p-0! flex-1 m-0 flex flex-col gap-[6px]"> | |
| <label className="text-base leading-lg font-semibold ">Há quanto tempo trabalha nesse emprego?</label> | |
| <label className="text-xs leading-sm font-semibold">Informe em meses para análise de estabilidade.</label> | |
| <Controller | |
| name="spouse.serviceTimeInMonths" | |
| control={control} | |
| render={({ field }) => ( | |
| <Input {...field} value={field.value?.toString() || ''} placeholder="Digite aqui..." error={errors.spouse?.serviceTimeInMonths?.message} /> | |
| )} | |
| /> | |
| </fieldset> | |
| </Group> | |
| <div className="flex flex-col gap-2 border-t border-concrete-500 pt-6 text-xs text-concrete-500"> | |
| <span className="font-bold leading-base">Compromisso de Proteção de Dados Housemap</span> | |
| <p> | |
| Nós valorizamos sua privacidade e a proteção dos seus dados pessoais. Assim, todas as informações fornecidas serão tratadas pela Housemap conforme estabelecido em nossa Política de Privacidade. | |
| <br /> | |
| A Housemap poderá entrar em contato com você por meio de nossos serviços de atendimento ao cliente, empresas associadas e representantes autorizados, por correio, telefone, WhatsApp, SMS ou outros meios digitais, para oferecer informações sobre nossos produtos, serviços ou eventos relacionados ao nosso empreendimento. Usaremos seus dados pessoais apenas na medida necessária para esses propósitos e sempre dentro dos limites da lei, garantindo que o tratamento dos dados seja adequado, razoável e proporcional. | |
| Nos comprometemos a seguir rigorosamente todas as leis aplicáveis de proteção de dados e privacidade, incluindo, mas não se limitando, ao Marco Civil da Internet e à LGPD (Lei Geral de Proteção de Dados Pessoais). | |
| </p> | |
| </div> | |
| </div> | |
| )} | |
| <div className="flex justify-end max-w-[960px] mx-auto"> | |
| <button | |
| type="submit" | |
| disabled={isSubmitting} | |
| className="px-8 py-4 bg-primary-500 text-white font-semibold rounded-lg disabled:opacity-50 disabled:cursor-not-allowed" | |
| > | |
| Enviar | |
| </button> | |
| </div> | |
| </div> | |
| ); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment