Removendo todas as pastas TImovel do versionamento

This commit is contained in:
Kenio 2025-11-11 10:28:32 -03:00
parent 2a4c759c16
commit 588f3b3d06
9 changed files with 0 additions and 760 deletions

View file

@ -1,126 +0,0 @@
import { ColumnDef } from "@tanstack/react-table";
import TImovelInterface from "../../interfaces/TImovel/TImovelInterface";
import { Button } from "@/components/ui/button";
import {
EllipsisIcon,
PencilIcon,
Trash2Icon,
} from "lucide-react";
import { FormatDateTime } from "@/shared/actions/dateTime/FormatDateTime";
import { FormatCEP } from "@/shared/actions/CEP/FormatCEP";
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuGroup,
DropdownMenuItem,
DropdownMenuSeparator,
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
import { ImovelTipoRegistro } from "@/shared/enums/ImovelTipoRegistro";
import { SortableHeader } from "@/shared/components/dataTable/SortableHeader";
import GetCapitalize from "@/shared/actions/text/GetCapitalize";
export default function TImovelColumns(
onEdit: (item: TImovelInterface, isEditingFormStatus: boolean) => void,
onDelete: (item: TImovelInterface, isEditingFormStatus: boolean) => void
): ColumnDef<TImovelInterface>[] {
return [
// ID
{
accessorKey: "imovel_id",
header: ({ column }) => SortableHeader("#", column),
cell: ({ row }) => Number(row.getValue("imovel_id")),
enableSorting: false,
},
// Tipo Registro
{
accessorKey: "tipo_registro",
header: ({ column }) => SortableHeader("Tipo Registro", column),
cell: ({ row }) => {
const value = row.getValue("tipo_registro") as keyof typeof ImovelTipoRegistro;
return ImovelTipoRegistro[value] ?? value;
},
},
// Número
{
accessorKey: "numero",
header: ({ column }) => SortableHeader("Número", column),
cell: ({ row }) => row.getValue("numero"),
},
// UF / Cidade / Bairro
{
id: "uf_cidade_bairro",
accessorFn: (row) => row,
header: ({ column }) => SortableHeader("Cidade / UF / Bairro", column),
cell: ({ row }) => {
const imovel = row.original;
return (
<div className="flex flex-col">
<span className="font-semibold text-gray-900 capitalize">
{GetCapitalize(imovel.cidade)}/{imovel.uf}
</span>
<span className="text-sm text-gray-500">{GetCapitalize(imovel.gtbb_descricao)}</span>
</div>
);
},
sortingFn: (a, b) =>
(a.original.cartorio?.toLowerCase() || "").localeCompare(
b.original.cartorio?.toLowerCase() || ""
),
},
// CEP
{
accessorKey: "cep",
header: ({ column }) => SortableHeader("CEP", column),
cell: ({ row }) => FormatCEP(row.getValue("cep")),
},
// Data de Registro
{
accessorKey: "data_registro",
header: ({ column }) => SortableHeader("Cadastro", column),
cell: ({ row }) => FormatDateTime(row.getValue("data_registro")),
sortingFn: "datetime",
},
// Ações
{
id: "actions",
header: "Ações",
cell: ({ row }) => {
const imovel = row.original;
return (
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="ghost" size="icon">
<EllipsisIcon />
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent side="left" align="start">
<DropdownMenuGroup>
<DropdownMenuItem onSelect={() => onEdit(imovel, true)}>
<PencilIcon className="mr-2 h-4 w-4" />
Editar
</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuItem
className="text-red-600"
onSelect={() => onDelete(imovel, true)}
>
<Trash2Icon className="mr-2 h-4 w-4" />
Remover
</DropdownMenuItem>
</DropdownMenuGroup>
</DropdownMenuContent>
</DropdownMenu>
);
},
enableSorting: false,
enableHiding: false,
},
];
}

View file

