[MVPTN-119] feat(CRUD): Cria cruds para manipular GEmolumento e GSeloGrupo
This commit is contained in:
parent
2340cee82a
commit
9b9f8b9454
48 changed files with 2089 additions and 2 deletions
|
|
@ -0,0 +1,9 @@
|
|||
import GEmolumentoIndex from "@/packages/administrativo/components/GEmolumento/GEmolumentoIndex";
|
||||
|
||||
export default function GEmolumentoPeriodoPage() {
|
||||
|
||||
return (
|
||||
<GEmolumentoIndex />
|
||||
);
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
import GSeloGrupoIndex from "@/packages/administrativo/components/GSeloGrupo/GSeloGrupoIndex";
|
||||
|
||||
export default function GSeloGrupoPage() {
|
||||
|
||||
return (
|
||||
<GSeloGrupoIndex />
|
||||
);
|
||||
|
||||
}
|
||||
|
|
@ -164,6 +164,14 @@ const data = {
|
|||
{
|
||||
title: "Financeiro/Periodo",
|
||||
url: "/administrativo/financeiro/periodos",
|
||||
},
|
||||
{
|
||||
title: "Financeiro/Emolumentos",
|
||||
url: "/administrativo/financeiro/emolumentos",
|
||||
},
|
||||
{
|
||||
title: "Selos/Grupos",
|
||||
url: "/administrativo/selos/grupos",
|
||||
}
|
||||
|
||||
],
|
||||
|
|
|
|||
|
|
@ -0,0 +1,78 @@
|
|||
import { ColumnDef } from '@tanstack/react-table';
|
||||
import { EllipsisIcon, PencilIcon, Trash2Icon } from 'lucide-react';
|
||||
|
||||
import { Button } from '@/components/ui/button';
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuGroup,
|
||||
DropdownMenuItem,
|
||||
DropdownMenuSeparator,
|
||||
DropdownMenuTrigger,
|
||||
} from '@/components/ui/dropdown-menu';
|
||||
import GetCapitalize from '@/shared/actions/text/GetCapitalize';
|
||||
import { SortableHeader } from '@/shared/components/dataTable/SortableHeader';
|
||||
|
||||
import GEmolumentoInterface from '../../interfaces/GEmolumento/GEmolumentoInterface';
|
||||
|
||||
export default function GEmolumentoColumns(
|
||||
onEdit: (item: GEmolumentoInterface, isEditingFormStatus: boolean) => void,
|
||||
onDelete: (item: GEmolumentoInterface, isEditingFormStatus: boolean) => void,
|
||||
): ColumnDef<GEmolumentoInterface>[] {
|
||||
return [
|
||||
// ID
|
||||
{
|
||||
accessorKey: 'emolumento_id',
|
||||
header: ({ column }) => SortableHeader('ID', column),
|
||||
cell: ({ row }) => Number(row.getValue('emolumento_id')),
|
||||
enableSorting: true,
|
||||
},
|
||||
|
||||
// Descrição
|
||||
{
|
||||
accessorKey: 'descricao',
|
||||
header: ({ column }) => SortableHeader('Descrição', column),
|
||||
cell: ({ row }) => GetCapitalize(String(row.getValue('descricao') || '')),
|
||||
},
|
||||
|
||||
// Ações
|
||||
{
|
||||
id: 'actions',
|
||||
header: 'Ações',
|
||||
cell: ({ row }) => {
|
||||
const natureza = row.original;
|
||||
|
||||
return (
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<Button variant="ghost" size="icon">
|
||||
<EllipsisIcon />
|
||||
</Button>
|
||||
</DropdownMenuTrigger>
|
||||
|
||||
<DropdownMenuContent side="left" align="start">
|
||||
<DropdownMenuGroup>
|
||||
<DropdownMenuItem onSelect={() => onEdit(natureza, true)}>
|
||||
<PencilIcon className="mr-2 h-4 w-4" />
|
||||
Editar
|
||||
</DropdownMenuItem>
|
||||
|
||||
<DropdownMenuSeparator />
|
||||
|
||||
<DropdownMenuItem
|
||||
className="text-red-600"
|
||||
onSelect={() => onDelete(natureza, true)}
|
||||
>
|
||||
<Trash2Icon className="mr-2 h-4 w-4" />
|
||||
Remover
|
||||
</DropdownMenuItem>
|
||||
</DropdownMenuGroup>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
);
|
||||
},
|
||||
enableSorting: false,
|
||||
enableHiding: false,
|
||||
},
|
||||
];
|
||||
}
|
||||
|
|
@ -0,0 +1,367 @@
|
|||
'use client';
|
||||
|
||||
import { HouseIcon, IdCardIcon } from 'lucide-react';
|
||||
import { 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 { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
|
||||
import { parseNumberInput } from '@/shared/actions/form/parseNumberInput';
|
||||
import { ResetFormIfData } from '@/shared/actions/form/ResetFormIfData';
|
||||
import LoadingButton from '@/shared/components/loadingButton/LoadingButton';
|
||||
import SistemasSelect from '@/shared/components/sistemas/SistemasSelect';
|
||||
import SituacoesSelect from '@/shared/components/situacoes/SituacoesSelect';
|
||||
import TipoEmolumentoSelect from '@/shared/components/tipoEmolumento/TipoAtoAnteriorSelect';
|
||||
|
||||
import { useGEmolumentoFormHook } from '../../hooks/GEmolumento/useGEmolumentoFormHook';
|
||||
import { GEmolumentoFormInterface } from '../../interfaces/GEmolumento/GEmolumentoFormInterface';
|
||||
import GSeloGrupoSelect from '../GSeloGrupo/GSeloGrupoSelect';
|
||||
|
||||
/**
|
||||
* Formulário de cadastro/edição de Natureza
|
||||
* Baseado nos campos da tabela G_NATUREZA
|
||||
*/
|
||||
export default function GEmolumentoForm({
|
||||
isOpen,
|
||||
data,
|
||||
onClose,
|
||||
onSave,
|
||||
buttonIsLoading,
|
||||
}: GEmolumentoFormInterface) {
|
||||
const form = useGEmolumentoFormHook({});
|
||||
|
||||
// Atualiza o formulário quando recebe dados para edição
|
||||
useEffect(() => {
|
||||
ResetFormIfData(form, data);
|
||||
}, [data, form]);
|
||||
|
||||
function onError(error: any) {
|
||||
console.log('Erro no formulário:', error);
|
||||
}
|
||||
|
||||
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-2xl lg:max-w-2xl">
|
||||
<DialogHeader>
|
||||
<DialogTitle className="text-lg sm:text-xl">Emolumento</DialogTitle>
|
||||
<DialogDescription className="text-muted-foreground text-sm">
|
||||
Formulário de Emolumento
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
{/* Formulário principal */}
|
||||
<Form {...form}>
|
||||
<form onSubmit={form.handleSubmit(onSave, onError)} className="space-y-6">
|
||||
<Tabs defaultValue="geral" className="space-y-4">
|
||||
<TabsList className="flex w-full">
|
||||
<TabsTrigger className="flex-1 cursor-pointer text-center" value="geral">
|
||||
<HouseIcon className="me-1 inline" />
|
||||
Geral
|
||||
</TabsTrigger>
|
||||
<TabsTrigger className="flex-1 cursor-pointer text-center" value="registroImoveis">
|
||||
<IdCardIcon className="inline" />
|
||||
Registro de Imóveis
|
||||
</TabsTrigger>
|
||||
</TabsList>
|
||||
<TabsContent value="geral" className="space-y-4">
|
||||
{/* GRID MOBILE FIRST */}
|
||||
<div className="grid w-full grid-cols-12 gap-4">
|
||||
{/* Descrição */}
|
||||
<div className="col-span-12 sm:col-span-6 md:col-span-12">
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="descricao"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>Descrição</FormLabel>
|
||||
<FormControl>
|
||||
<Input {...field} type="text" />
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Tipo */}
|
||||
<div className="col-span-12 sm:col-span-4 md:col-span-6">
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="tipo"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>Tipo</FormLabel>
|
||||
<TipoEmolumentoSelect field={field} />
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Sistema ID */}
|
||||
<div className="col-span-12 sm:col-span-4 md:col-span-6">
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="sistema_id"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>Serventia</FormLabel>
|
||||
<SistemasSelect
|
||||
field={field}
|
||||
onChange={(e) => field.onChange(parseNumberInput(e))}
|
||||
/>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Selo Grupo ID */}
|
||||
<div className="col-span-12 sm:col-span-4 md:col-span-6">
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="selo_grupo_id"
|
||||
render={({ field }) => (
|
||||
<FormItem className='w-full'>
|
||||
<FormLabel>Selo Grupo</FormLabel>
|
||||
<GSeloGrupoSelect field={field} />
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Registro/Averbação */}
|
||||
<div className="col-span-12 sm:col-span-4 md:col-span-6">
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="reg_averb"
|
||||
render={({ field }) => (
|
||||
<FormItem className='w-full'>
|
||||
<FormLabel>Registro/Averbação</FormLabel>
|
||||
<Input {...field} type="text" maxLength={1} />
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Situação */}
|
||||
<div className="col-span-12 sm:col-span-6 md:col-span-6">
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="situacao"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>Situação</FormLabel>
|
||||
<SituacoesSelect field={field} />
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Tipo Objetivo */}
|
||||
<div className="col-span-12 sm:col-span-6 md:col-span-6">
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="tipo_objetivo"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>Tipo Objetivo</FormLabel>
|
||||
<Input {...field} type="text" maxLength={3} />
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Modelo Tag */}
|
||||
<div className="col-span-12 sm:col-span-6 md:col-span-6">
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="modelo_tag"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>Modelo Tag</FormLabel>
|
||||
<Input {...field} type="text" maxLength={3} />
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Código Nota ID */}
|
||||
<div className="col-span-12 sm:col-span-6 md:col-span-6">
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="codigo_nota_id"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>Código Nota</FormLabel>
|
||||
<FormControl>
|
||||
<Input {...field}
|
||||
type="number"
|
||||
step="0.01"
|
||||
onChange={(e) => field.onChange(parseNumberInput(e))}
|
||||
/>
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</TabsContent>
|
||||
<TabsContent value="registroImoveis" className="space-y-4">
|
||||
{/* Pré-Definido */}
|
||||
<div className="col-span-12 sm:col-span-4 md:col-span-6">
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="pre_definido"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>Pré-Definido</FormLabel>
|
||||
<Input {...field} type="text" maxLength={1} />
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
{/* Motivo Redução */}
|
||||
<div className="col-span-12 sm:col-span-8 md:col-span-6">
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="motivo_reducao"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>Motivo da Redução</FormLabel>
|
||||
<FormControl>
|
||||
<Input {...field} type="text" />
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
{/* Valor Máximo Certidão */}
|
||||
<div className="col-span-12 sm:col-span-6 md:col-span-6">
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="valor_maximo_certidao"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>Valor Máximo Certidão</FormLabel>
|
||||
<FormControl>
|
||||
<Input {...field}
|
||||
type="number"
|
||||
step="0.001"
|
||||
onChange={(e) => field.onChange(parseNumberInput(e))}
|
||||
/>
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
{/* Com Redução */}
|
||||
<div className="col-span-12 sm:col-span-4 md:col-span-6">
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="com_reducao"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>Com Redução</FormLabel>
|
||||
<Input {...field} type="text" maxLength={1} />
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
<div className="grid w-full grid-cols-12 gap-4">
|
||||
{/* Item DF */}
|
||||
<div className="col-span-12 sm:col-span-6 md:col-span-6">
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="item_df"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>Item DF</FormLabel>
|
||||
<Input {...field} type="text" maxLength={10} />
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
{/* Convênio CODHAB */}
|
||||
<div className="col-span-12 sm:col-span-6 md:col-span-6">
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="convenio_codhab"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>Convênio CODHAB</FormLabel>
|
||||
<Input {...field} type="text" maxLength={1} />
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
{/* Situação RI */}
|
||||
<div className="col-span-12 sm:col-span-6 md:col-span-6">
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="situacao_ri"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>Situação RI</FormLabel>
|
||||
<SituacoesSelect field={field} />
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</TabsContent>
|
||||
</Tabs>
|
||||
{/* Rodapé */}
|
||||
<DialogFooter className="mt-6 flex flex-col justify-end gap-2 sm:flex-row">
|
||||
<DialogClose asChild>
|
||||
<Button variant="outline" type="button">
|
||||
Cancelar
|
||||
</Button>
|
||||
</DialogClose>
|
||||
<LoadingButton
|
||||
text="Salvar"
|
||||
textLoading="Salvando..."
|
||||
type="submit"
|
||||
loading={buttonIsLoading}
|
||||
/>
|
||||
</DialogFooter>
|
||||
</form>
|
||||
</Form>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
);
|
||||
}
|
||||
|
|
@ -0,0 +1,161 @@
|
|||
'use client';
|
||||
|
||||
import { useEffect, useState, useCallback } from 'react';
|
||||
|
||||
|
||||
import { useGEmolumentoDeleteHook } from '@/packages/administrativo/hooks/GEmolumento/useGEmolumentoDeleteHook';
|
||||
import { useGEmolumentoIndexHook } from '@/packages/administrativo/hooks/GEmolumento/useGEmolumentoIndexHook';
|
||||
import { useGEmolumentoSaveHook } from '@/packages/administrativo/hooks/GEmolumento/useGEmolumentoSaveHook';
|
||||
import GEmolumentoInterface from '@/packages/administrativo/interfaces/GEmolumento/GEmolumentoInterface';
|
||||
import ConfirmDialog from '@/shared/components/confirmDialog/ConfirmDialog';
|
||||
import { useConfirmDialog } from '@/shared/components/confirmDialog/useConfirmDialog';
|
||||
import Loading from '@/shared/components/loading/loading';
|
||||
import Header from '@/shared/components/structure/Header';
|
||||
|
||||
import GEmolumentoForm from './GEmolumentoForm';
|
||||
import GEmolumentoTable from './GEmolumentoTable';
|
||||
|
||||
export default function GEmolumentoIndex() {
|
||||
|
||||
// Controle de estado do botão
|
||||
const [buttonIsLoading, setButtonIsLoading] = useState(false);
|
||||
|
||||
// Hooks para leitura e salvamento
|
||||
const { gGramatica, indexGEmolumento } = useGEmolumentoIndexHook();
|
||||
const { saveGEmolumento } = useGEmolumentoSaveHook();
|
||||
const { deleteGEmolumento } = useGEmolumentoDeleteHook();
|
||||
|
||||
// Estados
|
||||
const [selectedData, setSelectedData] = useState<GEmolumentoInterface | null>(null);
|
||||
const [isFormOpen, setIsFormOpen] = useState(false);
|
||||
|
||||
// Estado para saber qual item será deletado
|
||||
const [itemToDelete, setItemToDelete] = useState<GEmolumentoInterface | null>(null);
|
||||
|
||||
/**
|
||||
* Hook do modal de confirmação
|
||||
*/
|
||||
const { isOpen: isConfirmOpen, openDialog: openConfirmDialog, handleCancel } = useConfirmDialog();
|
||||
|
||||
/**
|
||||
* Abre o formulário no modo de edição ou criação
|
||||
*/
|
||||
const handleOpenForm = useCallback((data: GEmolumentoInterface | null) => {
|
||||
setSelectedData(data);
|
||||
setIsFormOpen(true);
|
||||
}, []);
|
||||
|
||||
/**
|
||||
* Fecha o formulário e limpa o andamento selecionado
|
||||
*/
|
||||
const handleCloseForm = useCallback(() => {
|
||||
setSelectedData(null);
|
||||
setIsFormOpen(false);
|
||||
}, []);
|
||||
|
||||
/**
|
||||
* Salva os dados do formulário
|
||||
*/
|
||||
const handleSave = useCallback(
|
||||
async (formData: GEmolumentoInterface) => {
|
||||
// Coloca o botão em estado de loading
|
||||
setButtonIsLoading(true);
|
||||
|
||||
// Aguarda salvar o registro
|
||||
await saveGEmolumento(formData);
|
||||
|
||||
// Remove o botão em estado de loading
|
||||
setButtonIsLoading(false);
|
||||
|
||||
// Atualiza a lista de dados
|
||||
indexGEmolumento();
|
||||
},
|
||||
[saveGEmolumento, indexGEmolumento, handleCloseForm],
|
||||
);
|
||||
|
||||
/**
|
||||
* Quando o usuário clica em "remover" na tabela
|
||||
*/
|
||||
const handleConfirmDelete = useCallback(
|
||||
(item: GEmolumentoInterface) => {
|
||||
// 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 deleteGEmolumento(itemToDelete);
|
||||
|
||||
// Atualiza a lista
|
||||
await indexGEmolumento();
|
||||
|
||||
// Limpa o item selecionado
|
||||
setItemToDelete(null);
|
||||
|
||||
// Fecha o modal
|
||||
handleCancel();
|
||||
}, [itemToDelete, indexGEmolumento, handleCancel]);
|
||||
|
||||
/**
|
||||
* Busca inicial dos dados
|
||||
*/
|
||||
useEffect(() => {
|
||||
indexGEmolumento();
|
||||
}, []);
|
||||
|
||||
/**
|
||||
* Tela de loading enquanto carrega os dados
|
||||
*/
|
||||
if (gGramatica?.length == 0) {
|
||||
return <Loading type={2} />;
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
{/* Cabeçalho */}
|
||||
<Header
|
||||
title={'Emolumentos'}
|
||||
description={'Emolumentos'}
|
||||
buttonText={'Novo emolumento'}
|
||||
buttonAction={() => {
|
||||
handleOpenForm(null);
|
||||
}}
|
||||
/>
|
||||
{/* Tabela de andamentos */}
|
||||
<GEmolumentoTable data={gGramatica} onEdit={handleOpenForm} onDelete={handleConfirmDelete} />
|
||||
{/* Modal de confirmação */}
|
||||
{isConfirmOpen && (
|
||||
<ConfirmDialog
|
||||
isOpen={isConfirmOpen}
|
||||
title="Confirmar exclusão"
|
||||
description="Atenção"
|
||||
message={`Deseja realmente excluir o valor "${itemToDelete?.descricao}"?`}
|
||||
confirmText="Sim, excluir"
|
||||
cancelText="Cancelar"
|
||||
onConfirm={handleDelete}
|
||||
onCancel={handleCancel}
|
||||
/>
|
||||
)}
|
||||
{/* Formulário de criação/edição */}
|
||||
{isFormOpen && (
|
||||
<GEmolumentoForm
|
||||
isOpen={isFormOpen}
|
||||
data={selectedData}
|
||||
onClose={handleCloseForm}
|
||||
onSave={handleSave}
|
||||
buttonIsLoading={buttonIsLoading}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
'use client';
|
||||
|
||||
import { DataTable } from '@/shared/components/dataTable/DataTable';
|
||||
|
||||
import GEmolumentoColumns from './GEmolumentoColumns';
|
||||
import GEmolumentoTableInterface from '../../interfaces/GEmolumento/GEmolumentoTableInterface';
|
||||
|
||||
/**
|
||||
* Componente principal da tabela de Naturezas
|
||||
*/
|
||||
export default function GEmolumentoTable({ data, onEdit, onDelete }: GEmolumentoTableInterface) {
|
||||
const columns = GEmolumentoColumns(onEdit, onDelete);
|
||||
return (
|
||||
<div>
|
||||
<DataTable
|
||||
data={data}
|
||||
columns={columns}
|
||||
filterColumn="descricao"
|
||||
filterPlaceholder="Buscar por descrição da natureza..."
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
@ -0,0 +1,78 @@
|
|||
import { ColumnDef } from '@tanstack/react-table';
|
||||
import { EllipsisIcon, PencilIcon, Trash2Icon } from 'lucide-react';
|
||||
|
||||
import { Button } from '@/components/ui/button';
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuGroup,
|
||||
DropdownMenuItem,
|
||||
DropdownMenuSeparator,
|
||||
DropdownMenuTrigger,
|
||||
} from '@/components/ui/dropdown-menu';
|
||||
import GetCapitalize from '@/shared/actions/text/GetCapitalize';
|
||||
import { SortableHeader } from '@/shared/components/dataTable/SortableHeader';
|
||||
|
||||
import GSeloGrupoInterface from '../../interfaces/GSeloGrupo/GSeloGrupoInterface';
|
||||
|
||||
export default function GSeloGrupoColumns(
|
||||
onEdit: (item: GSeloGrupoInterface, isEditingFormStatus: boolean) => void,
|
||||
onDelete: (item: GSeloGrupoInterface, isEditingFormStatus: boolean) => void,
|
||||
): ColumnDef<GSeloGrupoInterface>[] {
|
||||
return [
|
||||
// ID
|
||||
{
|
||||
accessorKey: 'selo_grupo_id',
|
||||
header: ({ column }) => SortableHeader('ID', column),
|
||||
cell: ({ row }) => Number(row.getValue('selo_grupo_id')),
|
||||
enableSorting: true,
|
||||
},
|
||||
|
||||
// Descrição
|
||||
{
|
||||
accessorKey: 'descricao',
|
||||
header: ({ column }) => SortableHeader('descricao', column),
|
||||
cell: ({ row }) => GetCapitalize(String(row.getValue('descricao') || '')),
|
||||
},
|
||||
|
||||
// Ações
|
||||
{
|
||||
id: 'actions',
|
||||
header: 'Ações',
|
||||
cell: ({ row }) => {
|
||||
const natureza = row.original;
|
||||
|
||||
return (
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<Button variant="ghost" size="icon">
|
||||
<EllipsisIcon />
|
||||
</Button>
|
||||
</DropdownMenuTrigger>
|
||||
|
||||
<DropdownMenuContent side="left" align="start">
|
||||
<DropdownMenuGroup>
|
||||
<DropdownMenuItem onSelect={() => onEdit(natureza, true)}>
|
||||
<PencilIcon className="mr-2 h-4 w-4" />
|
||||
Editar
|
||||
</DropdownMenuItem>
|
||||
|
||||
<DropdownMenuSeparator />
|
||||
|
||||
<DropdownMenuItem
|
||||
className="text-red-600"
|
||||
onSelect={() => onDelete(natureza, true)}
|
||||
>
|
||||
<Trash2Icon className="mr-2 h-4 w-4" />
|
||||
Remover
|
||||
</DropdownMenuItem>
|
||||
</DropdownMenuGroup>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
);
|
||||
},
|
||||
enableSorting: false,
|
||||
enableHiding: false,
|
||||
},
|
||||
];
|
||||
}
|
||||
|
|
@ -0,0 +1,301 @@
|
|||
'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 { ResetFormIfData } from '@/shared/actions/form/ResetFormIfData';
|
||||
import LoadingButton from '@/shared/components/loadingButton/LoadingButton';
|
||||
|
||||
import { useGSeloGrupoFormHook } from '../../hooks/GSeloGrupo/useGSeloGrupoFormHook';
|
||||
import { GSeloGrupoFormInterface } from '../../interfaces/GSeloGrupo/GSeloGrupoFormInterface';
|
||||
import SituacoesSelect from '@/shared/components/situacoes/SituacoesSelect';
|
||||
import ConfirmacaoSelect from '@/shared/components/confirmacao/ConfirmacaoSelect';
|
||||
import { parseNumberInput } from '@/shared/actions/form/parseNumberInput';
|
||||
import TipoCartorioSelect from '@/shared/components/tipoCartorio/TipoCartorioSelect';
|
||||
|
||||
/**
|
||||
* Formulário de cadastro/edição de Natureza
|
||||
* Baseado nos campos da tabela G_NATUREZA
|
||||
*/
|
||||
export default function GSeloGrupoForm({
|
||||
isOpen,
|
||||
data,
|
||||
onClose,
|
||||
onSave,
|
||||
buttonIsLoading,
|
||||
}: GSeloGrupoFormInterface) {
|
||||
const form = useGSeloGrupoFormHook({});
|
||||
|
||||
// Atualiza o formulário quando recebe dados para edição
|
||||
useEffect(() => {
|
||||
ResetFormIfData(form, data);
|
||||
}, [data, form]);
|
||||
|
||||
function onError(error: any) {
|
||||
console.log('Erro no formulário:', error);
|
||||
}
|
||||
|
||||
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-2xl lg:max-w-2xl">
|
||||
<DialogHeader>
|
||||
<DialogTitle className="text-lg sm:text-xl">Formulário de Gramática</DialogTitle>
|
||||
<DialogDescription className="text-muted-foreground text-sm">
|
||||
Formulário de Gramática
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
{/* Formulário principal */}
|
||||
<Form {...form}>
|
||||
<form onSubmit={form.handleSubmit(onSave, onError)} className="space-y-6">
|
||||
{/* GRID MOBILE FIRST */}
|
||||
<div className="grid w-full grid-cols-12 gap-4">
|
||||
{/* Código */}
|
||||
<div className="col-span-12 sm:col-span-6 md:col-span-6">
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="numero"
|
||||
render={({ field }) => (
|
||||
<FormItem className="col-span-1 sm:col-span-2">
|
||||
<FormLabel>Código</FormLabel>
|
||||
<FormControl>
|
||||
<Input
|
||||
{...field}
|
||||
type="number"
|
||||
/>
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
{/* Agrupador */}
|
||||
<div className="col-span-12 sm:col-span-6 md:col-span-6">
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="agrupador"
|
||||
render={({ field }) => (
|
||||
<FormItem className="col-span-1 sm:col-span-2">
|
||||
<FormLabel>Agrupador</FormLabel>
|
||||
<ConfirmacaoSelect field={field} />
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
{/* Descrição */}
|
||||
<div className="col-span-12 sm:col-span-6 md:col-span-12">
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="descricao"
|
||||
render={({ field }) => (
|
||||
<FormItem className="col-span-1 sm:col-span-2">
|
||||
<FormLabel>Descrição</FormLabel>
|
||||
<FormControl>
|
||||
<Input
|
||||
{...field}
|
||||
type="text"
|
||||
/>
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
{/* Descrição Completa */}
|
||||
<div className="col-span-12 sm:col-span-6 md:col-span-12">
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="descricao_completa"
|
||||
render={({ field }) => (
|
||||
<FormItem className="col-span-1 sm:col-span-2">
|
||||
<FormLabel>Descrição Completa</FormLabel>
|
||||
<FormControl>
|
||||
<Input
|
||||
{...field}
|
||||
type="text"
|
||||
/>
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
{/* Controle Automático */}
|
||||
<div className="col-span-12 sm:col-span-6 md:col-span-6">
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="controle_automatico"
|
||||
render={({ field }) => (
|
||||
<FormItem className="col-span-1 sm:col-span-2">
|
||||
<FormLabel>Controle Automático</FormLabel>
|
||||
<ConfirmacaoSelect field={field} />
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
{/* Código Conta */}
|
||||
<div className="col-span-12 sm:col-span-6 md:col-span-6">
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="codigo_conta"
|
||||
render={({ field }) => (
|
||||
<FormItem className="col-span-1 sm:col-span-2">
|
||||
<FormLabel>Código Conta</FormLabel>
|
||||
<FormControl>
|
||||
<Input
|
||||
{...field}
|
||||
type="number"
|
||||
onChange={(e) => field.onChange(parseNumberInput(e))}
|
||||
/>
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
{/* Selo Principal Inicial */}
|
||||
<div className="col-span-12 sm:col-span-6 md:col-span-6">
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="numero_principal_ini"
|
||||
render={({ field }) => (
|
||||
<FormItem className="col-span-1 sm:col-span-2">
|
||||
<FormLabel>Selo Principal Inicial</FormLabel>
|
||||
<FormControl>
|
||||
<Input
|
||||
{...field}
|
||||
type="number"
|
||||
onChange={(e) => field.onChange(parseNumberInput(e))}
|
||||
/>
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
{/* Selo Principal Final */}
|
||||
<div className="col-span-12 sm:col-span-6 md:col-span-6">
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="numero_principal_fim"
|
||||
render={({ field }) => (
|
||||
<FormItem className="col-span-1 sm:col-span-2">
|
||||
<FormLabel>Selo Principal Final</FormLabel>
|
||||
<FormControl>
|
||||
<Input
|
||||
{...field}
|
||||
type="number"
|
||||
onChange={(e) => field.onChange(parseNumberInput(e))}
|
||||
/>
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
{/* Grupos Principal */}
|
||||
<div className="col-span-12 sm:col-span-6 md:col-span-12">
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="grupos_principal"
|
||||
render={({ field }) => (
|
||||
<FormItem className="col-span-1 sm:col-span-2">
|
||||
<FormLabel>Grupos Principal</FormLabel>
|
||||
<FormControl>
|
||||
<Input
|
||||
{...field}
|
||||
type="text"
|
||||
/>
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
{/* Um por protocolo */}
|
||||
<div className="col-span-12 sm:col-span-6 md:col-span-6">
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="um_por_protocolo"
|
||||
render={({ field }) => (
|
||||
<FormItem className="col-span-1 sm:col-span-2">
|
||||
<FormLabel>Um por Protocolo</FormLabel>
|
||||
<ConfirmacaoSelect field={field} />
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
{/* Tipo Cartório */}
|
||||
<div className="col-span-12 sm:col-span-6 md:col-span-6">
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="tipo_cartorio"
|
||||
render={({ field }) => (
|
||||
<FormItem className="col-span-1 sm:col-span-2">
|
||||
<FormLabel>Tipo Cartório</FormLabel>
|
||||
<TipoCartorioSelect field={field} />
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
{/* Situação */}
|
||||
<div className="col-span-12 sm:col-span-6 md:col-span-12">
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="situacao"
|
||||
render={({ field }) => (
|
||||
<FormItem className="col-span-1 sm:col-span-2">
|
||||
<FormLabel>Situação</FormLabel>
|
||||
<SituacoesSelect field={field} />
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
{/* Rodapé */}
|
||||
<DialogFooter className="mt-6 flex flex-col justify-end gap-2 sm:flex-row">
|
||||
<DialogClose asChild>
|
||||
<Button variant="outline" type="button">
|
||||
Cancelar
|
||||
</Button>
|
||||
</DialogClose>
|
||||
<LoadingButton
|
||||
text="Salvar"
|
||||
textLoading="Salvando..."
|
||||
type="submit"
|
||||
loading={buttonIsLoading}
|
||||
/>
|
||||
</DialogFooter>
|
||||
</form>
|
||||
</Form>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
);
|
||||
}
|
||||
|
|
@ -0,0 +1,161 @@
|
|||
'use client';
|
||||
|
||||
import { useEffect, useState, useCallback } from 'react';
|
||||
|
||||
|
||||
import { useGSeloGrupoDeleteHook } from '@/packages/administrativo/hooks/GSeloGrupo/useGSeloGrupoDeleteHook';
|
||||
import { useGSeloGrupoIndexHook } from '@/packages/administrativo/hooks/GSeloGrupo/useGSeloGrupoIndexHook';
|
||||
import { useGSeloGrupoSaveHook } from '@/packages/administrativo/hooks/GSeloGrupo/useGSeloGrupoSaveHook';
|
||||
import GSeloGrupoInterface from '@/packages/administrativo/interfaces/GSeloGrupo/GSeloGrupoInterface';
|
||||
import ConfirmDialog from '@/shared/components/confirmDialog/ConfirmDialog';
|
||||
import { useConfirmDialog } from '@/shared/components/confirmDialog/useConfirmDialog';
|
||||
import Loading from '@/shared/components/loading/loading';
|
||||
import Header from '@/shared/components/structure/Header';
|
||||
|
||||
import GSeloGrupoForm from './GSeloGrupoForm';
|
||||
import GSeloGrupoTable from './GSeloGrupoTable';
|
||||
|
||||
export default function GSeloGrupoIndex() {
|
||||
|
||||
// Controle de estado do botão
|
||||
const [buttonIsLoading, setButtonIsLoading] = useState(false);
|
||||
|
||||
// Hooks para leitura e salvamento
|
||||
const { gSeloGrupo, indexGSeloGrupo } = useGSeloGrupoIndexHook();
|
||||
const { saveGSeloGrupo } = useGSeloGrupoSaveHook();
|
||||
const { deleteGSeloGrupo } = useGSeloGrupoDeleteHook();
|
||||
|
||||
// Estados
|
||||
const [selectedData, setSelectedData] = useState<GSeloGrupoInterface | null>(null);
|
||||
const [isFormOpen, setIsFormOpen] = useState(false);
|
||||
|
||||
// Estado para saber qual item será deletado
|
||||
const [itemToDelete, setItemToDelete] = useState<GSeloGrupoInterface | null>(null);
|
||||
|
||||
/**
|
||||
* Hook do modal de confirmação
|
||||
*/
|
||||
const { isOpen: isConfirmOpen, openDialog: openConfirmDialog, handleCancel } = useConfirmDialog();
|
||||
|
||||
/**
|
||||
* Abre o formulário no modo de edição ou criação
|
||||
*/
|
||||
const handleOpenForm = useCallback((data: GSeloGrupoInterface | null) => {
|
||||
setSelectedData(data);
|
||||
setIsFormOpen(true);
|
||||
}, []);
|
||||
|
||||
/**
|
||||
* Fecha o formulário e limpa o andamento selecionado
|
||||
*/
|
||||
const handleCloseForm = useCallback(() => {
|
||||
setSelectedData(null);
|
||||
setIsFormOpen(false);
|
||||
}, []);
|
||||
|
||||
/**
|
||||
* Salva os dados do formulário
|
||||
*/
|
||||
const handleSave = useCallback(
|
||||
async (formData: GSeloGrupoInterface) => {
|
||||
// Coloca o botão em estado de loading
|
||||
setButtonIsLoading(true);
|
||||
|
||||
// Aguarda salvar o registro
|
||||
await saveGSeloGrupo(formData);
|
||||
|
||||
// Remove o botão em estado de loading
|
||||
setButtonIsLoading(false);
|
||||
|
||||
// Atualiza a lista de dados
|
||||
indexGSeloGrupo();
|
||||
},
|
||||
[saveGSeloGrupo, indexGSeloGrupo, handleCloseForm],
|
||||
);
|
||||
|
||||
/**
|
||||
* Quando o usuário clica em "remover" na tabela
|
||||
*/
|
||||
const handleConfirmDelete = useCallback(
|
||||
(item: GSeloGrupoInterface) => {
|
||||
// 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 deleteGSeloGrupo(itemToDelete);
|
||||
|
||||
// Atualiza a lista
|
||||
await indexGSeloGrupo();
|
||||
|
||||
// Limpa o item selecionado
|
||||
setItemToDelete(null);
|
||||
|
||||
// Fecha o modal
|
||||
handleCancel();
|
||||
}, [itemToDelete, indexGSeloGrupo, handleCancel]);
|
||||
|
||||
/**
|
||||
* Busca inicial dos dados
|
||||
*/
|
||||
useEffect(() => {
|
||||
indexGSeloGrupo();
|
||||
}, []);
|
||||
|
||||
/**
|
||||
* Tela de loading enquanto carrega os dados
|
||||
*/
|
||||
if (gSeloGrupo?.length == 0) {
|
||||
return <Loading type={2} />;
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
{/* Cabeçalho */}
|
||||
<Header
|
||||
title={'Grupos de Selos'}
|
||||
description={'Grupos de Selos'}
|
||||
buttonText={'Novo grupo'}
|
||||
buttonAction={() => {
|
||||
handleOpenForm(null);
|
||||
}}
|
||||
/>
|
||||
{/* Tabela de andamentos */}
|
||||
<GSeloGrupoTable data={gSeloGrupo} onEdit={handleOpenForm} onDelete={handleConfirmDelete} />
|
||||
{/* Modal de confirmação */}
|
||||
{isConfirmOpen && (
|
||||
<ConfirmDialog
|
||||
isOpen={isConfirmOpen}
|
||||
title="Confirmar exclusão"
|
||||
description="Atenção"
|
||||
message={`Deseja realmente excluir o grupo "${itemToDelete?.descricao}"?`}
|
||||
confirmText="Sim, excluir"
|
||||
cancelText="Cancelar"
|
||||
onConfirm={handleDelete}
|
||||
onCancel={handleCancel}
|
||||
/>
|
||||
)}
|
||||
{/* Formulário de criação/edição */}
|
||||
{isFormOpen && (
|
||||
<GSeloGrupoForm
|
||||
isOpen={isFormOpen}
|
||||
data={selectedData}
|
||||
onClose={handleCloseForm}
|
||||
onSave={handleSave}
|
||||
buttonIsLoading={buttonIsLoading}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
@ -0,0 +1,115 @@
|
|||
'use client';
|
||||
|
||||
import { CheckIcon, ChevronsUpDownIcon } from 'lucide-react';
|
||||
import React, { useState, useEffect, useCallback, useMemo } 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 { useGSeloGrupoIndexHook } from '@/packages/administrativo/hooks/GSeloGrupo/useGSeloGrupoIndexHook';
|
||||
import GetCapitalize from '@/shared/actions/text/GetCapitalize';
|
||||
|
||||
import GTBairroSelectInterface from '../../interfaces/GSeloGrupo/GSeloGrupoSelectInterace';
|
||||
|
||||
export default function GSeloGrupoSelect({ field }: GTBairroSelectInterface) {
|
||||
const [open, setOpen] = useState(false);
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const { gSeloGrupo = [], indexGSeloGrupo } = useGSeloGrupoIndexHook();
|
||||
|
||||
/**
|
||||
* Efeito para buscar os dados apenas uma vez.
|
||||
* useCallback evita recriação desnecessária da função.
|
||||
*/
|
||||
const loadData = useCallback(async () => {
|
||||
if (gSeloGrupo.length) return;
|
||||
setIsLoading(true);
|
||||
await indexGSeloGrupo();
|
||||
setIsLoading(false);
|
||||
}, [gSeloGrupo.length, indexGSeloGrupo]);
|
||||
|
||||
useEffect(() => {
|
||||
loadData();
|
||||
}, [loadData]);
|
||||
|
||||
/**
|
||||
* Memoriza o bairro selecionado para evitar reprocessamentos.
|
||||
*/
|
||||
const selected = useMemo(
|
||||
() => gSeloGrupo.find((b) => String(b.selo_grupo_id) === String(field?.value ?? '')),
|
||||
[gSeloGrupo, field?.value],
|
||||
);
|
||||
|
||||
/**
|
||||
* Manipulador de seleção com verificação segura.
|
||||
*/
|
||||
const handleSelect = useCallback(
|
||||
(bairroId: string | number) => {
|
||||
if (!field?.onChange) return;
|
||||
field.onChange(bairroId);
|
||||
setOpen(false);
|
||||
},
|
||||
[field],
|
||||
);
|
||||
|
||||
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 bairro..." disabled={isLoading} />
|
||||
<CommandList>
|
||||
<CommandEmpty>
|
||||
{isLoading ? 'Carregando...' : 'Nenhum resultado encontrado.'}
|
||||
</CommandEmpty>
|
||||
<CommandGroup>
|
||||
{gSeloGrupo.map((item) => (
|
||||
<CommandItem
|
||||
key={item.selo_grupo_id}
|
||||
value={item.descricao?.toLowerCase() ?? ''}
|
||||
onSelect={() => handleSelect(item.selo_grupo_id)}
|
||||
>
|
||||
<CheckIcon
|
||||
className={cn(
|
||||
'mr-2 h-4 w-4',
|
||||
String(field?.value ?? '') === String(item.selo_grupo_id)
|
||||
? 'opacity-100'
|
||||
: 'opacity-0',
|
||||
)}
|
||||
/>
|
||||
{GetCapitalize(item.descricao ?? '')}
|
||||
</CommandItem>
|
||||
))}
|
||||
</CommandGroup>
|
||||
</CommandList>
|
||||
</Command>
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
);
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
'use client';
|
||||
|
||||
import { DataTable } from '@/shared/components/dataTable/DataTable';
|
||||
|
||||
import GSeloGrupoColumns from './GSeloGrupoColumns';
|
||||
import GSeloGrupoTableInterface from '../../interfaces/GSeloGrupo/GSeloGrupoTableInterface';
|
||||
|
||||
/**
|
||||
* Componente principal da tabela de Naturezas
|
||||
*/
|
||||
export default function GSeloGrupoTable({ data, onEdit, onDelete }: GSeloGrupoTableInterface) {
|
||||
const columns = GSeloGrupoColumns(onEdit, onDelete);
|
||||
return (
|
||||
<div>
|
||||
<DataTable
|
||||
data={data}
|
||||
columns={columns}
|
||||
filterColumn="descricao"
|
||||
filterPlaceholder="Buscar por descrição do grupo..."
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
'use client';
|
||||
|
||||
import { HouseIcon, IdCardIcon } from 'lucide-react';
|
||||
import React, { useEffect } from 'react';
|
||||
import { useEffect } from 'react';
|
||||
|
||||
import { Button } from '@/components/ui/button';
|
||||
import {
|
||||
|
|
@ -27,12 +27,12 @@ import { parseNumberInput } from '@/shared/actions/form/parseNumberInput';
|
|||
import { ResetFormIfData } from '@/shared/actions/form/ResetFormIfData';
|
||||
import LoadingButton from '@/shared/components/loadingButton/LoadingButton';
|
||||
|
||||
import TImovelTipoRegistroSelect from './TImovelTipoRegistroSelect';
|
||||
import { useTImovelFormHook } from '../../hooks/TImovel/useTImovelFormHook';
|
||||
import { TImovelFormInterface } from '../../interfaces/TImovel/TImovelFormInterface';
|
||||
import GTBBairroSelect from '../GTBBairro/GTBBairroSelect';
|
||||
import TImovelUnidadeRuralIndex from '../TImovelUnidade/TImovelUnidadeRural/TImovelUnidadeRuralIndex';
|
||||
import TImovelUnidadeUrbanoPage from '../TImovelUnidade/TImovelUnidadeUrbano/TImovelUnidadeUrbanoIndex';
|
||||
import TImovelTipoRegistroSelect from './TImovelTipoRegistroSelect';
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,16 @@
|
|||
import { withClientErrorHandler } from '@/shared/actions/withClientErrorHandler/withClientErrorHandler';
|
||||
import API from '@/shared/services/api/Api';
|
||||
import { Methods } from '@/shared/services/api/enums/ApiMethodEnum';
|
||||
import ApiResponseInterface from '@/shared/services/api/interfaces/ApiResponseInterface';
|
||||
import GEmolumentoInterface from '../../interfaces/GEmolumento/GEmolumentoInterface';
|
||||
|
||||
async function executeGEmolumentoDeleteData(data: GEmolumentoInterface): Promise<ApiResponseInterface> {
|
||||
const api = new API();
|
||||
|
||||
return api.send({
|
||||
method: Methods.DELETE,
|
||||
endpoint: `administrativo/g_emolumento/${data.emolumento_id}`,
|
||||
});
|
||||
}
|
||||
|
||||
export const GEmolumentoDeleteData = withClientErrorHandler(executeGEmolumentoDeleteData);
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
import { withClientErrorHandler } from '@/shared/actions/withClientErrorHandler/withClientErrorHandler';
|
||||
import API from '@/shared/services/api/Api';
|
||||
import { Methods } from '@/shared/services/api/enums/ApiMethodEnum';
|
||||
import ApiResponseInterface from '@/shared/services/api/interfaces/ApiResponseInterface';
|
||||
|
||||
async function executeGEmolumentoIndexData(): Promise<ApiResponseInterface> {
|
||||
const api = new API();
|
||||
|
||||
return api.send({
|
||||
method: Methods.GET,
|
||||
endpoint: `administrativo/g_emolumento/`,
|
||||
});
|
||||
}
|
||||
|
||||
export const GEmolumentoIndexData = withClientErrorHandler(executeGEmolumentoIndexData);
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
import { withClientErrorHandler } from '@/shared/actions/withClientErrorHandler/withClientErrorHandler';
|
||||
import API from '@/shared/services/api/Api';
|
||||
import { Methods } from '@/shared/services/api/enums/ApiMethodEnum';
|
||||
import ApiResponseInterface from '@/shared/services/api/interfaces/ApiResponseInterface';
|
||||
|
||||
import GEmolumentoInterface from '../../interfaces/GEmolumento/GEmolumentoInterface';
|
||||
|
||||
async function executeGEmolumentoSaveData(data: GEmolumentoInterface): Promise<ApiResponseInterface> {
|
||||
// Verifica se existe ID para decidir se é atualização (PUT) ou criação (POST)
|
||||
const isUpdate = Boolean(data.emolumento_id);
|
||||
|
||||
// Instancia o cliente da API
|
||||
const api = new API();
|
||||
|
||||
// Executa a requisição para a API com o método apropriado e envia os dados no corpo
|
||||
return api.send({
|
||||
method: isUpdate ? Methods.PUT : Methods.POST, // PUT se atualizar, POST se criar
|
||||
endpoint: `administrativo/g_emolumento/${data.emolumento_id || ''}`, // endpoint dinâmico
|
||||
body: data, // payload enviado para a API
|
||||
});
|
||||
}
|
||||
|
||||
export const GEmolumentoSaveData = withClientErrorHandler(executeGEmolumentoSaveData);
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
import { withClientErrorHandler } from '@/shared/actions/withClientErrorHandler/withClientErrorHandler';
|
||||
import API from '@/shared/services/api/Api';
|
||||
import { Methods } from '@/shared/services/api/enums/ApiMethodEnum';
|
||||
import ApiResponseInterface from '@/shared/services/api/interfaces/ApiResponseInterface';
|
||||
|
||||
import GSeloGrupoInterface from '../../interfaces/GSeloGrupo/GSeloGrupoInterface';
|
||||
|
||||
async function executeGSeloGrupoDeleteData(data: GSeloGrupoInterface): Promise<ApiResponseInterface> {
|
||||
const api = new API();
|
||||
|
||||
return api.send({
|
||||
method: Methods.DELETE,
|
||||
endpoint: `administrativo/_selo_grupo/${data.selo_grupo_id}`,
|
||||
});
|
||||
}
|
||||
|
||||
export const GSeloGrupoDeleteData = withClientErrorHandler(executeGSeloGrupoDeleteData);
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
import { withClientErrorHandler } from '@/shared/actions/withClientErrorHandler/withClientErrorHandler';
|
||||
import API from '@/shared/services/api/Api';
|
||||
import { Methods } from '@/shared/services/api/enums/ApiMethodEnum';
|
||||
import ApiResponseInterface from '@/shared/services/api/interfaces/ApiResponseInterface';
|
||||
|
||||
async function executeGSeloGrupoIndexData(): Promise<ApiResponseInterface> {
|
||||
const api = new API();
|
||||
|
||||
return api.send({
|
||||
method: Methods.GET,
|
||||
endpoint: `administrativo/g_selo_grupo/`,
|
||||
});
|
||||
}
|
||||
|
||||
export const GSeloGrupoIndexData = withClientErrorHandler(executeGSeloGrupoIndexData);
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
import { withClientErrorHandler } from '@/shared/actions/withClientErrorHandler/withClientErrorHandler';
|
||||
import API from '@/shared/services/api/Api';
|
||||
import { Methods } from '@/shared/services/api/enums/ApiMethodEnum';
|
||||
import ApiResponseInterface from '@/shared/services/api/interfaces/ApiResponseInterface';
|
||||
|
||||
import GSeloGrupoInterface from '../../interfaces/GSeloGrupo/GSeloGrupoInterface';
|
||||
|
||||
async function executeGSeloGrupoSaveData(data: GSeloGrupoInterface): Promise<ApiResponseInterface> {
|
||||
// Verifica se existe ID para decidir se é atualização (PUT) ou criação (POST)
|
||||
const isUpdate = Boolean(data.selo_grupo_id);
|
||||
|
||||
// Instancia o cliente da API
|
||||
const api = new API();
|
||||
|
||||
// Executa a requisição para a API com o método apropriado e envia os dados no corpo
|
||||
return api.send({
|
||||
method: isUpdate ? Methods.PUT : Methods.POST, // PUT se atualizar, POST se criar
|
||||
endpoint: `administrativo/g_selo_grupo/${data.selo_grupo_id || ''}`, // endpoint dinâmico
|
||||
body: data, // payload enviado para a API
|
||||
});
|
||||
}
|
||||
|
||||
export const GSeloGrupoSaveData = withClientErrorHandler(executeGSeloGrupoSaveData);
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
import { useState } from 'react';
|
||||
|
||||
import { useResponse } from '@/shared/components/response/ResponseContext';
|
||||
|
||||
import GEmolumentoInterface from '../../interfaces/GEmolumento/GEmolumentoInterface';
|
||||
import { GEmolumentoDeleteService } from '../../services/GEmolumento/GEmolumentoDeleteService';
|
||||
|
||||
export const useGEmolumentoDeleteHook = () => {
|
||||
const { setResponse } = useResponse();
|
||||
|
||||
const [gGramatica, setGEmolumento] = useState<GEmolumentoInterface>();
|
||||
|
||||
const deleteGEmolumento = async (data: GEmolumentoInterface) => {
|
||||
const response = await GEmolumentoDeleteService(data);
|
||||
|
||||
setGEmolumento(data);
|
||||
setResponse(response);
|
||||
};
|
||||
|
||||
return { gGramatica, deleteGEmolumento };
|
||||
};
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
import { zodResolver } from '@hookform/resolvers/zod';
|
||||
import { useForm } from 'react-hook-form';
|
||||
|
||||
import { GEmolumentoFormValues, GEmolumentoSchema } from '../../schemas/GEmolumento/GEmolumentoSchema';
|
||||
|
||||
export function useGEmolumentoFormHook(defaults?: Partial<GEmolumentoFormValues>) {
|
||||
return useForm<GEmolumentoFormValues>({
|
||||
resolver: zodResolver(GEmolumentoSchema),
|
||||
defaultValues: {
|
||||
emolumento_id: 0,
|
||||
...defaults,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
'use client';
|
||||
|
||||
import { useState } from 'react';
|
||||
|
||||
import { useResponse } from '@/shared/components/response/ResponseContext';
|
||||
|
||||
import GEmolumentoInterface from '../../interfaces/GEmolumento/GEmolumentoInterface';
|
||||
import { GEmolumentoIndexService } from '../../services/GEmolumento/GEmolumentoIndexService';
|
||||
|
||||
export const useGEmolumentoIndexHook = () => {
|
||||
const { setResponse } = useResponse();
|
||||
|
||||
const [gGramatica, setGEmolumento] = useState<GEmolumentoInterface[]>([]);
|
||||
|
||||
const indexGEmolumento = async () => {
|
||||
const response = await GEmolumentoIndexService();
|
||||
// Armazena os dados consultados
|
||||
setGEmolumento(response.data);
|
||||
// Define a resposta (toast, modal, feedback, etc.)
|
||||
setResponse(response);
|
||||
};
|
||||
|
||||
return {
|
||||
gGramatica,
|
||||
indexGEmolumento,
|
||||
};
|
||||
};
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
'use client';
|
||||
|
||||
import { useState } from 'react';
|
||||
|
||||
import { useResponse } from '@/shared/components/response/ResponseContext';
|
||||
|
||||
import GEmolumentoInterface from '../../interfaces/GEmolumento/GEmolumentoInterface';
|
||||
import { GEmolumentoSaveService } from '../../services/GEmolumento/GEmolumentoSaveService';
|
||||
|
||||
export const useGEmolumentoSaveHook = () => {
|
||||
const { setResponse } = useResponse();
|
||||
|
||||
const [gGramatica, setGEmolumento] = useState<GEmolumentoInterface | null>(null);
|
||||
|
||||
// controla se o formulário está aberto ou fechado
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
|
||||
const saveGEmolumento = async (data: GEmolumentoInterface) => {
|
||||
const response = await GEmolumentoSaveService(data);
|
||||
|
||||
// Armazena os dados da resposta
|
||||
setGEmolumento(response.data);
|
||||
|
||||
// Define os dados da resposta (toast, modal, etc.)
|
||||
setResponse(response);
|
||||
|
||||
// Fecha o formulário automaticamente após salvar
|
||||
setIsOpen(false);
|
||||
|
||||
// Retorna os valores de forma imediata
|
||||
return response.data;
|
||||
};
|
||||
|
||||
return { gGramatica, saveGEmolumento, isOpen, setIsOpen };
|
||||
};
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
import { useState } from 'react';
|
||||
|
||||
import { useResponse } from '@/shared/components/response/ResponseContext';
|
||||
|
||||
import GSeloGrupoInterface from '../../interfaces/GSeloGrupo/GSeloGrupoInterface';
|
||||
import { GSeloGrupoDeleteService } from '../../services/GSeloGrupo/GSeloGrupoDeleteService';
|
||||
|
||||
export const useGSeloGrupoDeleteHook = () => {
|
||||
const { setResponse } = useResponse();
|
||||
|
||||
const [gSeloGrupo, setGSeloGrupo] = useState<GSeloGrupoInterface>();
|
||||
|
||||
const deleteGSeloGrupo = async (data: GSeloGrupoInterface) => {
|
||||
const response = await GSeloGrupoDeleteService(data);
|
||||
|
||||
setGSeloGrupo(data);
|
||||
setResponse(response);
|
||||
};
|
||||
|
||||
return { gSeloGrupo, deleteGSeloGrupo };
|
||||
};
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
import { zodResolver } from '@hookform/resolvers/zod';
|
||||
import { useForm } from 'react-hook-form';
|
||||
|
||||
import { GSeloGrupoFormValues, GSeloGrupoSchema } from '../../schemas/GSeloGrupo/GSeloGrupoSchema';
|
||||
|
||||
export function useGSeloGrupoFormHook(defaults?: Partial<GSeloGrupoFormValues>) {
|
||||
return useForm<GSeloGrupoFormValues>({
|
||||
resolver: zodResolver(GSeloGrupoSchema),
|
||||
defaultValues: {
|
||||
selo_grupo_id: 0,
|
||||
...defaults,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
'use client';
|
||||
|
||||
import { useState } from 'react';
|
||||
|
||||
import { useResponse } from '@/shared/components/response/ResponseContext';
|
||||
|
||||
import GSeloGrupoInterface from '../../interfaces/GSeloGrupo/GSeloGrupoInterface';
|
||||
import { GSeloGrupoIndexService } from '../../services/GSeloGrupo/GSeloGrupoIndexService';
|
||||
|
||||
export const useGSeloGrupoIndexHook = () => {
|
||||
const { setResponse } = useResponse();
|
||||
|
||||
const [gSeloGrupo, setGSeloGrupo] = useState<GSeloGrupoInterface[]>([]);
|
||||
|
||||
const indexGSeloGrupo = async () => {
|
||||
const response = await GSeloGrupoIndexService();
|
||||
// Armazena os dados consultados
|
||||
setGSeloGrupo(response.data);
|
||||
// Define a resposta (toast, modal, feedback, etc.)
|
||||
setResponse(response);
|
||||
};
|
||||
|
||||
return {
|
||||
gSeloGrupo,
|
||||
indexGSeloGrupo,
|
||||
};
|
||||
};
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
'use client';
|
||||
|
||||
import { useState } from 'react';
|
||||
|
||||
import { useResponse } from '@/shared/components/response/ResponseContext';
|
||||
|
||||
import GSeloGrupoInterface from '../../interfaces/GSeloGrupo/GSeloGrupoInterface';
|
||||
import { GSeloGrupoSaveService } from '../../services/GSeloGrupo/GSeloGrupoSaveService';
|
||||
|
||||
export const useGSeloGrupoSaveHook = () => {
|
||||
const { setResponse } = useResponse();
|
||||
|
||||
const [gSeloGrupo, setGSeloGrupo] = useState<GSeloGrupoInterface | null>(null);
|
||||
|
||||
// controla se o formulário está aberto ou fechado
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
|
||||
const saveGSeloGrupo = async (data: GSeloGrupoInterface) => {
|
||||
const response = await GSeloGrupoSaveService(data);
|
||||
|
||||
// Armazena os dados da resposta
|
||||
setGSeloGrupo(response.data);
|
||||
|
||||
// Define os dados da resposta (toast, modal, etc.)
|
||||
setResponse(response);
|
||||
|
||||
// Fecha o formulário automaticamente após salvar
|
||||
setIsOpen(false);
|
||||
|
||||
// Retorna os valores de forma imediata
|
||||
return response.data;
|
||||
};
|
||||
|
||||
return { gSeloGrupo, saveGSeloGrupo, isOpen, setIsOpen };
|
||||
};
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
import { GEmolumentoFormValues } from '../../schemas/GEmolumento/GEmolumentoSchema';
|
||||
|
||||
export interface GEmolumentoFormInterface {
|
||||
isOpen: boolean;
|
||||
data: GEmolumentoFormValues | null;
|
||||
onClose: (item: null, isFormStatus: boolean) => void;
|
||||
onSave: (data: GEmolumentoFormValues) => void;
|
||||
buttonIsLoading: boolean;
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
export default interface GEmolumentoInterface {
|
||||
emolumento_id?: number;
|
||||
descricao?: string;
|
||||
tipo?: string;
|
||||
sistema_id?: number;
|
||||
selo_grupo_id?: number;
|
||||
reg_averb?: string;
|
||||
pre_definido?: string;
|
||||
situacao?: string;
|
||||
situacao_ri?: string;
|
||||
com_reducao?: string;
|
||||
motivo_reducao?: string;
|
||||
valor_maximo_certidao?: number;
|
||||
tipo_objetivo?: string;
|
||||
modelo_tag?: string;
|
||||
codigo_nota_id?: number;
|
||||
convenio_codhab?: string;
|
||||
item_df?: string;
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
import GEmolumentoInterface from './GEmolumentoInterface';
|
||||
|
||||
export default interface GEmolumentoTableInterface {
|
||||
data?: GEmolumentoInterface[];
|
||||
onEdit: (item: GEmolumentoInterface, isEditingFormStatus: boolean) => void;
|
||||
onDelete: (item: GEmolumentoInterface, isEditingFormStatus: boolean) => void;
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
import { GSeloGrupoFormValues } from '../../schemas/GSeloGrupo/GSeloGrupoSchema';
|
||||
|
||||
export interface GSeloGrupoFormInterface {
|
||||
isOpen: boolean;
|
||||
data: GSeloGrupoFormValues | null;
|
||||
onClose: (item: null, isFormStatus: boolean) => void;
|
||||
onSave: (data: GSeloGrupoFormValues) => void;
|
||||
buttonIsLoading: boolean;
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
export default interface GSeloGrupoInterface {
|
||||
selo_grupo_id?: number;
|
||||
descricao?: string;
|
||||
numero?: number;
|
||||
situacao?: string;
|
||||
controle_automatico?: string;
|
||||
sistema_id?: number;
|
||||
valor?: number;
|
||||
tipo_cartorio?: string;
|
||||
descricao_completa?: string;
|
||||
agrupador?: string;
|
||||
um_por_protocolo?: string;
|
||||
numero_principal_ini?: number;
|
||||
numero_principal_fim?: number;
|
||||
selo_grupo_id_principal?: number;
|
||||
envio_automatico?: string;
|
||||
selo_grupo_id_agrupador?: number;
|
||||
codigo_conta?: number;
|
||||
id_tipo_ato_antigo?: number;
|
||||
grupos_principal?: string;
|
||||
sigla?: string;
|
||||
tipo_selo?: string;
|
||||
natureza?: number;
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
export default interface GSeloGrupoSelectInterace {
|
||||
field?: {
|
||||
value?: number | string;
|
||||
onChange?: (value: string | number) => void;
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
import GSeloGrupoInterface from './GSeloGrupoInterface';
|
||||
|
||||
export default interface GSeloGrupoTableInterface {
|
||||
data?: GSeloGrupoInterface[];
|
||||
onEdit: (item: GSeloGrupoInterface, isEditingFormStatus: boolean) => void;
|
||||
onDelete: (item: GSeloGrupoInterface, isEditingFormStatus: boolean) => void;
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
import z from "zod";
|
||||
|
||||
export const GEmolumentoSchema = z.object({
|
||||
emolumento_id: z.number().optional(),
|
||||
descricao: z.string().optional(),
|
||||
tipo: z.string().optional(),
|
||||
sistema_id: z.number().optional(),
|
||||
selo_grupo_id: z.number().optional(),
|
||||
reg_averb: z.string().optional(),
|
||||
pre_definido: z.string().optional(),
|
||||
situacao: z.string().optional(),
|
||||
situacao_ri: z.string().optional(),
|
||||
com_reducao: z.string().optional(),
|
||||
motivo_reducao: z.string().optional(),
|
||||
valor_maximo_certidao: z.number().optional(),
|
||||
tipo_objetivo: z.string().optional(),
|
||||
modelo_tag: z.string().optional(),
|
||||
codigo_nota_id: z.number().optional(),
|
||||
convenio_codhab: z.string().optional(),
|
||||
item_df: z.string().optional(),
|
||||
});
|
||||
|
||||
export type GEmolumentoFormValues = z.infer<typeof GEmolumentoSchema>;
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
import { z } from "zod";
|
||||
|
||||
export const GSeloGrupoSchema = z.object({
|
||||
selo_grupo_id: z.number().optional(),
|
||||
descricao: z.string().optional(),
|
||||
numero: z.number().optional(),
|
||||
situacao: z.string().optional(),
|
||||
controle_automatico: z.string().optional(),
|
||||
sistema_id: z.number().optional(),
|
||||
valor: z.number().optional(),
|
||||
tipo_cartorio: z.string().optional(),
|
||||
descricao_completa: z.string().optional(),
|
||||
agrupador: z.string().optional(),
|
||||
um_por_protocolo: z.string().optional(),
|
||||
numero_principal_ini: z.number().optional(),
|
||||
numero_principal_fim: z.number().optional(),
|
||||
selo_grupo_id_principal: z.number().optional(),
|
||||
envio_automatico: z.string().optional(),
|
||||
selo_grupo_id_agrupador: z.number().optional(),
|
||||
codigo_conta: z.number().optional(),
|
||||
id_tipo_ato_antigo: z.number().optional(),
|
||||
grupos_principal: z.string().optional(),
|
||||
sigla: z.string().optional(),
|
||||
tipo_selo: z.string().optional(),
|
||||
natureza: z.number().optional(),
|
||||
});
|
||||
|
||||
export type GSeloGrupoFormValues = z.infer<typeof GSeloGrupoSchema>;
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
|
||||
import { GEmolumentoDeleteData } from '../../data/GEmolumento/GEmolumentoDeleteData';
|
||||
import { withClientErrorHandler } from '@/shared/actions/withClientErrorHandler/withClientErrorHandler';
|
||||
|
||||
import GEmolumentoInterface from '../../interfaces/GEmolumento/GEmolumentoInterface';
|
||||
|
||||
|
||||
async function executeGEmolumentoDeleteService(data: GEmolumentoInterface) {
|
||||
const response = await GEmolumentoDeleteData(data);
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
export const GEmolumentoDeleteService = withClientErrorHandler(executeGEmolumentoDeleteService);
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
import { withClientErrorHandler } from '@/shared/actions/withClientErrorHandler/withClientErrorHandler';
|
||||
|
||||
import { GEmolumentoIndexData } from '../../data/GEmolumento/GEmolumentoIndexData';
|
||||
|
||||
export default async function executeGEmolumentoIndexService() {
|
||||
const response = await GEmolumentoIndexData();
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
export const GEmolumentoIndexService = withClientErrorHandler(executeGEmolumentoIndexService);
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
import { withClientErrorHandler } from '@/shared/actions/withClientErrorHandler/withClientErrorHandler';
|
||||
|
||||
import { GEmolumentoSaveData } from '../../data/GEmolumento/GEmolumentoSaveData';
|
||||
import GEmolumentoInterface from '../../interfaces/GEmolumento/GEmolumentoInterface';
|
||||
|
||||
async function executeGEmolumentoSaveService(data: GEmolumentoInterface) {
|
||||
const response = await GEmolumentoSaveData(data);
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
export const GEmolumentoSaveService = withClientErrorHandler(executeGEmolumentoSaveService);
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
import { withClientErrorHandler } from '@/shared/actions/withClientErrorHandler/withClientErrorHandler';
|
||||
import { GSeloGrupoDeleteData } from '../../data/GSeloGrupo/GSeloGrupoDeleteData';
|
||||
import GSeloGrupoInterface from '../../interfaces/GSeloGrupo/GSeloGrupoInterface';
|
||||
|
||||
async function executeGSeloGrupoDeleteService(data: GSeloGrupoInterface) {
|
||||
const response = await GSeloGrupoDeleteData(data);
|
||||
return response;
|
||||
}
|
||||
|
||||
export const GSeloGrupoDeleteService = withClientErrorHandler(executeGSeloGrupoDeleteService);
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
import { withClientErrorHandler } from '@/shared/actions/withClientErrorHandler/withClientErrorHandler';
|
||||
|
||||
import { GSeloGrupoIndexData } from '../../data/GSeloGrupo/GSeloGrupoIndexData';
|
||||
|
||||
export default async function executeGSeloGrupoIndexService() {
|
||||
const response = await GSeloGrupoIndexData();
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
export const GSeloGrupoIndexService = withClientErrorHandler(executeGSeloGrupoIndexService);
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
import { withClientErrorHandler } from '@/shared/actions/withClientErrorHandler/withClientErrorHandler';
|
||||
|
||||
import { GSeloGrupoSaveData } from '../../data/GSeloGrupo/GSeloGrupoSaveData';
|
||||
import GSeloGrupoInterface from '../../interfaces/GSeloGrupo/GSeloGrupoInterface';
|
||||
|
||||
async function executeGSeloGrupoSaveService(data: GSeloGrupoInterface) {
|
||||
const response = await GSeloGrupoSaveData(data);
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
export const GSeloGrupoSaveService = withClientErrorHandler(executeGSeloGrupoSaveService);
|
||||
82
src/shared/components/sistemas/SistemasSelect.tsx
Normal file
82
src/shared/components/sistemas/SistemasSelect.tsx
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
import { Command } from 'cmdk';
|
||||
import { CheckIcon, ChevronsUpDownIcon } from 'lucide-react';
|
||||
import React from 'react';
|
||||
import { ControllerRenderProps } from 'react-hook-form';
|
||||
|
||||
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 { SistemasEnum } from '@/shared/enums/SistemasEnum';
|
||||
|
||||
interface SistemasSelectProps {
|
||||
field: ControllerRenderProps<any, any>;
|
||||
}
|
||||
|
||||
const SistemasSelect: React.FC<SistemasSelectProps> = ({ field }) => {
|
||||
const [open, setOpen] = React.useState(false);
|
||||
|
||||
const options = Object.entries(SistemasEnum).map(([key, label]) => ({
|
||||
value: Number(key),
|
||||
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) => Number(item.value) === Number(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 sistema..." />
|
||||
<CommandList>
|
||||
<CommandEmpty>Nenhum resultado encontrado.</CommandEmpty>
|
||||
<CommandGroup>
|
||||
{options.map((item) => (
|
||||
<CommandItem
|
||||
key={item.value}
|
||||
value={item.label.toLowerCase()}
|
||||
onSelect={() => {
|
||||
field.onChange(Number(item.value));
|
||||
setOpen(false);
|
||||
}}
|
||||
>
|
||||
<CheckIcon
|
||||
className={cn(
|
||||
'mr-2 h-4 w-4',
|
||||
Number(field.value) === Number(item.value)
|
||||
? 'opacity-100'
|
||||
: 'opacity-0',
|
||||
)}
|
||||
/>
|
||||
{item.label}
|
||||
</CommandItem>
|
||||
))}
|
||||
</CommandGroup>
|
||||
</CommandList>
|
||||
</Command>
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
);
|
||||
};
|
||||
|
||||
export default SistemasSelect;
|
||||
73
src/shared/components/tipoCartorio/TipoCartorioSelect.tsx
Normal file
73
src/shared/components/tipoCartorio/TipoCartorioSelect.tsx
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
import { Command } from 'cmdk';
|
||||
import { CheckIcon, ChevronsUpDownIcon } from 'lucide-react';
|
||||
import React from 'react';
|
||||
|
||||
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 { TipoCartorioEnum } from '@/shared/enums/TipoCartorioEnum';
|
||||
|
||||
export default function TipoCartorioSelect({ field }: any) {
|
||||
const [open, setOpen] = React.useState(false);
|
||||
|
||||
const options = Object.entries(TipoCartorioEnum).map(([value, label]) => ({
|
||||
value,
|
||||
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 situaçã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,73 @@
|
|||
import { Command } from 'cmdk';
|
||||
import { CheckIcon, ChevronsUpDownIcon } from 'lucide-react';
|
||||
import React from 'react';
|
||||
|
||||
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 { TipoEmolumento } from '@/shared/enums/TipoEmolumentoEnum';
|
||||
|
||||
export default function TipoEmolumentoSelect({ field }: any) {
|
||||
const [open, setOpen] = React.useState(false);
|
||||
|
||||
const options = Object.entries(TipoEmolumento).map(([value, label]) => ({
|
||||
value,
|
||||
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 situaçã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>
|
||||
);
|
||||
}
|
||||
8
src/shared/enums/SistemasEnum.ts
Normal file
8
src/shared/enums/SistemasEnum.ts
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
export const SistemasEnum = {
|
||||
1: 'Registro de Imóveis',
|
||||
2: 'Tabelionato de Notas',
|
||||
5: 'Caixa',
|
||||
7: 'Registro de Títulos e Documentos',
|
||||
12: 'Registro Civil',
|
||||
13: 'Protesto de Títulos e Documentos',
|
||||
} as const;
|
||||
7
src/shared/enums/TipoCartorioEnum.ts
Normal file
7
src/shared/enums/TipoCartorioEnum.ts
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
export const TipoCartorioEnum = {
|
||||
1: 'Tabelionato de Notas',
|
||||
2: 'Registro de Imóveis',
|
||||
3: 'Registro Civil',
|
||||
4: 'RTD',
|
||||
5: 'Tabelionato de Protesto',
|
||||
} as const;
|
||||
6
src/shared/enums/TipoEmolumentoEnum.ts
Normal file
6
src/shared/enums/TipoEmolumentoEnum.ts
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
export const TipoEmolumento = {
|
||||
C: 'Certidões',
|
||||
T: 'Títulos',
|
||||
P: 'Personalizado',
|
||||
B: 'Balcão',
|
||||
} as const;
|
||||
Loading…
Add table
Reference in a new issue