[MVPTN-99] refactor(Arquitetura): Refatoração da arquiteturação do Tpessoa

This commit is contained in:
Keven Willian Pereira de Souza 2025-10-03 10:35:43 -03:00
parent 7f9b7944db
commit f5ffe5739c
36 changed files with 481 additions and 519 deletions

View file

@ -3,8 +3,8 @@
import React, { useEffect, useState, useCallback } from 'react';
import Loading from '@/app/_components/loading/loading';
import TPessoaTable from '@/packages/administrativo/components/t_pessoa/fisica/TPessoaFisicaTable';
import TPessoaForm from '@/packages/administrativo/components/t_pessoa/fisica/TPessoaFisicaForm';
import TPessoaTable from '@/packages/administrativo/components/TPessoa/TPessoaFisica/TPessoaFisicaTable';
import TPessoaForm from '@/packages/administrativo/components/TPessoa/TPessoaFisica/TPessoaFisicaForm';
import { useTPessoaIndexHook } from '@/packages/administrativo/hooks/t_pessoa/useTPessoaIndexHook';
import { useTPessoaSaveHook } from '@/packages/administrativo/hooks/t_pessoa/useTPessoaSaveHook';
@ -13,7 +13,7 @@ import { useTPessoaDeleteHook } from '@/packages/administrativo/hooks/t_pessoa/u
import ConfirmDialog from '@/app/_components/confirm_dialog/ConfirmDialog';
import { useConfirmDialog } from '@/app/_components/confirm_dialog/useConfirmDialog';
import TPessoaInterface from '@/packages/administrativo/interfaces/TPessoaInterface';
import TPessoaInterface from '@/packages/administrativo/interfaces/TPessoa/TPessoaInterface';
import Header from '@/app/_components/structure/Header';
export default function TPessoaFisica() {

View file

@ -10,11 +10,11 @@ import { useTPessoaDeleteHook } from '@/packages/administrativo/hooks/t_pessoa/u
import ConfirmDialog from '@/app/_components/confirm_dialog/ConfirmDialog';
import { useConfirmDialog } from '@/app/_components/confirm_dialog/useConfirmDialog';
import TPessoaInterface from '@/packages/administrativo/interfaces/TPessoaInterface';
import TPessoaInterface from '@/packages/administrativo/interfaces/TPessoa/TPessoaInterface';
import Header from '@/app/_components/structure/Header';
import TPessoaJuridicaTable from '@/packages/administrativo/components/t_pessoa/juridica/TPessoaJuridicaTable';
import TPessoaJuridicaTable from '@/packages/administrativo/components/TPessoa/TPessoaJuridica/TPessoaJuridicaTable';
import { useTPessoaJuridicaIndexHook } from '@/packages/administrativo/hooks/t_pessoa/juridica/useTPessoaJuridicaIndexHook';
import TPessoaJuridicaForm from '@/packages/administrativo/components/t_pessoa/juridica/TPessoaJuridicaForm';
import TPessoaJuridicaForm from '@/packages/administrativo/components/TPessoa/TPessoaJuridica/TPessoaJuridicaForm';
export default function TPessoaFisica() {
// Controle de estado do botão

View file

@ -1,41 +1,21 @@
'use client';
import { Button } from '@/components/ui/button';
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuGroup,
DropdownMenuItem,
DropdownMenuSeparator,
DropdownMenuTrigger,
} from '@/components/ui/dropdown-menu';
import { ArrowUpDownIcon, EllipsisIcon, PencilIcon, Trash2Icon } from 'lucide-react';
import { ColumnDef } from '@tanstack/react-table';
import GetNameInitials from '@/actions/text/GetNameInitials';
import { DataTable } from '@/app/_components/dataTable/DataTable';
import TPessoaInterface from '../../../interfaces/TPessoaInterface';
import { FormatCPF } from '@/actions/CPF/FormatCPF';
import { FormatPhone } from '@/actions/phone/FormatPhone';
import { FormatDateTime } from '@/actions/dateTime/FormatDateTime';
import empty from '@/actions/validations/empty';
// Tipagem das props
interface TPessoaTableProps {
data: TPessoaInterface[];
onEdit: (item: TPessoaInterface, isEditingFormStatus: boolean) => void;
onDelete: (item: TPessoaInterface, isEditingFormStatus: boolean) => void;
}
import { FormatCPF } from "@/actions/CPF/FormatCPF";
import { FormatDateTime } from "@/actions/dateTime/FormatDateTime";
import { FormatPhone } from "@/actions/phone/FormatPhone";
import GetNameInitials from "@/actions/text/GetNameInitials";
import empty from "@/actions/validations/empty";
import { Button } from "@/components/ui/button";
import { DropdownMenu, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuSeparator, DropdownMenuTrigger } from "@/components/ui/dropdown-menu";
import TPessoaFisicaInterface from "@/packages/administrativo/interfaces/TPessoa/TPessoaFisica/TPessoaFisicaInterface";
import { ColumnDef } from "@tanstack/react-table";
import { ArrowUpDownIcon, EllipsisIcon, PencilIcon, Trash2Icon } from "lucide-react";
/**
* Função para criar a definição das colunas da tabela
*/
function createPessoaColumns(
onEdit: (item: TPessoaInterface, isEditingFormStatus: boolean) => void,
onDelete: (item: TPessoaInterface, isEditingFormStatus: boolean) => void,
): ColumnDef<TPessoaInterface>[] {
export function TPessoaFisicaColumns(
onEdit: (item: TPessoaFisicaInterface, isEditingFormStatus: boolean) => void,
onDelete: (item: TPessoaFisicaInterface, isEditingFormStatus: boolean) => void,
): ColumnDef<TPessoaFisicaInterface>[] {
return [
// ID
{
@ -196,21 +176,4 @@ function createPessoaColumns(
enableHiding: false,
},
];
}
/**
* Componente principal da tabela
*/
export default function TPessoaTable({ data, onEdit, onDelete }: TPessoaTableProps) {
const columns = createPessoaColumns(onEdit, onDelete);
return (
<div>
<DataTable
data={data}
columns={columns}
filterColumn="nome_completo"
filterPlaceholder="Buscar por nome ou email..."
/>
</div>
);
}
}

View file

@ -1,9 +1,6 @@
'use client';
import z from 'zod';
import React, { useEffect } from 'react';
import { useForm, Controller } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import { Button } from '@/components/ui/button';
import {
@ -25,7 +22,6 @@ import {
} from '@/components/ui/form';
import { Input } from '@/components/ui/input';
import { TPessoaSchema } from '../../../schemas/TPessoaFisicaSchema';
import LoadingButton from '@/app/_components/loadingButton/LoadingButton';
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
import {
@ -33,7 +29,6 @@ import {
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from '@/components/ui/select';
import { CheckIcon, ChevronsUpDownIcon, HouseIcon, IdCardIcon, UserIcon } from 'lucide-react';
import { Sexo } from '@/enums/SexoEnum';
@ -51,50 +46,36 @@ import {
CommandList,
} from '@/components/ui/command';
import { cn } from '@/lib/utils';
import TPessoaFisicaFormInterface from '../../../interfaces/TPessoa/TPessoaFisica/TPessoaFisicaFormInterface';
import { ResetFormIfData } from '@/actions/form/ResetFormIfData';
import { useTPessoaForm } from '@/packages/administrativo/hooks/t_pessoa/fisica/usetTPessoaFormHook';
type FormValues = z.infer<typeof TPessoaSchema>;
interface TPessoaFormProps {
isOpen: boolean;
data: FormValues | null;
onClose: (item: null, isFormStatus: boolean) => void;
onSave: (data: FormValues) => void;
buttonIsLoading: boolean;
}
export default function TCensecForm({
export default function TPessoaFisicaForm({
isOpen,
data,
onClose,
onSave,
buttonIsLoading,
}: TPessoaFormProps) {
}: TPessoaFisicaFormInterface) {
const { gTBProfissao, fetchGTBProfissao } = useGTBProfissaoReadHook();
const { gTBEstadoCivil, fetchGTBEstadoCivil } = useGTBEstadoCivilReadHook();
const { gTBRegimeComunhao, fetchGTBRegimeComunhao } = useGTBRegimeComunhaoReadHook();
// Inicializa o react-hook-form com schema zod
const form = useForm<FormValues>({
resolver: zodResolver(TPessoaSchema),
defaultValues: {
nome: '',
pessoa_id: 0,
},
});
const form = useTPessoaForm({});
// Atualiza o formulário quando recebe dados para edição
useEffect(() => {
// Função para carregar os dados de forma sincrona
const loadData = async () => {
// Se existir dados, reseta o formulário com os dados informados
if (data) form.reset(data);
ResetFormIfData(form, data)
// Aguarda a busca terminar
await fetchGTBProfissao();
await fetchGTBEstadoCivil();
await fetchGTBRegimeComunhao();
};
// Dispara a função
loadData();
}, [data, form]);
@ -108,8 +89,12 @@ export default function TCensecForm({
>
<DialogContent className="w-full max-w-full p-6 sm:max-w-3xl md:max-w-4xl lg:max-w-5xl">
<DialogHeader>
<DialogTitle>Pessoa</DialogTitle>
<DialogDescription>Preencha os dados da pessoa</DialogDescription>
<DialogTitle>
Pessoa Física
</DialogTitle>
<DialogDescription>
Preencha os dados da pessoa
</DialogDescription>
</DialogHeader>
<Form {...form}>
<form onSubmit={form.handleSubmit(onSave)} className="space-y-6">
@ -310,10 +295,10 @@ export default function TCensecForm({
className="justify-between"
>
{field.value
? gTBEstadoCivil.find(
(item) =>
String(item.tb_estadocivil_id) === String(field.value),
)?.descricao
? gTBEstadoCivil?.find(
(item) =>
String(item.tb_estadocivil_id) === String(field.value),
)?.descricao
: 'Escolha o estado civil'}
<ChevronsUpDownIcon className="ml-2 h-4 w-4 shrink-0 opacity-50" />
</Button>
@ -376,11 +361,11 @@ export default function TCensecForm({
className="justify-between"
>
{field.value
? gTBRegimeComunhao.find(
(item) =>
String(item.tb_regimecomunhao_id) ===
String(field.value),
)?.descricao
? gTBRegimeComunhao?.find(
(item) =>
String(item.tb_regimecomunhao_id) ===
String(field.value),
)?.descricao
: 'Escolha o regime'}
<ChevronsUpDownIcon className="ml-2 h-4 w-4 shrink-0 opacity-50" />
</Button>
@ -444,10 +429,10 @@ export default function TCensecForm({
className="justify-between"
>
{field.value
? gTBProfissao.find(
(item) =>
String(item.tb_profissao_id) === String(field.value),
)?.descricao
? gTBProfissao?.find(
(item) =>
String(item.tb_profissao_id) === String(field.value),
)?.descricao
: 'Escolha a profissão'}
<ChevronsUpDownIcon className="ml-2 h-4 w-4 shrink-0 opacity-50" />
</Button>
@ -800,7 +785,6 @@ export default function TCensecForm({
)}
/>
</div>
{/* Validade */}
<div className="col-span-12 sm:col-span-12 md:col-span-3">
<FormField
@ -820,7 +804,6 @@ export default function TCensecForm({
</div>
</TabsContent>
</Tabs>
{/* Rodapé do Dialog */}
<DialogFooter className="mt-4">
<DialogClose asChild>
@ -840,7 +823,6 @@ export default function TCensecForm({
loading={buttonIsLoading}
/>
</DialogFooter>
{/* Campo oculto */}
<input type="hidden" {...form.register('pessoa_id')} />
</form>

View file

@ -0,0 +1,22 @@
'use client';
import { DataTable } from '@/app/_components/dataTable/DataTable';
import TPessoaFisicaTableInterface from '@/packages/administrativo/interfaces/TPessoa/TPessoaFisica/TPessoaFisicaTableInterface';
import { TPessoaFisicaColumns } from './TPessoaFisicaColumns';
/**
* Componente principal da tabela
*/
export default function TPessoaFisicaTable({ data, onEdit, onDelete }: TPessoaFisicaTableInterface) {
const columns = TPessoaFisicaColumns(onEdit, onDelete);
return (
<div>
<DataTable
data={data}
columns={columns}
filterColumn="nome_completo"
filterPlaceholder="Buscar por nome ou email..."
/>
</div>
);
}

View file

@ -0,0 +1,159 @@
import { FormatCNPJ } from "@/actions/CNPJ/FormatCNPJ";
import { FormatDateTime } from "@/actions/dateTime/FormatDateTime";
import { FormatPhone } from "@/actions/phone/FormatPhone";
import empty from "@/actions/validations/empty";
import { Button } from "@/components/ui/button";
import { DropdownMenu, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuSeparator, DropdownMenuTrigger } from "@/components/ui/dropdown-menu";
import TPessoaJuridicaInterface from "@/packages/administrativo/interfaces/TPessoa/TPessoaJuridica/TPessoaJuridicaInterface";
import { ColumnDef } from "@tanstack/react-table";
import { ArrowUpDownIcon, EllipsisIcon, PencilIcon, Trash2Icon } from "lucide-react";
export default function TPessoaJuridicaColumns(
onEdit: (item: TPessoaJuridicaInterface, isEditingFormStatus: boolean) => void,
onDelete: (item: TPessoaJuridicaInterface, isEditingFormStatus: boolean) => void,
): ColumnDef<TPessoaJuridicaInterface>[] {
return [
// ID
{
accessorKey: 'pessoa_id',
header: ({ column }) => (
<Button
variant="ghost"
onClick={() => column.toggleSorting(column.getIsSorted() === 'asc')}
>
# <ArrowUpDownIcon className="ml-1 h-4 w-4" />
</Button>
),
cell: ({ row }) => Number(row.getValue('pessoa_id')),
enableSorting: false,
},
// Nome / Email / Foto
{
id: 'nome_completo',
accessorFn: (row) => row,
header: ({ column }) => (
<Button
variant="ghost"
onClick={() => column.toggleSorting(column.getIsSorted() === 'asc')}
>
Nome / Email <ArrowUpDownIcon className="ml-1 h-4 w-4 cursor-pointer" />
</Button>
),
cell: ({ row }) => {
const pessoa = row.original;
return (
<div className="flex items-center gap-3">
{/* 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>
);
},
sortingFn: (a, b) =>
(a.original.nome?.toLowerCase() || '').localeCompare(b.original.nome?.toLowerCase() || ''),
},
// CPF
{
accessorKey: 'cpf_cnpj',
header: ({ column }) => (
<Button
variant="ghost"
onClick={() => column.toggleSorting(column.getIsSorted() === 'asc')}
>
CNPJ <ArrowUpDownIcon className="ml-1 h-4 w-4 cursor-pointer" />
</Button>
),
cell: ({ row }) => FormatCNPJ(row.getValue('cpf_cnpj')),
},
// Telefone
{
accessorKey: 'telefone',
header: ({ column }) => (
<Button
variant="ghost"
onClick={() => column.toggleSorting(column.getIsSorted() === 'asc')}
>
Telefone <ArrowUpDownIcon className="ml-1 h-4 w-4 cursor-pointer" />
</Button>
),
cell: ({ row }) => FormatPhone(row.getValue('telefone')),
},
// Cidade / UF
{
id: 'cidade_uf',
accessorFn: (row) => `${row.cidade}/${row.uf}`,
header: ({ column }) => (
<Button
variant="ghost"
onClick={() => column.toggleSorting(column.getIsSorted() === 'asc')}
>
Cidade/UF <ArrowUpDownIcon className="ml-1 h-4 w-4 cursor-pointer" />
</Button>
),
cell: ({ row }) => <span>{row.getValue('cidade_uf') || '-'}</span>,
sortingFn: (a, b) =>
`${a.original.cidade}/${a.original.uf}`
.toLowerCase()
.localeCompare(`${b.original.cidade}/${b.original.uf}`.toLowerCase()),
},
// Data de cadastro
{
accessorKey: 'data_cadastro',
header: ({ column }) => (
<Button
variant="ghost"
onClick={() => column.toggleSorting(column.getIsSorted() === 'asc')}
>
Cadastro <ArrowUpDownIcon className="ml-1 h-4 w-4 cursor-pointer" />
</Button>
),
cell: ({ row }) => FormatDateTime(row.getValue('data_cadastro')),
sortingFn: 'datetime',
},
// Ações
{
id: 'actions',
header: 'Ações',
cell: ({ row }) => {
const pessoa = row.original;
return (
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="ghost" size="icon" className="cursor-pointer">
<EllipsisIcon />
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent side="left" align="start">
<DropdownMenuGroup>
<DropdownMenuItem className="cursor-pointer" onSelect={() => onEdit(pessoa, true)}>
<PencilIcon className="mr-2 h-4 w-4" />
Editar
</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuItem
className="cursor-pointer text-red-600"
onSelect={() => onDelete(pessoa, true)}
>
<Trash2Icon className="mr-2 h-4 w-4" />
Remover
</DropdownMenuItem>
</DropdownMenuGroup>
</DropdownMenuContent>
</DropdownMenu>
);
},
enableSorting: false,
enableHiding: false,
},
];
}

View file

@ -25,7 +25,7 @@ import {
} from '@/components/ui/form';
import { Input } from '@/components/ui/input';
import { TPessoaSchema } from '../../../schemas/TPessoaFisicaSchema';
import { TPessoaSchema } from '../../../schemas/TPessoa/TPessoaSchema';
import LoadingButton from '@/app/_components/loadingButton/LoadingButton';
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
import { HouseIcon, IdCardIcon, UserIcon } from 'lucide-react';

View file

@ -0,0 +1,27 @@
'use client';
import { DataTable } from '@/app/_components/dataTable/DataTable';
import TPessoaJuridicaColumns from './TPessoaJuridicaColumns';
import TPessoaJuridicaTableInterface from '@/packages/administrativo/interfaces/TPessoa/TPessoaJuridica/TPessoaJuridicaTableInterface';
/**
* Componente principal da tabela
*/
export default function TPessoaJuridicaTable({
data,
onEdit,
onDelete,
}: TPessoaJuridicaTableInterface) {
const columns = TPessoaJuridicaColumns(onEdit, onDelete);
return (
<div>
<DataTable
data={data}
columns={columns}
filterColumn="nome_completo"
filterPlaceholder="Buscar por nome ou email..."
/>
</div>
);
}

View file

@ -1,205 +0,0 @@
'use client';
import { Button } from '@/components/ui/button';
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuGroup,
DropdownMenuItem,
DropdownMenuSeparator,
DropdownMenuTrigger,
} from '@/components/ui/dropdown-menu';
import { ArrowUpDownIcon, EllipsisIcon, PencilIcon, Trash2Icon } from 'lucide-react';
import { ColumnDef } from '@tanstack/react-table';
import GetNameInitials from '@/actions/text/GetNameInitials';
import { DataTable } from '@/app/_components/dataTable/DataTable';
import TPessoaInterface from '../../../interfaces/TPessoaInterface';
import { FormatCPF } from '@/actions/CPF/FormatCPF';
import { FormatPhone } from '@/actions/phone/FormatPhone';
import { FormatDateTime } from '@/actions/dateTime/FormatDateTime';
import empty from '@/actions/validations/empty';
import { FormatCNPJ } from '@/actions/CNPJ/FormatCNPJ';
// Tipagem das props
interface TPessoaJuridicaTableProps {
data: TPessoaInterface[];
onEdit: (item: TPessoaInterface, isEditingFormStatus: boolean) => void;
onDelete: (item: TPessoaInterface, isEditingFormStatus: boolean) => void;
}
/**
* Função para criar a definição das colunas da tabela
*/
function createPessoaColumns(
onEdit: (item: TPessoaInterface, isEditingFormStatus: boolean) => void,
onDelete: (item: TPessoaInterface, isEditingFormStatus: boolean) => void,
): ColumnDef<TPessoaInterface>[] {
return [
// ID
{
accessorKey: 'pessoa_id',
header: ({ column }) => (
<Button
variant="ghost"
onClick={() => column.toggleSorting(column.getIsSorted() === 'asc')}
>
# <ArrowUpDownIcon className="ml-1 h-4 w-4" />
</Button>
),
cell: ({ row }) => Number(row.getValue('pessoa_id')),
enableSorting: false,
},
// Nome / Email / Foto
{
id: 'nome_completo',
accessorFn: (row) => row,
header: ({ column }) => (
<Button
variant="ghost"
onClick={() => column.toggleSorting(column.getIsSorted() === 'asc')}
>
Nome / Email <ArrowUpDownIcon className="ml-1 h-4 w-4 cursor-pointer" />
</Button>
),
cell: ({ row }) => {
const pessoa = row.original;
return (
<div className="flex items-center gap-3">
{/* 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>
);
},
sortingFn: (a, b) =>
(a.original.nome?.toLowerCase() || '').localeCompare(b.original.nome?.toLowerCase() || ''),
},
// CPF
{
accessorKey: 'cpf_cnpj',
header: ({ column }) => (
<Button
variant="ghost"
onClick={() => column.toggleSorting(column.getIsSorted() === 'asc')}
>
CNPJ <ArrowUpDownIcon className="ml-1 h-4 w-4 cursor-pointer" />
</Button>
),
cell: ({ row }) => FormatCNPJ(row.getValue('cpf_cnpj')),
},
// Telefone
{
accessorKey: 'telefone',
header: ({ column }) => (
<Button
variant="ghost"
onClick={() => column.toggleSorting(column.getIsSorted() === 'asc')}
>
Telefone <ArrowUpDownIcon className="ml-1 h-4 w-4 cursor-pointer" />
</Button>
),
cell: ({ row }) => FormatPhone(row.getValue('telefone')),
},
// Cidade / UF
{
id: 'cidade_uf',
accessorFn: (row) => `${row.cidade}/${row.uf}`,
header: ({ column }) => (
<Button
variant="ghost"
onClick={() => column.toggleSorting(column.getIsSorted() === 'asc')}
>
Cidade/UF <ArrowUpDownIcon className="ml-1 h-4 w-4 cursor-pointer" />
</Button>
),
cell: ({ row }) => <span>{row.getValue('cidade_uf') || '-'}</span>,
sortingFn: (a, b) =>
`${a.original.cidade}/${a.original.uf}`
.toLowerCase()
.localeCompare(`${b.original.cidade}/${b.original.uf}`.toLowerCase()),
},
// Data de cadastro
{
accessorKey: 'data_cadastro',
header: ({ column }) => (
<Button
variant="ghost"
onClick={() => column.toggleSorting(column.getIsSorted() === 'asc')}
>
Cadastro <ArrowUpDownIcon className="ml-1 h-4 w-4 cursor-pointer" />
</Button>
),
cell: ({ row }) => FormatDateTime(row.getValue('data_cadastro')),
sortingFn: 'datetime',
},
// Ações
{
id: 'actions',
header: 'Ações',
cell: ({ row }) => {
const pessoa = row.original;
return (
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="ghost" size="icon" className="cursor-pointer">
<EllipsisIcon />
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent side="left" align="start">
<DropdownMenuGroup>
<DropdownMenuItem className="cursor-pointer" onSelect={() => onEdit(pessoa, true)}>
<PencilIcon className="mr-2 h-4 w-4" />
Editar
</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuItem
className="cursor-pointer text-red-600"
onSelect={() => onDelete(pessoa, true)}
>
<Trash2Icon className="mr-2 h-4 w-4" />
Remover
</DropdownMenuItem>
</DropdownMenuGroup>
</DropdownMenuContent>
</DropdownMenu>
);
},
enableSorting: false,
enableHiding: false,
},
];
}
/**
* Componente principal da tabela
*/
export default function TPessoaJuridicaTable({
data,
onEdit,
onDelete,
}: TPessoaJuridicaTableProps) {
const columns = createPessoaColumns(onEdit, onDelete);
return (
<div>
<DataTable
data={data}
columns={columns}
filterColumn="nome_completo"
filterPlaceholder="Buscar por nome ou email..."
/>
</div>
);
}

View file

@ -25,7 +25,7 @@ import {
} from '@/components/ui/form';
import { Input } from '@/components/ui/input';
import { TPessoaSchema } from '../../schemas/TPessoaFisicaSchema';
import { TPessoaSchema } from '../../schemas/TPessoa/TPessoaSchema';
import LoadingButton from '@/app/_components/loadingButton/LoadingButton';
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
import {
@ -62,8 +62,8 @@ import {
} from '@/components/ui/command';
import { cn } from '@/lib/utils';
import { useTPessoaIndexHook } from '../../hooks/t_pessoa/useTPessoaIndexHook';
import TPessoaTable from '../t_pessoa/fisica/TPessoaFisicaTable';
import TPessoaInterface from '../../interfaces/TPessoaInterface';
import TPessoaTable from '../TPessoa/TPessoaFisica/TPessoaFisicaTable';
import TPessoaInterface from '../../interfaces/TPessoa/TPessoaInterface';
import { ColumnDef } from '@tanstack/react-table';
import GetNameInitials from '@/actions/text/GetNameInitials';
import empty from '@/actions/validations/empty';

View file

@ -3,7 +3,7 @@
import React, { useEffect, useState, useCallback } from 'react';
import Loading from '@/app/_components/loading/loading';
import TPessoaForm from '../t_pessoa/fisica/TPessoaFisicaForm';
import TPessoaForm from '../TPessoa/TPessoaFisica/TPessoaFisicaForm';
import { useTPessoaIndexHook } from '../../hooks/t_pessoa/useTPessoaIndexHook';
import { useTPessoaSaveHook } from '../../hooks/t_pessoa/useTPessoaSaveHook';
@ -12,7 +12,7 @@ import { useTPessoaDeleteHook } from '../../hooks/t_pessoa/useTPessoaDeleteHook'
import ConfirmDialog from '@/app/_components/confirm_dialog/ConfirmDialog';
import { useConfirmDialog } from '@/app/_components/confirm_dialog/useConfirmDialog';
import TPessoaInterface from '../../interfaces/TPessoaInterface';
import TPessoaInterface from '../../interfaces/TPessoa/TPessoaInterface';
import TPessoaRepresentanteTable from './TPessoaRepresentanteTable';
import { useTPessoaRepresentanteIndexHook } from '../../hooks/t_pessoa_representante/useTPessoaRepresentanteIndexHook';
import { Button } from '@/components/ui/button';

View file

@ -16,7 +16,7 @@ import { ColumnDef } from '@tanstack/react-table';
import GetNameInitials from '@/actions/text/GetNameInitials';
import { DataTable } from '@/app/_components/dataTable/DataTable';
import TPessoaInterface from '../../interfaces/TPessoaInterface';
import TPessoaInterface from '../../interfaces/TPessoa/TPessoaInterface';
import { FormatCPF } from '@/actions/CPF/FormatCPF';
import { FormatPhone } from '@/actions/phone/FormatPhone';
import empty from '@/actions/validations/empty';

View file

@ -0,0 +1,16 @@
// hooks/useTPessoaForm.ts
import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { TPessoaFormValues, TPessoaSchema } from "@/packages/administrativo/schemas/TPessoa/TPessoaSchema";
// Hook customizado
export function useTPessoaForm(defaults?: Partial<TPessoaFormValues>) {
return useForm<TPessoaFormValues>({
resolver: zodResolver(TPessoaSchema),
defaultValues: {
nome: "",
pessoa_id: 0,
...defaults, // sobrescreve valores iniciais se forem passados
},
});
}

View file

@ -1,5 +1,5 @@
import { useResponse } from '@/app/_response/ResponseContext';
import TPessoaJuridicaInterface from '../../../interfaces/TPessoaJuridicaInterface';
import TPessoaJuridicaInterface from '../../../interfaces/TPessoa/TPessoaJuridica/TPessoaJuridicaInterface';
import { TCensecDeleteService } from '../../../../../app/(protected)/(cadastros)/cadastros/_services/t_censec/TCensecDeleteService';
export const useTPessoaJuridicaDeleteHook = () => {

View file

@ -1,7 +1,7 @@
import { useResponse } from '@/app/_response/ResponseContext';
import { TPessoaJuridicaIndexService } from '../../../services/t_pessoa/juridica/TPessoaJuridicaIndexService';
import { useState } from 'react';
import TPessoaJuridicaInterface from '../../../interfaces/TPessoaJuridicaInterface';
import TPessoaJuridicaInterface from '../../../interfaces/TPessoa/TPessoaJuridica/TPessoaJuridicaInterface';
export const useTPessoaJuridicaIndexHook = () => {
const { setResponse } = useResponse();

View file

@ -2,7 +2,7 @@
import { useResponse } from '@/app/_response/ResponseContext';
import { useState } from 'react';
import TPessoaInterface from '../../../interfaces/TPessoaInterface';
import TPessoaInterface from '../../../interfaces/TPessoa/TPessoaInterface';
import { TCensecSaveService } from '../../../../../app/(protected)/(cadastros)/cadastros/_services/t_censec/TCensecSaveService';
export const useTPessoaJuridicaSaveHook = () => {

View file

@ -1,5 +1,5 @@
import { useResponse } from '@/app/_response/ResponseContext';
import TPessoaInterface from '../../interfaces/TPessoaInterface';
import TPessoaInterface from '../../interfaces/TPessoa/TPessoaInterface';
import { TCensecDeleteService } from '../../../../app/(protected)/(cadastros)/cadastros/_services/t_censec/TCensecDeleteService';
export const useTPessoaDeleteHook = () => {

View file

@ -1,7 +1,7 @@
import { useResponse } from '@/app/_response/ResponseContext';
import { TPessoaIndexService } from '../../services/t_pessoa/TPessoaIndexService';
import { useState } from 'react';
import TPessoaInterface from '../../interfaces/TPessoaInterface';
import TPessoaInterface from '../../interfaces/TPessoa/TPessoaInterface';
export const useTPessoaIndexHook = () => {
const { setResponse } = useResponse();

View file

@ -2,7 +2,7 @@
import { useResponse } from '@/app/_response/ResponseContext';
import { useState } from 'react';
import TPessoaInterface from '../../interfaces/TPessoaInterface';
import TPessoaInterface from '../../interfaces/TPessoa/TPessoaInterface';
import { TCensecSaveService } from '../../../../app/(protected)/(cadastros)/cadastros/_services/t_censec/TCensecSaveService';
export const useTPessoaSaveHook = () => {

View file

@ -1,5 +1,5 @@
import { useResponse } from '@/app/_response/ResponseContext';
import TPessoaInterface from '../../interfaces/TPessoaInterface';
import TPessoaInterface from '../../interfaces/TPessoa/TPessoaInterface';
import { TCensecDeleteService } from '../../../../app/(protected)/(cadastros)/cadastros/_services/t_censec/TCensecDeleteService';
export const useTPessoaDeleteHook = () => {

View file

@ -1,7 +1,7 @@
import { useResponse } from '@/app/_response/ResponseContext';
import { TPessoaIndexService } from '../../services/t_pessoa/TPessoaIndexService';
import { useState } from 'react';
import TPessoaInterface from '../../interfaces/TPessoaInterface';
import TPessoaInterface from '../../interfaces/TPessoa/TPessoaInterface';
import { TPessoaRepresentanteIndexData } from '../../data/TPessoaRepresentante/TPessoaRepresentanteIndexData';
export const useTPessoaRepresentanteIndexHook = () => {

View file

@ -2,7 +2,7 @@
import { useResponse } from '@/app/_response/ResponseContext';
import { useState } from 'react';
import TPessoaInterface from '../../interfaces/TPessoaInterface';
import TPessoaInterface from '../../interfaces/TPessoa/TPessoaInterface';
import { TCensecSaveService } from '../../../../app/(protected)/(cadastros)/cadastros/_services/t_censec/TCensecSaveService';
export const useTPessoaSaveHook = () => {

View file

@ -0,0 +1,9 @@
import { TPessoaFisicaFormValues } from "../../../schemas/TPessoa/TPessoaFisicaSchema";
export default interface TPessoaFisicaFormInterface {
isOpen: boolean;
data: TPessoaFisicaFormValues | null;
onClose: (item: null, isFormStatus: boolean) => void;
onSave: (data: TPessoaFisicaFormValues) => void;
buttonIsLoading: boolean;
}

View file

@ -0,0 +1,33 @@
import TPessoaInterface from "../TPessoaInterface";
export default interface TPessoaFisicaInterface extends TPessoaInterface {
nacionalidade?: string;
tb_documentotipo_id?: number;
tb_profissao_id?: number;
tb_estadocivil_id?: number;
nome_pai?: string;
nome_mae?: string;
data_nascimento?: string;
sexo?: string;
tb_regimecomunhao_id?: number;
pessoa_conjuge_id?: number;
documento_expedicao?: string;
documento_validade?: string;
cert_casamento_numero?: string;
cert_casamento_folha?: string;
cert_casamento_livro?: string;
cert_casamento_cartorio?: string;
cert_casamento_data?: string;
cert_casamento_lei?: string;
pessoa_conjuge_nome?: string;
estrangeiro_nat?: string;
estrangeiro_nat_tb_pais_id?: number;
estrangeiro_res_tb_pais_id?: number;
estrangeiro_res?: string;
documento_orgao?: string;
documento_uf?: string;
uf_residencia?: string;
deficiencias?: string;
grau_instrucao?: string;
cidade_nat_id?: number;
}

View file

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

View file

@ -0,0 +1,32 @@
export default interface TPessoaInterface {
pessoa_id?: number;
pessoa_tipo?: string;
nome?: string;
documento?: string;
data_cadastro?: string;
naturalidade?: string;
telefone?: string;
endereco?: string;
cidade?: string;
uf?: string;
email?: string;
documento_numero?: string;
bairro?: string;
cep?: string;
observacao?: string;
cpf_cnpj?: string;
cpf_terceiro?: string;
texto?: string;
ddd?: number;
municipio_id?: number;
enviado_cnncnb?: boolean;
data_auteracao?: string;
data_envioccn?: string;
ccnregistros_id?: number;
observacao_envioccn?: string;
observacao_envio_ccn?: string;
tb_tipologradouro_id?: number;
unidade?: string;
numero_end?: string;
foto?: string;
}

View file

@ -0,0 +1,9 @@
import TPessoaJuridicaInterface from "./TPessoaJuridicaInterface";
export default interface TPessoaJuridicaFormInterface {
isOpen: boolean;
data: TPessoaJuridicaInterface | null;
onClose: (item: null, isFormStatus: boolean) => void;
onSave: (data: TPessoaJuridicaInterface) => void;
buttonIsLoading: boolean;
}

View file

@ -0,0 +1,12 @@
import TPessoaInterface from "../TPessoaInterface";
export default interface TPessoaJuridicaInterface extends TPessoaInterface {
razao_social?: string;
nome_fantasia?: string;
inscricao_estadual?: string;
inscricao_municipal?: string;
capital_social?: number;
data_abertura?: string;
cnae_principal?: string;
cnae_secundario?: string[];
}

View file

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

View file

@ -1,63 +0,0 @@
export default interface TPessoaInterface {
pessoa_id?: number;
pessoa_tipo?: string;
nome?: string;
nacionalidade?: string;
documento?: string;
tb_documentotipo_id?: number;
tb_profissao_id?: number;
tb_estadocivil_id?: number;
nome_pai?: string;
nome_mae?: string;
data_cadastro?: string; // ou Date
naturalidade?: string;
telefone?: string;
endereco?: string;
cidade?: string;
uf?: string;
data_nascimento?: string; // ou Date
sexo?: string;
tb_regimecomunhao_id?: number;
pessoa_conjuge_id?: number;
email?: string;
documento_numero?: string;
bairro?: string;
cep?: string;
documento_expedicao?: string; // ou Date
documento_validade?: string; // ou Date
observacao?: string;
cpf_cnpj?: string;
cpf_terceiro?: string;
nome_fantasia?: string;
texto?: string;
ddd?: number;
cert_casamento_numero?: string;
cert_casamento_folha?: string;
cert_casamento_livro?: string;
cert_casamento_cartorio?: string;
cert_casamento_data?: string; // ou Date
cert_casamento_lei?: string;
pessoa_conjuge_nome?: string;
estrangeiro_nat?: string;
estrangeiro_nat_tb_pais_id?: number;
estrangeiro_res_tb_pais_id?: number;
estrangeiro_res?: string;
municipio_id?: number;
documento_orgao?: string;
documento_uf?: string;
uf_residencia?: string;
inscricao_municipal?: string;
enviado_cnncnb?: boolean;
data_auteracao?: string; // ou Date
data_envioccn?: string; // ou Date
ccnregistros_id?: number;
observacao_envioccn?: string;
observacao_envio_ccn?: string;
deficiencias?: string;
grau_instrucao?: string;
cidade_nat_id?: number;
tb_tipologradouro_id?: number;
unidade?: string;
numero_end?: string;
foto?: string;
}

View file

@ -1,63 +0,0 @@
export default interface TPessoaJuridicaInterface {
pessoa_id?: number;
pessoa_tipo?: string;
nome?: string;
nacionalidade?: string;
documento?: string;
tb_documentotipo_id?: number;
tb_profissao_id?: number;
tb_estadocivil_id?: number;
nome_pai?: string;
nome_mae?: string;
data_cadastro?: string; // ou Date
naturalidade?: string;
telefone?: string;
endereco?: string;
cidade?: string;
uf?: string;
data_nascimento?: string; // ou Date
sexo?: string;
tb_regimecomunhao_id?: number;
pessoa_conjuge_id?: number;
email?: string;
documento_numero?: string;
bairro?: string;
cep?: string;
documento_expedicao?: string; // ou Date
documento_validade?: string; // ou Date
observacao?: string;
cpf_cnpj?: string;
cpf_terceiro?: string;
nome_fantasia?: string;
texto?: string;
ddd?: number;
cert_casamento_numero?: string;
cert_casamento_folha?: string;
cert_casamento_livro?: string;
cert_casamento_cartorio?: string;
cert_casamento_data?: string; // ou Date
cert_casamento_lei?: string;
pessoa_conjuge_nome?: string;
estrangeiro_nat?: string;
estrangeiro_nat_tb_pais_id?: number;
estrangeiro_res_tb_pais_id?: number;
estrangeiro_res?: string;
municipio_id?: number;
documento_orgao?: string;
documento_uf?: string;
uf_residencia?: string;
inscricao_municipal?: string;
enviado_cnncnb?: boolean;
data_auteracao?: string; // ou Date
data_envioccn?: string; // ou Date
ccnregistros_id?: number;
observacao_envioccn?: string;
observacao_envio_ccn?: string;
deficiencias?: string;
grau_instrucao?: string;
cidade_nat_id?: number;
tb_tipologradouro_id?: number;
unidade?: string;
numero_end?: string;
foto?: string;
}

View file

@ -1,5 +0,0 @@
export default interface TPessoaJuridicaInterface {
pessoa_representante_id: number;
nome: string;
tipo: string;
}

View file

@ -0,0 +1,36 @@
import { TPessoaSchema } from "./TPessoaSchema";
import z from "zod";
export const TPessoaFisicaSchema = TPessoaSchema.extend({
nacionalidade: z.string().optional(),
tb_documentotipo_id: z.number().optional(),
tb_profissao_id: z.number().optional(),
tb_estadocivil_id: z.number().optional(),
nome_pai: z.string().optional(),
nome_mae: z.string().optional(),
data_nascimento: z.string().optional(),
sexo: z.string().optional(),
tb_regimecomunhao_id: z.number().optional(),
pessoa_conjuge_id: z.number().optional(),
documento_expedicao: z.string().optional(),
documento_validade: z.string().optional(),
cert_casamento_numero: z.string().optional(),
cert_casamento_folha: z.string().optional(),
cert_casamento_livro: z.string().optional(),
cert_casamento_cartorio: z.string().optional(),
cert_casamento_data: z.string().optional(),
cert_casamento_lei: z.string().optional(),
pessoa_conjuge_nome: z.string().optional(),
estrangeiro_nat: z.string().optional(),
estrangeiro_nat_tb_pais_id: z.number().optional(),
estrangeiro_res_tb_pais_id: z.number().optional(),
estrangeiro_res: z.string().optional(),
documento_orgao: z.string().optional(),
documento_uf: z.string().optional(),
uf_residencia: z.string().optional(),
deficiencias: z.string().optional(),
grau_instrucao: z.string().optional(),
cidade_nat_id: z.number().optional(),
});
export type TPessoaFisicaFormValues = z.infer<typeof TPessoaFisicaSchema>;

View file

@ -0,0 +1,15 @@
import { TPessoaSchema } from "./TPessoaSchema";
import z from "zod";
export const TPessoaJuridicaSchema = TPessoaSchema.extend({
razao_social: z.string().min(1, "Razão social é obrigatória"),
nome_fantasia: z.string().optional(),
inscricao_estadual: z.string().optional(),
inscricao_municipal: z.string().optional(),
capital_social: z.number().optional(),
data_abertura: z.string().optional(),
cnae_principal: z.string().optional(),
cnae_secundario: z.array(z.string()).optional(),
});
export type TPessoaJuridicaFormValues = z.infer<typeof TPessoaJuridicaSchema>;

View file

@ -0,0 +1,33 @@
import z from 'zod';
export const TPessoaSchema = z.object({
pessoa_id: z.number().optional(),
pessoa_tipo: z.string().optional(),
nome: z.string().min(1, 'O campo deve ser preenchido').max(120, 'O nome excede 120 caracteres'),
documento: z.string().optional(),
data_cadastro: z.string().optional(),
telefone: z.string().optional(),
endereco: z.string().optional(),
cidade: z.string().optional(),
uf: z.string().optional(),
email: z.string().email().optional(),
documento_numero: z.string().optional(),
bairro: z.string().optional(),
cep: z.string().optional(),
observacao: z.string().optional(),
cpf_cnpj: z.string().optional(),
cpf_terceiro: z.string().optional(),
texto: z.string().optional(),
ddd: z.number().optional(),
municipio_id: z.number().optional(),
enviado_cnncnb: z.boolean().optional(),
data_auteracao: z.string().optional(),
data_envioccn: z.string().optional(),
ccnregistros_id: z.number().optional(),
observacao_envioccn: z.string().optional(),
observacao_envio_ccn: z.string().optional(),
tb_tipologradouro_id: z.number().optional(),
unidade: z.string().optional(),
numero_end: z.string().optional(),
foto: z.string().optional(),
});

View file

@ -1,64 +0,0 @@
import z from 'zod';
export const TPessoaSchema = z.object({
pessoa_id: z.number().optional(),
pessoa_tipo: z.string().optional(),
nome: z.string().min(1, 'O campo deve ser preenchido').max(120, 'O nome excede 120 caracteres'),
nacionalidade: z.string().optional(),
documento: z.string().optional(),
tb_documentotipo_id: z.number().optional(),
tb_profissao_id: z.number().optional(),
tb_estadocivil_id: z.number().optional(),
nome_pai: z.string().optional(),
nome_mae: z.string().optional(),
data_cadastro: z.string().optional(), // ou z.string().datetime()
naturalidade: z.string().optional(),
telefone: z.string().optional(),
endereco: z.string().optional(),
cidade: z.string().optional(),
uf: z.string().optional(),
data_nascimento: z.string().optional(), // ou z.string().datetime()
sexo: z.string().optional(),
tb_regimecomunhao_id: z.number().optional(),
pessoa_conjuge_id: z.number().optional(),
email: z.string().email().optional(),
documento_numero: z.string().optional(),
bairro: z.string().optional(),
cep: z.string().optional(),
documento_expedicao: z.string().optional(), // ou z.string().datetime()
documento_validade: z.string().optional(), // ou z.string().datetime()
observacao: z.string().optional(),
cpf_cnpj: z.string().optional(),
cpf_terceiro: z.string().optional(),
nome_fantasia: z.string().optional(),
texto: z.string().optional(),
ddd: z.number().optional(),
cert_casamento_numero: z.string().optional(),
cert_casamento_folha: z.string().optional(),
cert_casamento_livro: z.string().optional(),
cert_casamento_cartorio: z.string().optional(),
cert_casamento_data: z.string().optional(), // ou z.string().datetime()
cert_casamento_lei: z.string().optional(),
pessoa_conjuge_nome: z.string().optional(),
estrangeiro_nat: z.string().optional(),
estrangeiro_nat_tb_pais_id: z.number().optional(),
estrangeiro_res_tb_pais_id: z.number().optional(),
estrangeiro_res: z.string().optional(),
municipio_id: z.number().optional(),
documento_orgao: z.string().optional(),
documento_uf: z.string().optional(),
uf_residencia: z.string().optional(),
inscricao_municipal: z.string().optional(),
enviado_cnncnb: z.boolean().optional(),
data_auteracao: z.string().optional(), // ou z.string().datetime()
data_envioccn: z.string().optional(), // ou z.string().datetime()
ccnregistros_id: z.number().optional(),
observacao_envioccn: z.string().optional(),
observacao_envio_ccn: z.string().optional(),
deficiencias: z.string().optional(),
grau_instrucao: z.string().optional(),
cidade_nat_id: z.number().optional(),
tb_tipologradouro_id: z.number().optional(),
unidade: z.string().optional(),
numero_end: z.string().optional(),
});