@ -1,385 +0,0 @@
'use client';
import React, { useEffect } from 'react';
import { Button } from '@/components/ui/button';
import {
Dialog,
DialogClose,
DialogContent,
DialogDescription,
DialogFooter,
DialogHeader,
DialogTitle,
} from '@/components/ui/dialog';
import {
Form,
FormControl,
FormField,
FormItem,
FormLabel,
FormMessage,
} from '@/components/ui/form';
import { Input } from '@/components/ui/input';
import LoadingButton from '@/shared/components/loadingButton/LoadingButton';
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';
import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList } from '@/components/ui/command';
import { cn } from '@/lib/utils';
import GetCapitalize from '@/shared/actions/text/GetCapitalize';
import { TImovelFormInterface } from '../../interfaces/TImovel/TImovelFormInterface';
import { useTImovelFormHook } from '../../hooks/TImovel/useTImovelFormHook';
import TImovelUnidadeUrbanoPage from '../TImovelUnidade/TImovelUnidadeUrbano/TImovelUnidadeUrbanoPage';
import TImovelUnidadeRuralPage from '../TImovelUnidade/TImovelUnidadeRural/TImovelUnidadeRuralPage';
import { parseNumberInput } from '@/shared/actions/form/parseNumberInput';
export default function TImovelForm({ isOpen, data, onClose, onSave, buttonIsLoading, tipoClasse }: TImovelFormInterface) {
const { gTBBairro, fetchGTBBairro } = useGTBBairroReadHook();
// Inicializa o react-hook-form com schema zod
const form = useTImovelFormHook();
// Atualiza o formulário quando recebe dados para edição
useEffect(() => {
// Se existir dados, reseta o formulário com os mesmos
ResetFormIfData(form, data);
// Função sincrona para carregamento de dados
async function loadData() {
// Busca os bairros
await fetchGTBBairro();
}
// Executa a função
loadData();
}, [data, form]);
return (
<Dialog
open={isOpen}
onOpenChange={(open) => {
if (!open) onClose(null, false);
}}
>
<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
</DialogTitle>
<DialogDescription>
Cadastro de imóvel urbano
</DialogDescription>
</DialogHeader>
<Form {...form}>
<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">
<div className="grid w-full grid-cols-12 gap-4">
{/* UF */}
<div className="col-span-12 sm:col-span-6 md:col-span-2">
<FormField
control={form.control}
name="uf"
render={({ field }) => (
<FormItem>
<FormLabel>UF</FormLabel>
<FormControl>
<Input {...field} type='text' placeholder="UF" maxLength={2} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
</div>
{/* CEP */}
<div className="col-span-12 sm:col-span-6 md:col-span-4">
<FormField
control={form.control}
name="cep"
render={({ field }) => (
<FormItem>
<FormLabel>CEP</FormLabel>
<FormControl>
<Input {...field} type='text' placeholder="Digite o CEP" />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
</div>
{/* Cidade */}
<div className="col-span-12 sm:col-span-6 md:col-span-3">
<FormField
control={form.control}
name="cidade"
render={({ field }) => (
<FormItem>
<FormLabel>Cidade</FormLabel>
<FormControl>
<Input {...field} type="text" placeholder="Digite a cidade" />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
</div>
{/* Bairro */}
<div className="col-span-12 sm:col-span-6 md:col-span-3">
<FormField
control={form.control}
name="tb_bairro_id"
render={({ field }) => {
const [open, setOpen] = React.useState(false);
return (
<FormItem>
<FormLabel>Bairro</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
? gTBBairro.find(
(item) =>
String(item.tb_bairro_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>
{gTBBairro?.map((item) => (
<CommandItem
key={item.tb_bairro_id}
value={(item.descricao ?? '').toLowerCase()}
onSelect={() => {
field.onChange(Number(item.tb_bairro_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>
);
}}
/>
</div>
{/* Cartório */}
<div className="col-span-12 sm:col-span-6 md:col-span-2">
<FormField
control={form.control}
name="cartorio"
render={({ field }) => (
<FormItem>
<FormLabel>Cartório</FormLabel>
<FormControl>
<Input {...field} type='number' placeholder="Digite o cartório" />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
</div>
{/* CNS */}
<div className="col-span-12 sm:col-span-6 md:col-span-5">
<FormField
control={form.control}
name="cns"
render={({ field }) => (
<FormItem>
<FormLabel>CNS</FormLabel>
<FormControl>
<Input {...field} type="number" placeholder="Digite o CNS" onChange={e => field.onChange(parseNumberInput(e))} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
</div>
{/* Livro */}
<div className="col-span-12 sm:col-span-6 md:col-span-5">
<FormField
control={form.control}
name="livro"
render={({ field }) => (
<FormItem>
<FormLabel>Livro</FormLabel>
<FormControl>
<Input {...field} type='text' placeholder="Digite o livro" />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
</div>
{/* Tipo Registro */}
<div className="col-span-12 sm:col-span-6 md:col-span-3">
<FormField
control={form.control}
name="tipo_registro"
render={({ field }) => (
<FormItem className="w-full">
<FormLabel>Tipo Registro</FormLabel>
<FormControl>
<Select value={field.value} onValueChange={field.onChange}>
<SelectTrigger className="w-full">
{field.value
? ImovelTipoRegistro[field.value as keyof typeof ImovelTipoRegistro]
: "Selecione"}
</SelectTrigger>
<SelectContent>
{Object.entries(ImovelTipoRegistro).map(([key, label]) => (
<SelectItem key={key} value={key} className="cursor-pointer">
{label}
</SelectItem>
))}
</SelectContent>
</Select>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
</div>
{/* Número */}
<div className="col-span-12 sm:col-span-6 md:col-span-3">
<FormField
control={form.control}
name="numero"
render={({ field }) => (
<FormItem>
<FormLabel>Número</FormLabel>
<FormControl>
<Input {...field} type="number" placeholder="Digite o número" />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
</div>
{/* Número Letra */}
<div className="col-span-12 sm:col-span-6 md:col-span-3">
<FormField
control={form.control}
name="numero_letra"
render={({ field }) => (
<FormItem>
<FormLabel>Número Letra</FormLabel>
<FormControl>
<Input {...field} type='text' placeholder="Digite a letra" />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
</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>
</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 ? <TImovelUnidadeRuralPage /> : null}
</TabsContent>
</Tabs>
{/* Rodapé do Dialog */}
<DialogFooter className="mt-4 flex flex-col sm:flex-row gap-2 justify-end">
<DialogClose asChild>
<Button variant="outline" type="button" onClick={() => onClose(null, false)}>
Cancelar
</Button>
</DialogClose>
<LoadingButton
text="Salvar"
textLoading="Aguarde..."
type="submit"
loading={buttonIsLoading}
/>
</DialogFooter>
{/* Campo oculto */}
<input type="hidden" {...form.register("imovel_id")} />
</form>
</Form>
</DialogContent>
</Dialog>
);
}

View file

@ -1,170 +0,0 @@
'use client';
import { useEffect, useState, useCallback } from 'react';
import Loading from '@/shared/components/loading/loading';
import { useTImovelIndexHook } from '@/packages/administrativo/hooks/TImovel/useTImovelIndexHook';
import { useTImovelSaveHook } from '@/packages/administrativo/hooks/TImovel/useTImovelSaveHook';
import { useTImovelDeleteHook } from '@/packages/administrativo/hooks/TImovel/useTImovelDeleteHook';
import ConfirmDialog from '@/shared/components/confirmDialog/ConfirmDialog';
import { useConfirmDialog } from '@/shared/components/confirmDialog/useConfirmDialog';
import TImovelInterface from '@/packages/administrativo/interfaces/TImovel/TImovelInterface';
import Header from '@/shared/components/structure/Header';
import { TImovelIndexInterface } from '../../interfaces/TImovel/TImovelIndexInterface';
import TImovelTable from './TImovelTable';
import TImovelForm from './TImovelForm';
export default function TImovelIndex({ pageTitle, pageDescription, tipoClasse }: TImovelIndexInterface) {
// Controle de estado do botão
const [buttonIsLoading, setButtonIsLoading] = useState(false);
// Hooks para leitura e salvamento
const { tImovel, indexTImovel } = useTImovelIndexHook();
const { saveTImovel } = useTImovelSaveHook();
const { deleteTImovel } = useTImovelDeleteHook();
// Estados
const [selectedAndamento, setSelectedAndamento] = useState<TImovelInterface | null>(null);
const [isFormOpen, setIsFormOpen] = useState(false);
// Estado para saber qual item será deletado
const [itemToDelete, setItemToDelete] = useState<TImovelInterface | null>(null);
/**
* Hook do modal de confirmação
*/
const {
isOpen: isConfirmOpen,
openDialog: openConfirmDialog,
handleConfirm,
handleCancel,
} = useConfirmDialog();
/**
* Abre o formulário no modo de edição ou criação
*/
const handleOpenForm = useCallback((data: TImovelInterface | null) => {
setSelectedAndamento(data);
setIsFormOpen(true);
}, []);
/**
* Fecha o formulário e limpa o andamento selecionado
*/
const handleCloseForm = useCallback(() => {
setSelectedAndamento(null);
setIsFormOpen(false);
}, []);
/**
* Salva os dados do formulário
*/
const handleSave = useCallback(
async (formData: TImovelInterface) => {
// Coloca o botão em estado de loading
setButtonIsLoading(true);
// Aguarda salvar o registro
await saveTImovel(formData);
// Remove o botão em estado de loading
setButtonIsLoading(false);
// Atualiza a lista de dados
indexTImovel();
},
[saveTImovel, indexTImovel, handleCloseForm],
);
/**
* Quando o usuário clica em "remover" na tabela
*/
const handleConfirmDelete = useCallback(
(item: TImovelInterface) => {
// Define o item atual para remoção
setItemToDelete(item);
// Abre o modal de confirmação
openConfirmDialog();
},
[openConfirmDialog],
);
/**
* Executa a exclusão de fato quando o usuário confirma
*/
const handleDelete = useCallback(async () => {
// Protege contra null
if (!itemToDelete) return;
// Executa o Hook de remoção
await deleteTImovel(itemToDelete);
// Atualiza a lista
await indexTImovel();
// Limpa o item selecionado
setItemToDelete(null);
// Fecha o modal
handleCancel();
}, [itemToDelete, indexTImovel, handleCancel]);
/**
* Busca inicial dos dados
*/
useEffect(() => {
indexTImovel();
}, []);
/**
* Tela de loading enquanto carrega os dados
*/
if (tImovel?.length == 0) {
return <Loading type={2} />;
}
return (
<div>
{/* Cabeçalho */}
<Header
title={pageTitle}
description={pageDescription}
buttonText={'Novo imóvel'}
buttonAction={() => {
handleOpenForm(null);
}}
/>
{/* Tabela de andamentos */}
<TImovelTable
data={tImovel}
onEdit={handleOpenForm}
onDelete={handleConfirmDelete}
/>
{/* Modal de confirmação */}
<ConfirmDialog
isOpen={isConfirmOpen}
title="Confirmar exclusão"
description="Atenção"
message={`Deseja realmente excluir o imóvel "${itemToDelete?.cidade}"?`}
confirmText="Sim, excluir"
cancelText="Cancelar"
onConfirm={handleDelete}
onCancel={handleCancel}
/>
{/* Formulário de criação/edição */}
<TImovelForm
isOpen={isFormOpen}
data={selectedAndamento}
onClose={handleCloseForm}
onSave={handleSave}
buttonIsLoading={buttonIsLoading}
tipoClasse={tipoClasse}
/>
</div>
);
}

View file

@ -1,22 +0,0 @@
'use client';
import { DataTable } from '@/shared/components/dataTable/DataTable';
import TImovelColumns from './TImovelColumns';
import TImovelTableInterface from '../../interfaces/TImovel/TImovelTabelInterface';
/**
* Componente principal da tabela
*/
export default function TImovelTable({ data, onEdit, onDelete }: TImovelTableInterface) {
const columns = TImovelColumns(onEdit, onDelete);
return (
<div>
<DataTable
data={data}
columns={columns}
filterColumn="numero"
filterPlaceholder="Buscar pelo numero de transcrição, matricula etc..."
/>
</div>
);
}

View file

@ -1,10 +0,0 @@
import { TImovelFormValues } from "../../schemas/TImovel/TImovelSchema";
export interface TImovelFormInterface {
isOpen: boolean;
data: TImovelFormValues | null;
onClose: (item: null, isFormStatus: boolean) => void;
onSave: (data: TImovelFormValues) => void;
buttonIsLoading: boolean;
tipoClasse: number;
}

View file

@ -1,5 +0,0 @@
export interface TImovelIndexInterface {
pageTitle: string,
pageDescription: string,
tipoClasse: number
}

View file

@ -1,16 +0,0 @@
export default interface TImovelInterface {
imovel_id?: number,
tipo_classe?: string,
tipo_registro?: string,
data_registro?: string,
numero?: number,
numero_letra?: string,
cidade?: string,
cep?: string,
uf?: string,
tb_bairro_id?: number,
cartorio?: string,
livro?: string,
cns?: number,
gtbb_descricao?: string,
}

View file

@ -1,7 +0,0 @@
import TImovelInterface from "./TImovelInterface";
export default interface TImovelTableInterface {
data?: TImovelInterface[];
onEdit: (item: TImovelInterface, isEditingFormStatus: boolean) => void;
onDelete: (item: TImovelInterface, isEditingFormStatus: boolean) => void;
}

View file

@ -1,19 +0,0 @@
import z from "zod";
export const TImovelSchema = z.object({
imovel_id: z.number().optional(),
tipo_classe: z.string().optional(),
tipo_registro: z.string().optional(),
data_registro: z.string().optional(),
numero: z.number().optional(),
numero_letra: z.string().optional(),
cidade: z.string().optional(),
cep: z.string().optional(),
uf: z.string().optional(),
tb_bairro_id: z.number().optional(),
cartorio: z.string().optional(),
livro: z.string().optional(),
cns: z.number().optional(),
});
export type TImovelFormValues = z.infer<typeof TImovelSchema>;