[MVPTN-88] fix(CRUD): Ajustes diversos no CRUD de Imóveis e Unidades dos Imóveis
This commit is contained in:
parent
ff28fe1f58
commit
cbaf19af0b
12 changed files with 294 additions and 272 deletions
|
|
@ -67,9 +67,7 @@ export default function TImovelColumns(
|
|||
);
|
||||
},
|
||||
sortingFn: (a, b) =>
|
||||
(a.original.cartorio?.toLowerCase() || "").localeCompare(
|
||||
b.original.cartorio?.toLowerCase() || ""
|
||||
),
|
||||
Number(a.original.numero || 0) - Number(b.original.numero || 0),
|
||||
},
|
||||
|
||||
// CEP
|
||||
|
|
|
|||
|
|
@ -27,7 +27,6 @@ import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
|
|||
import { CheckIcon, ChevronsUpDownIcon, HouseIcon, IdCardIcon } from 'lucide-react';
|
||||
import { Select, SelectContent, SelectItem, SelectTrigger } from '@/components/ui/select';
|
||||
import { ImovelTipoRegistro } from '@/shared/enums/ImovelTipoRegistro';
|
||||
import { ImovelTipoClasseEnum } from '@/shared/enums/ImovelTipoClasseEnum';
|
||||
import { ResetFormIfData } from '@/shared/actions/form/ResetFormIfData';
|
||||
import { useGTBBairroReadHook } from '../../../../app/(protected)/(cadastros)/cadastros/_hooks/g_tb_bairro/useGTBBairroReadHook';
|
||||
import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover';
|
||||
|
|
@ -45,7 +44,7 @@ export default function TImovelForm({ isOpen, data, onClose, onSave, buttonIsLoa
|
|||
const { gTBBairro, fetchGTBBairro } = useGTBBairroReadHook();
|
||||
|
||||
// Inicializa o react-hook-form com schema zod
|
||||
const form = useTImovelFormHook();
|
||||
const form = useTImovelFormHook({});
|
||||
|
||||
// Atualiza o formulário quando recebe dados para edição
|
||||
useEffect(() => {
|
||||
|
|
@ -66,6 +65,10 @@ export default function TImovelForm({ isOpen, data, onClose, onSave, buttonIsLoa
|
|||
|
||||
}, [data, form]);
|
||||
|
||||
function onError(error: any) {
|
||||
console.log(error);
|
||||
}
|
||||
|
||||
return (
|
||||
<Dialog
|
||||
open={isOpen}
|
||||
|
|
@ -76,28 +79,28 @@ export default function TImovelForm({ isOpen, data, onClose, onSave, buttonIsLoa
|
|||
<DialogContent className="w-full max-w-full p-6 sm:max-w-3xl md:max-w-4xl lg:max-w-5xl">
|
||||
<DialogHeader>
|
||||
<DialogTitle>
|
||||
Imóvel Urbano
|
||||
{tipoClasse === 1 ? 'Imóvel Urbano' : 'Imóvel Rural'}
|
||||
</DialogTitle>
|
||||
<DialogDescription>
|
||||
Cadastro de imóvel urbano
|
||||
{tipoClasse === 1 ? 'Cadastro de imóvel urbano' : 'Cadastro de imóvel rural'}
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
<Form {...form}>
|
||||
{/* Tabs */}
|
||||
<Tabs defaultValue="dadosDoImovel" className="space-y-4">
|
||||
<TabsList className="flex w-full">
|
||||
<TabsTrigger className="flex-1 text-center cursor-pointer" value="dadosDoImovel">
|
||||
<HouseIcon className="me-1 inline" />
|
||||
Dados do Imóvel
|
||||
</TabsTrigger>
|
||||
<TabsTrigger className="flex-1 text-center cursor-pointer" value="unidades">
|
||||
<IdCardIcon className="inline" />
|
||||
Unidades
|
||||
</TabsTrigger>
|
||||
</TabsList>
|
||||
{/* Dados do Imóvel */}
|
||||
<TabsContent value="dadosDoImovel" className="space-y-4">
|
||||
<form onSubmit={form.handleSubmit(onSave)} className="space-y-6">
|
||||
{/* Tabs */}
|
||||
<Tabs defaultValue="dadosDoImovel" className="space-y-4">
|
||||
<TabsList className="flex w-full">
|
||||
<TabsTrigger className="flex-1 text-center cursor-pointer" value="dadosDoImovel">
|
||||
<HouseIcon className="me-1 inline" />
|
||||
Dados do Imóvel
|
||||
</TabsTrigger>
|
||||
<TabsTrigger className="flex-1 text-center cursor-pointer" value="unidades">
|
||||
<IdCardIcon className="inline" />
|
||||
Unidades
|
||||
</TabsTrigger>
|
||||
</TabsList>
|
||||
{/* Dados do Imóvel */}
|
||||
<TabsContent value="dadosDoImovel" className="space-y-4">
|
||||
<Form {...form}>
|
||||
<form onSubmit={form.handleSubmit(onSave, onError)} className="space-y-6">
|
||||
<div className="grid w-full grid-cols-12 gap-4">
|
||||
{/* UF */}
|
||||
<div className="col-span-12 sm:col-span-6 md:col-span-2">
|
||||
|
|
@ -222,7 +225,7 @@ export default function TImovelForm({ isOpen, data, onClose, onSave, buttonIsLoa
|
|||
<FormItem>
|
||||
<FormLabel>Cartório</FormLabel>
|
||||
<FormControl>
|
||||
<Input {...field} type='number' placeholder="Digite o cartório" />
|
||||
<Input {...field} type='number' placeholder="Digite o cartório" onChange={e => field.onChange(parseNumberInput(e))} />
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
|
|
@ -262,7 +265,7 @@ export default function TImovelForm({ isOpen, data, onClose, onSave, buttonIsLoa
|
|||
/>
|
||||
</div>
|
||||
{/* Tipo Registro */}
|
||||
<div className="col-span-12 sm:col-span-6 md:col-span-3">
|
||||
<div className="col-span-12 sm:col-span-6 md:col-span-4">
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="tipo_registro"
|
||||
|
|
@ -291,7 +294,7 @@ export default function TImovelForm({ isOpen, data, onClose, onSave, buttonIsLoa
|
|||
/>
|
||||
</div>
|
||||
{/* Número */}
|
||||
<div className="col-span-12 sm:col-span-6 md:col-span-3">
|
||||
<div className="col-span-12 sm:col-span-6 md:col-span-4">
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="numero"
|
||||
|
|
@ -307,7 +310,7 @@ export default function TImovelForm({ isOpen, data, onClose, onSave, buttonIsLoa
|
|||
/>
|
||||
</div>
|
||||
{/* Número Letra */}
|
||||
<div className="col-span-12 sm:col-span-6 md:col-span-3">
|
||||
<div className="col-span-12 sm:col-span-6 md:col-span-4">
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="numero_letra"
|
||||
|
|
@ -322,35 +325,6 @@ export default function TImovelForm({ isOpen, data, onClose, onSave, buttonIsLoa
|
|||
)}
|
||||
/>
|
||||
</div>
|
||||
{/* Tipo Registro */}
|
||||
<div className="col-span-12 sm:col-span-6 md:col-span-3">
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="tipo_classe"
|
||||
render={({ field }) => (
|
||||
<FormItem className="w-full">
|
||||
<FormLabel>Tipo Classe</FormLabel>
|
||||
<FormControl>
|
||||
<Select value={field.value} onValueChange={field.onChange}>
|
||||
<SelectTrigger className="w-full">
|
||||
{field.value
|
||||
? ImovelTipoClasseEnum[Number(field.value) as keyof typeof ImovelTipoClasseEnum]
|
||||
: "Selecione"}
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{Object.entries(ImovelTipoClasseEnum).map(([key, label]) => (
|
||||
<SelectItem key={key} value={key} className="cursor-pointer">
|
||||
{label}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
{/* Rodapé do Dialog */}
|
||||
<DialogFooter className="mt-4 flex flex-col sm:flex-row gap-2 justify-end">
|
||||
|
|
@ -366,19 +340,17 @@ export default function TImovelForm({ isOpen, data, onClose, onSave, buttonIsLoa
|
|||
loading={buttonIsLoading}
|
||||
/>
|
||||
</DialogFooter>
|
||||
<input type="hidden" {...form.register("imovel_id")} />
|
||||
</form>
|
||||
</TabsContent>
|
||||
{/* Unidades */}
|
||||
<TabsContent value="unidades" className="space-y-4">
|
||||
{/* Conteúdo das unidades */}
|
||||
{tipoClasse === 1 ? <TImovelUnidadeUrbanoPage imovel_id={data?.imovel_id} /> : null}
|
||||
{/* Conteúdo das unidades */}
|
||||
{tipoClasse === 3 ? <TImovelUnidadeRuralIndex imovel_id={data?.imovel_id} /> : null}
|
||||
</TabsContent>
|
||||
</Tabs>
|
||||
{/* Campo oculto */}
|
||||
</Form>
|
||||
</Form>
|
||||
</TabsContent>
|
||||
{/* Unidades */}
|
||||
<TabsContent value="unidades" className="space-y-4">
|
||||
{/* Conteúdo das unidades */}
|
||||
{tipoClasse === 1 ? <TImovelUnidadeUrbanoPage imovel_id={data?.imovel_id} /> : null}
|
||||
{/* Conteúdo das unidades */}
|
||||
{tipoClasse === 3 ? <TImovelUnidadeRuralIndex imovel_id={data?.imovel_id} /> : null}
|
||||
</TabsContent>
|
||||
</Tabs>
|
||||
</DialogContent>
|
||||
</Dialog >
|
||||
);
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ export default function TImovelIndex({ pageTitle, pageDescription, tipoClasse }:
|
|||
const { deleteTImovel } = useTImovelDeleteHook();
|
||||
|
||||
// Estados
|
||||
const [selectedAndamento, setSelectedAndamento] = useState<TImovelInterface | null>(null);
|
||||
const [selectedData, setSelectedData] = useState<TImovelInterface | null>(null);
|
||||
const [isFormOpen, setIsFormOpen] = useState(false);
|
||||
|
||||
// Estado para saber qual item será deletado
|
||||
|
|
@ -53,7 +53,15 @@ export default function TImovelIndex({ pageTitle, pageDescription, tipoClasse }:
|
|||
* Abre o formulário no modo de edição ou criação
|
||||
*/
|
||||
const handleOpenForm = useCallback((data: TImovelInterface | null) => {
|
||||
setSelectedAndamento(data);
|
||||
// Se não houver dados (criação), cria um objeto inicial com pessoa_tipo
|
||||
const initialData: TImovelInterface = data ?? { tipo_classe: tipoClasse } as TImovelInterface;
|
||||
|
||||
// Se existir dado de tipo_classe preenchido, converte para inteiro
|
||||
if (initialData.tipo_classe !== undefined && initialData.tipo_classe !== null) {
|
||||
initialData.tipo_classe = Number(initialData.tipo_classe);
|
||||
}
|
||||
|
||||
setSelectedData(initialData);
|
||||
setIsFormOpen(true);
|
||||
}, []);
|
||||
|
||||
|
|
@ -61,7 +69,7 @@ export default function TImovelIndex({ pageTitle, pageDescription, tipoClasse }:
|
|||
* Fecha o formulário e limpa o andamento selecionado
|
||||
*/
|
||||
const handleCloseForm = useCallback(() => {
|
||||
setSelectedAndamento(null);
|
||||
setSelectedData(null);
|
||||
setIsFormOpen(false);
|
||||
}, []);
|
||||
|
||||
|
|
@ -92,7 +100,6 @@ export default function TImovelIndex({ pageTitle, pageDescription, tipoClasse }:
|
|||
(item: TImovelInterface) => {
|
||||
// Define o item atual para remoção
|
||||
setItemToDelete(item);
|
||||
|
||||
// Abre o modal de confirmação
|
||||
openConfirmDialog();
|
||||
},
|
||||
|
|
@ -164,7 +171,7 @@ export default function TImovelIndex({ pageTitle, pageDescription, tipoClasse }:
|
|||
{/* Formulário de criação/edição */}
|
||||
<TImovelForm
|
||||
isOpen={isFormOpen}
|
||||
data={selectedAndamento}
|
||||
data={selectedData}
|
||||
onClose={handleCloseForm}
|
||||
onSave={handleSave}
|
||||
buttonIsLoading={buttonIsLoading}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,66 @@
|
|||
import { Button } from "@/components/ui/button";
|
||||
import { CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList } from "@/components/ui/command";
|
||||
import { FormControl } from "@/components/ui/form";
|
||||
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { ImovelConstrucaoEnum } from "@/shared/enums/ImovelConstrucaoEnum";
|
||||
import { Command } from "cmdk";
|
||||
import { CheckIcon, ChevronsUpDownIcon } from "lucide-react";
|
||||
import React from "react";
|
||||
|
||||
export default function TImovelTipoConstrucaoSelect({ field }: any) {
|
||||
const [open, setOpen] = React.useState(false);
|
||||
const options = Object.entries(ImovelConstrucaoEnum).map(([id, label]) => ({
|
||||
value: Number(id),
|
||||
label,
|
||||
}));
|
||||
return (
|
||||
<Popover open={open} onOpenChange={setOpen}>
|
||||
<PopoverTrigger asChild>
|
||||
<FormControl className="w-full">
|
||||
<Button
|
||||
variant="outline"
|
||||
role="combobox"
|
||||
aria-expanded={open}
|
||||
className="justify-between"
|
||||
>
|
||||
{field.value
|
||||
? options.find((item) => item.value === field.value)?.label
|
||||
: "Selecione..."}
|
||||
<ChevronsUpDownIcon className="ml-2 h-4 w-4 shrink-0 opacity-50" />
|
||||
</Button>
|
||||
</FormControl>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent className="w-full p-0">
|
||||
<Command>
|
||||
<CommandInput placeholder="Buscar tipo construção..." />
|
||||
<CommandList>
|
||||
<CommandEmpty>Nenhum resultado encontrado.</CommandEmpty>
|
||||
<CommandGroup>
|
||||
{options.map((item) => (
|
||||
<CommandItem
|
||||
key={item.value}
|
||||
value={item.label.toLowerCase()}
|
||||
onSelect={() => {
|
||||
field.onChange(item.value);
|
||||
setOpen(false);
|
||||
}}
|
||||
>
|
||||
<CheckIcon
|
||||
className={cn(
|
||||
"mr-2 h-4 w-4",
|
||||
field.value === item.value
|
||||
? "opacity-100"
|
||||
: "opacity-0"
|
||||
)}
|
||||
/>
|
||||
{item.label}
|
||||
</CommandItem>
|
||||
))}
|
||||
</CommandGroup>
|
||||
</CommandList>
|
||||
</Command>
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
);
|
||||
}
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
import { Button } from "@/components/ui/button";
|
||||
import { CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList } from "@/components/ui/command";
|
||||
import { FormControl } from "@/components/ui/form";
|
||||
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { ImovelTipoEnum } from "@/shared/enums/ImovelTipoEnum";
|
||||
import { Command } from "cmdk";
|
||||
import { CheckIcon, ChevronsUpDownIcon } from "lucide-react";
|
||||
import React from "react";
|
||||
|
||||
export default function TImovelTipoImovelSelect({ field }: any) {
|
||||
const [open, setOpen] = React.useState(false);
|
||||
const options = Object.entries(ImovelTipoEnum).map(([id, label]) => ({
|
||||
value: Number(id),
|
||||
label,
|
||||
}));
|
||||
|
||||
return (
|
||||
<Popover open={open} onOpenChange={setOpen}>
|
||||
<PopoverTrigger asChild>
|
||||
<FormControl className="w-full">
|
||||
<Button variant="outline" role="combobox" aria-expanded={open} className="justify-between">
|
||||
{field.value
|
||||
? options.find((item) => item.value === field.value)?.label
|
||||
: 'Selecione...'}
|
||||
<ChevronsUpDownIcon className="ml-2 h-4 w-4 shrink-0 opacity-50" />
|
||||
</Button>
|
||||
</FormControl>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent className="w-full p-0">
|
||||
<Command>
|
||||
<CommandInput placeholder="Buscar tipo imóvel..." />
|
||||
<CommandList>
|
||||
<CommandEmpty>Nenhum resultado encontrado.</CommandEmpty>
|
||||
<CommandGroup>
|
||||
{options.map((item) => (
|
||||
<CommandItem
|
||||
key={item.value}
|
||||
value={item.label.toLowerCase()}
|
||||
onSelect={() => {
|
||||
field.onChange(item.value);
|
||||
setOpen(false);
|
||||
}}
|
||||
>
|
||||
<CheckIcon
|
||||
className={cn(
|
||||
'mr-2 h-4 w-4',
|
||||
field.value === item.value ? 'opacity-100' : 'opacity-0'
|
||||
)}
|
||||
/>
|
||||
{item.label}
|
||||
</CommandItem>
|
||||
))}
|
||||
</CommandGroup>
|
||||
</CommandList>
|
||||
</Command>
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
);
|
||||
}
|
||||
|
|
@ -0,0 +1,92 @@
|
|||
'use client';
|
||||
|
||||
import React from "react";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import {
|
||||
Command,
|
||||
CommandEmpty,
|
||||
CommandGroup,
|
||||
CommandInput,
|
||||
CommandItem,
|
||||
CommandList,
|
||||
} from "@/components/ui/command";
|
||||
import { FormControl } from "@/components/ui/form";
|
||||
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { CheckIcon, ChevronsUpDownIcon } from "lucide-react";
|
||||
import GetCapitalize from "@/shared/actions/text/GetCapitalize";
|
||||
import { useGTBTipoLogradouroReadHook } from "@/app/(protected)/(cadastros)/cadastros/_hooks/g_tb_tipologradouro/useGTBTipoLogradouroReadHook";
|
||||
|
||||
export default function TImovelTipoLogradouroSelect({ field }: any) {
|
||||
const [open, setOpen] = React.useState(false);
|
||||
const [isLoading, setIsLoading] = React.useState(false);
|
||||
const { gTBTipoLogradouro, fetchGTBTipoLogradouro } = useGTBTipoLogradouroReadHook();
|
||||
// Busca os dados uma única vez ao montar
|
||||
React.useEffect(() => {
|
||||
const loadData = async () => {
|
||||
if (!gTBTipoLogradouro.length) {
|
||||
setIsLoading(true);
|
||||
await fetchGTBTipoLogradouro();
|
||||
setIsLoading(false);
|
||||
}
|
||||
};
|
||||
loadData();
|
||||
}, []);
|
||||
const selected = gTBTipoLogradouro.find(
|
||||
(item) => String(item.tb_tipologradouro_id) === String(field.value)
|
||||
);
|
||||
return (
|
||||
<Popover open={open} onOpenChange={setOpen}>
|
||||
<PopoverTrigger asChild>
|
||||
<FormControl className="w-full">
|
||||
<Button
|
||||
variant="outline"
|
||||
role="combobox"
|
||||
aria-expanded={open}
|
||||
disabled={isLoading}
|
||||
className="justify-between"
|
||||
>
|
||||
{isLoading
|
||||
? "Carregando..."
|
||||
: selected
|
||||
? GetCapitalize(selected.descricao)
|
||||
: "Selecione..."}
|
||||
<ChevronsUpDownIcon className="ml-2 h-4 w-4 shrink-0 opacity-50" />
|
||||
</Button>
|
||||
</FormControl>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent className="w-full p-0">
|
||||
<Command>
|
||||
<CommandInput placeholder="Buscar tipo logradouro..." />
|
||||
<CommandList>
|
||||
<CommandEmpty>
|
||||
{isLoading ? "Carregando..." : "Nenhum resultado encontrado."}
|
||||
</CommandEmpty>
|
||||
<CommandGroup>
|
||||
{gTBTipoLogradouro?.map((item) => (
|
||||
<CommandItem
|
||||
key={item.tb_tipologradouro_id}
|
||||
value={item.descricao?.toLowerCase() ?? ""}
|
||||
onSelect={() => {
|
||||
field.onChange(Number(item.tb_tipologradouro_id));
|
||||
setOpen(false);
|
||||
}}
|
||||
>
|
||||
<CheckIcon
|
||||
className={cn(
|
||||
"mr-2 h-4 w-4",
|
||||
String(field.value) === String(item.tb_tipologradouro_id)
|
||||
? "opacity-100"
|
||||
: "opacity-0"
|
||||
)}
|
||||
/>
|
||||
{GetCapitalize(item.descricao)}
|
||||
</CommandItem>
|
||||
))}
|
||||
</CommandGroup>
|
||||
</CommandList>
|
||||
</Command>
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
);
|
||||
}
|
||||
|
|
@ -53,7 +53,7 @@ export default function TImovelUnidadeRuralForm({ isOpen, data, onClose, onSave,
|
|||
async function loadData() {
|
||||
|
||||
// Carrega o tipo de logradouro
|
||||
await fetchGTBTipoLogradouro();
|
||||
// await fetchGTBTipoLogradouro();
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -23,44 +23,31 @@ import {
|
|||
import { Input } from '@/components/ui/input';
|
||||
|
||||
import LoadingButton from '@/shared/components/loadingButton/LoadingButton';
|
||||
import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover';
|
||||
import { CheckIcon, ChevronsUpDownIcon } from 'lucide-react';
|
||||
import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList } from '@/components/ui/command';
|
||||
import { cn } from '@/lib/utils';
|
||||
import GetCapitalize from '@/shared/actions/text/GetCapitalize';
|
||||
import { ResetFormIfData } from '@/shared/actions/form/ResetFormIfData';
|
||||
import { parseNumberInput } from '@/shared/actions/form/parseNumberInput';
|
||||
import { ImovelTipoEnum } from '@/shared/enums/ImovelTipoEnum';
|
||||
import { ImovelConstrucaoEnum } from '@/shared/enums/ImovelConstrucaoEnum';
|
||||
import { useGTBTipoLogradouroReadHook } from '@/app/(protected)/(cadastros)/cadastros/_hooks/g_tb_tipologradouro/useGTBTipoLogradouroReadHook';
|
||||
import { useTImovelUnidadeUrbanoFormHook } from '@/packages/administrativo/hooks/TImovelUnidade/TImovelUnidadeUrbano/useTImovelUnidadeUrbanoFormHook';
|
||||
import { TImovelUnidadeUrbanoFormInterface } from '@/packages/administrativo/interfaces/TImovelUnidade/TImovelUnidadeUrbano/TImovelUnidadeUrbanoFormInterface';
|
||||
import TImovelTipoImovelSelect from '../../TImovel/TImovelTipoImovelSelect';
|
||||
import TImovelTipoConstrucaoSelect from '../../TImovel/TImovelTipoConstrucaoSelect';
|
||||
import TImovelTipoLogradouroSelect from '../../TImovel/TImovelTipoLogradouroSelect';
|
||||
|
||||
export default function TImovelUnidadeUrbanoForm({ isOpen, data, onClose, onSave, buttonIsLoading }: TImovelUnidadeUrbanoFormInterface) {
|
||||
|
||||
const { gTBTipoLogradouro, fetchGTBTipoLogradouro } = useGTBTipoLogradouroReadHook();
|
||||
|
||||
// Inicializa o react-hook-form com schema zod
|
||||
const form = useTImovelUnidadeUrbanoFormHook();
|
||||
const form = useTImovelUnidadeUrbanoFormHook({});
|
||||
|
||||
// Atualiza o formulário quando recebe dados para edição
|
||||
// Aguarda alteração no Data
|
||||
useEffect(() => {
|
||||
|
||||
// Se existir dados, reseta o formulário com os mesmos
|
||||
ResetFormIfData(form, data);
|
||||
}, [data]);
|
||||
|
||||
// Carregamento de dados iniciais
|
||||
async function loadData() {
|
||||
|
||||
// Carrega o tipo de logradouro
|
||||
await fetchGTBTipoLogradouro();
|
||||
|
||||
}
|
||||
|
||||
// Executa a função
|
||||
loadData();
|
||||
|
||||
}, [data, form]);
|
||||
// Execução imediata
|
||||
useEffect(() => {
|
||||
if (!gTBTipoLogradouro.length) fetchGTBTipoLogradouro();
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<Dialog
|
||||
|
|
@ -153,65 +140,13 @@ export default function TImovelUnidadeUrbanoForm({ isOpen, data, onClose, onSave
|
|||
<FormField
|
||||
control={form.control}
|
||||
name="tb_tipologradouro_id"
|
||||
render={({ field }) => {
|
||||
const [open, setOpen] = React.useState(false);
|
||||
return (
|
||||
<FormItem>
|
||||
<FormLabel>Tipo logradouro</FormLabel>
|
||||
<Popover open={open} onOpenChange={setOpen}>
|
||||
<PopoverTrigger asChild>
|
||||
<FormControl className="w-full">
|
||||
<Button
|
||||
variant="outline"
|
||||
role="combobox"
|
||||
aria-expanded={open}
|
||||
className="justify-between"
|
||||
>
|
||||
{field.value
|
||||
? gTBTipoLogradouro.find(
|
||||
(item) =>
|
||||
String(item.tb_tipologradouro_id) === String(field.value),
|
||||
)?.descricao
|
||||
: 'Selecione...'}
|
||||
<ChevronsUpDownIcon className="ml-2 h-4 w-4 shrink-0 opacity-50" />
|
||||
</Button>
|
||||
</FormControl>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent className="w-full p-0">
|
||||
<Command>
|
||||
<CommandInput placeholder="Buscar tipo logradouro..." />
|
||||
<CommandList>
|
||||
<CommandEmpty>Nenhum resultado encontrado.</CommandEmpty>
|
||||
<CommandGroup>
|
||||
{gTBTipoLogradouro?.map((item) => (
|
||||
<CommandItem
|
||||
key={item.tb_tipologradouro_id}
|
||||
value={(item.descricao ?? '').toLowerCase()}
|
||||
onSelect={() => {
|
||||
field.onChange(Number(item.tb_tipologradouro_id));
|
||||
setOpen(false);
|
||||
}}
|
||||
>
|
||||
<CheckIcon
|
||||
className={cn(
|
||||
'mr-2 h-4 w-4',
|
||||
String(field.value) === String(item.descricao)
|
||||
? 'opacity-100'
|
||||
: 'opacity-0',
|
||||
)}
|
||||
/>
|
||||
{GetCapitalize(item.descricao)}
|
||||
</CommandItem>
|
||||
))}
|
||||
</CommandGroup>
|
||||
</CommandList>
|
||||
</Command>
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
);
|
||||
}}
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>Tipo logradouro</FormLabel>
|
||||
<TImovelTipoLogradouroSelect field={field} />
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
{/* Logradouro */}
|
||||
|
|
@ -236,62 +171,10 @@ export default function TImovelUnidadeUrbanoForm({ isOpen, data, onClose, onSave
|
|||
control={form.control}
|
||||
name="tipo_imovel"
|
||||
render={({ field }) => {
|
||||
const [open, setOpen] = React.useState(false);
|
||||
// transforma o objeto em um array [{value, label}]
|
||||
const options = Object.entries(ImovelTipoEnum).map(([id, label]) => ({
|
||||
value: Number(id),
|
||||
label,
|
||||
}));
|
||||
return (
|
||||
<FormItem>
|
||||
<FormLabel>Tipo Imóvel</FormLabel>
|
||||
<Popover open={open} onOpenChange={setOpen}>
|
||||
<PopoverTrigger asChild>
|
||||
<FormControl className="w-full">
|
||||
<Button
|
||||
variant="outline"
|
||||
role="combobox"
|
||||
aria-expanded={open}
|
||||
className="justify-between"
|
||||
>
|
||||
{field.value
|
||||
? options.find((item) => item.value === field.value)?.label
|
||||
: "Selecione..."}
|
||||
<ChevronsUpDownIcon className="ml-2 h-4 w-4 shrink-0 opacity-50" />
|
||||
</Button>
|
||||
</FormControl>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent className="w-full p-0">
|
||||
<Command>
|
||||
<CommandInput placeholder="Buscar tipo imóvel..." />
|
||||
<CommandList>
|
||||
<CommandEmpty>Nenhum resultado encontrado.</CommandEmpty>
|
||||
<CommandGroup>
|
||||
{options.map((item) => (
|
||||
<CommandItem
|
||||
key={item.value}
|
||||
value={item.label.toLowerCase()}
|
||||
onSelect={() => {
|
||||
field.onChange(item.value);
|
||||
setOpen(false);
|
||||
}}
|
||||
>
|
||||
<CheckIcon
|
||||
className={cn(
|
||||
"mr-2 h-4 w-4",
|
||||
field.value === item.value
|
||||
? "opacity-100"
|
||||
: "opacity-0"
|
||||
)}
|
||||
/>
|
||||
{item.label}
|
||||
</CommandItem>
|
||||
))}
|
||||
</CommandGroup>
|
||||
</CommandList>
|
||||
</Command>
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
<TImovelTipoImovelSelect field={field} />
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
);
|
||||
|
|
@ -304,61 +187,10 @@ export default function TImovelUnidadeUrbanoForm({ isOpen, data, onClose, onSave
|
|||
control={form.control}
|
||||
name="tipo_construcao"
|
||||
render={({ field }) => {
|
||||
const [open, setOpen] = React.useState(false);
|
||||
const options = Object.entries(ImovelConstrucaoEnum).map(([id, label]) => ({
|
||||
value: Number(id),
|
||||
label,
|
||||
}));
|
||||
return (
|
||||
<FormItem>
|
||||
<FormLabel>Construção</FormLabel>
|
||||
<Popover open={open} onOpenChange={setOpen}>
|
||||
<PopoverTrigger asChild>
|
||||
<FormControl className="w-full">
|
||||
<Button
|
||||
variant="outline"
|
||||
role="combobox"
|
||||
aria-expanded={open}
|
||||
className="justify-between"
|
||||
>
|
||||
{field.value
|
||||
? options.find((item) => item.value === field.value)?.label
|
||||
: "Selecione..."}
|
||||
<ChevronsUpDownIcon className="ml-2 h-4 w-4 shrink-0 opacity-50" />
|
||||
</Button>
|
||||
</FormControl>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent className="w-full p-0">
|
||||
<Command>
|
||||
<CommandInput placeholder="Buscar tipo construção..." />
|
||||
<CommandList>
|
||||
<CommandEmpty>Nenhum resultado encontrado.</CommandEmpty>
|
||||
<CommandGroup>
|
||||
{options.map((item) => (
|
||||
<CommandItem
|
||||
key={item.value}
|
||||
value={item.label.toLowerCase()}
|
||||
onSelect={() => {
|
||||
field.onChange(item.value);
|
||||
setOpen(false);
|
||||
}}
|
||||
>
|
||||
<CheckIcon
|
||||
className={cn(
|
||||
"mr-2 h-4 w-4",
|
||||
field.value === item.value
|
||||
? "opacity-100"
|
||||
: "opacity-0"
|
||||
)}
|
||||
/>
|
||||
{item.label}
|
||||
</CommandItem>
|
||||
))}
|
||||
</CommandGroup>
|
||||
</CommandList>
|
||||
</Command>
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
<TImovelTipoConstrucaoSelect field={field} />
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
);
|
||||
|
|
@ -495,7 +327,6 @@ export default function TImovelUnidadeUrbanoForm({ isOpen, data, onClose, onSave
|
|||
)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Numero da Edificação */}
|
||||
<div className="col-span-12 sm:col-span-6 md:col-span-4">
|
||||
<FormField
|
||||
|
|
@ -512,7 +343,6 @@ export default function TImovelUnidadeUrbanoForm({ isOpen, data, onClose, onSave
|
|||
)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Complemento */}
|
||||
<div className="col-span-12 sm:col-span-6 md:col-span-8">
|
||||
<FormField
|
||||
|
|
|
|||
|
|
@ -47,9 +47,6 @@ export default function TPessoaJuridicaColumns(
|
|||
{/* Nome e Email */}
|
||||
<div>
|
||||
<div className="font-semibold text-gray-900 capitalize">{pessoa.nome || '-'}</div>
|
||||
<div className="text-sm text-gray-500">
|
||||
{empty(pessoa.email) ? 'Email não informado' : pessoa.email}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
@ -57,7 +54,6 @@ export default function TPessoaJuridicaColumns(
|
|||
sortingFn: (a, b) =>
|
||||
(a.original.nome?.toLowerCase() || '').localeCompare(b.original.nome?.toLowerCase() || ''),
|
||||
},
|
||||
|
||||
// CPF
|
||||
{
|
||||
accessorKey: 'cpf_cnpj',
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { useForm } from "react-hook-form";
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import { TImovelFormValues, TImovelSchema } from "../../schemas/TImovel/TImovelSchema";
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
|
||||
export function useTImovelFormHook(defaults?: Partial<TImovelFormValues>) {
|
||||
return useForm<TImovelFormValues>({
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
export default interface TImovelInterface {
|
||||
imovel_id?: number,
|
||||
tipo_classe?: string,
|
||||
tipo_classe?: number,
|
||||
tipo_registro?: string,
|
||||
data_registro?: string,
|
||||
numero?: number,
|
||||
|
|
@ -9,7 +9,7 @@ export default interface TImovelInterface {
|
|||
cep?: string,
|
||||
uf?: string,
|
||||
tb_bairro_id?: number,
|
||||
cartorio?: string,
|
||||
cartorio?: number,
|
||||
livro?: string,
|
||||
cns?: number,
|
||||
gtbb_descricao?: string,
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import z from "zod";
|
|||
|
||||
export const TImovelSchema = z.object({
|
||||
imovel_id: z.number().optional(),
|
||||
tipo_classe: z.string().optional(),
|
||||
tipo_classe: z.number().optional(),
|
||||
tipo_registro: z.string().optional(),
|
||||
data_registro: z.string().optional(),
|
||||
numero: z.number().optional(),
|
||||
|
|
@ -11,9 +11,10 @@ export const TImovelSchema = z.object({
|
|||
cep: z.string().optional(),
|
||||
uf: z.string().optional(),
|
||||
tb_bairro_id: z.number().optional(),
|
||||
cartorio: z.string().optional(),
|
||||
cartorio: z.number().optional(),
|
||||
livro: z.string().optional(),
|
||||
cns: z.number().optional(),
|
||||
gtbb_descricao: z.string().optional(),
|
||||
});
|
||||
|
||||
export type TImovelFormValues = z.infer<typeof TImovelSchema>;
|
||||
Loading…
Add table
Reference in a new issue