[MVPTN-122] feat(CRUD): Implementa parcialmente o CRUD par amanipular a tabela GEmolumentoItem
This commit is contained in:
parent
9b9f8b9454
commit
6051afc3e0
25 changed files with 800 additions and 8 deletions
|
|
@ -0,0 +1,17 @@
|
|||
'use client'
|
||||
|
||||
import { useParams } from "next/navigation";
|
||||
|
||||
import GEmolumentoItemIndex from "@/packages/administrativo/components/GEmolumentoItem/GEmolumentoItemIndex";
|
||||
|
||||
export default function GGramaticaPage() {
|
||||
|
||||
const params = useParams();
|
||||
|
||||
return (
|
||||
<GEmolumentoItemIndex
|
||||
emolumento_id={Number(params.emolumentoId)}
|
||||
/>
|
||||
);
|
||||
|
||||
}
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
import { ColumnDef } from '@tanstack/react-table';
|
||||
import { EllipsisIcon, PencilIcon, Trash2Icon } from 'lucide-react';
|
||||
import { EllipsisIcon, ListIcon, PencilIcon, Trash2Icon } from 'lucide-react';
|
||||
import Link from 'next/link';
|
||||
|
||||
import { Button } from '@/components/ui/button';
|
||||
import {
|
||||
|
|
@ -41,7 +42,6 @@ export default function GEmolumentoColumns(
|
|||
header: 'Ações',
|
||||
cell: ({ row }) => {
|
||||
const natureza = row.original;
|
||||
|
||||
return (
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild>
|
||||
|
|
@ -49,16 +49,20 @@ export default function GEmolumentoColumns(
|
|||
<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 asChild>
|
||||
<Link href={`/administrativo/financeiro/emolumentos/${Number(row.getValue('emolumento_id'))}/itens`}>
|
||||
<ListIcon className="mr-2 h-4 w-4" />
|
||||
Itens
|
||||
</Link>
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuSeparator />
|
||||
<DropdownMenuItem
|
||||
className="text-red-600"
|
||||
onSelect={() => onDelete(natureza, true)}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
'use client';
|
||||
|
||||
import { useEffect, useState, useCallback } from 'react';
|
||||
|
||||
import { useCallback, useEffect, useState } from 'react';
|
||||
|
||||
import { useGEmolumentoDeleteHook } from '@/packages/administrativo/hooks/GEmolumento/useGEmolumentoDeleteHook';
|
||||
import { useGEmolumentoIndexHook } from '@/packages/administrativo/hooks/GEmolumento/useGEmolumentoIndexHook';
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@
|
|||
|
||||
import { DataTable } from '@/shared/components/dataTable/DataTable';
|
||||
|
||||
import GEmolumentoColumns from './GEmolumentoColumns';
|
||||
import GEmolumentoTableInterface from '../../interfaces/GEmolumento/GEmolumentoTableInterface';
|
||||
import GEmolumentoColumns from './GEmolumentoColumns';
|
||||
|
||||
/**
|
||||
* Componente principal da tabela de Naturezas
|
||||
|
|
|
|||
|
|
@ -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 GEmolumentoItemInterface from '../../interfaces/GEmolumentoItem/GEmolumentoItemInterface';
|
||||
|
||||
export default function GEmolumentoItemColumns(
|
||||
onEdit: (item: GEmolumentoItemInterface, isEditingFormStatus: boolean) => void,
|
||||
onDelete: (item: GEmolumentoItemInterface, isEditingFormStatus: boolean) => void,
|
||||
): ColumnDef<GEmolumentoItemInterface>[] {
|
||||
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,139 @@
|
|||
'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 { ResetFormIfData } from '@/shared/actions/form/ResetFormIfData';
|
||||
import LoadingButton from '@/shared/components/loadingButton/LoadingButton';
|
||||
|
||||
import { useGEmolumentoItemFormHook } from '../../hooks/GEmolumentoItem/useGEmolumentoItemFormHook';
|
||||
import { GEmolumentoItemFormInterface } from '../../interfaces/GEmolumentoItem/GEmolumentoItemFormInterface';
|
||||
|
||||
/**
|
||||
* Formulário de cadastro/edição de Natureza
|
||||
* Baseado nos campos da tabela G_NATUREZA
|
||||
*/
|
||||
export default function GEmolumentoItemForm({
|
||||
isOpen,
|
||||
data,
|
||||
onClose,
|
||||
onSave,
|
||||
buttonIsLoading,
|
||||
}: GEmolumentoItemFormInterface) {
|
||||
const form = useGEmolumentoItemFormHook({});
|
||||
|
||||
// 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>
|
||||
</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>
|
||||
</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,172 @@
|
|||
'use client';
|
||||
|
||||
import { useCallback, useEffect, useRef, useState } from 'react';
|
||||
|
||||
import { useGEmolumentoItemDeleteHook } from '@/packages/administrativo/hooks/GEmolumentoItem/useGEmolumentoItemDeleteHook';
|
||||
import { useGEmolumentoItemIndexHook } from '@/packages/administrativo/hooks/GEmolumentoItem/useGEmolumentoItemIndexHook';
|
||||
import { useGEmolumentoItemSaveHook } from '@/packages/administrativo/hooks/GEmolumentoItem/useGEmolumentoItemSaveHook';
|
||||
import GEmolumentoItemIndexInterface from '@/packages/administrativo/interfaces/GEmolumentoItem/GEmolumentoItemIndexInterface';
|
||||
import GEmolumentoItemInterface from '@/packages/administrativo/interfaces/GEmolumentoItem/GEmolumentoItemInterface';
|
||||
import ConfirmDialog from '@/shared/components/confirmDialog/ConfirmDialog';
|
||||
import { useConfirmDialog } from '@/shared/components/confirmDialog/useConfirmDialog';
|
||||
import Header from '@/shared/components/structure/Header';
|
||||
|
||||
import GEmolumentoItemForm from './GEmolumentoItemForm';
|
||||
import GEmolumentoItemTable from './GEmolumentoItemTable';
|
||||
|
||||
export default function GEmolumentoItemIndex({ emolumento_id }: GEmolumentoItemIndexInterface) {
|
||||
// Controle de estado do botão
|
||||
const [buttonIsLoading, setButtonIsLoading] = useState(false);
|
||||
|
||||
// Hooks para leitura e salvamento
|
||||
const { gEmolumentoItem, indexGEmolumentoItem } = useGEmolumentoItemIndexHook();
|
||||
const { saveGEmolumentoItem } = useGEmolumentoItemSaveHook();
|
||||
const { deleteGEmolumentoItem } = useGEmolumentoItemDeleteHook();
|
||||
|
||||
// Estados do componente
|
||||
const [selectedData, setSelectedData] = useState<GEmolumentoItemInterface | null>(null);
|
||||
const [isFormOpen, setIsFormOpen] = useState(false);
|
||||
const [itemToDelete, setItemToDelete] = useState<GEmolumentoItemInterface | null>(null);
|
||||
|
||||
// Estado para controlar o período selecionado
|
||||
const [getEmolumentoPeriodoId, setEmolumentoPeriodoId] = useState<number | null>(null);
|
||||
|
||||
// Hook do modal de confirmação
|
||||
const { isOpen: isConfirmOpen, openDialog: openConfirmDialog, handleCancel } = useConfirmDialog();
|
||||
|
||||
// Flag para evitar duplas execuções em modo Strict
|
||||
const isMounted = useRef(false);
|
||||
|
||||
/**
|
||||
* Abre o formulário no modo de edição ou criação
|
||||
*/
|
||||
const handleOpenForm = useCallback((data: GEmolumentoItemInterface | null) => {
|
||||
setSelectedData(data);
|
||||
setIsFormOpen(true);
|
||||
}, []);
|
||||
|
||||
/**
|
||||
* Fecha o formulário e limpa o andamento selecionado
|
||||
*/
|
||||
const handleCloseForm = useCallback(() => {
|
||||
setSelectedData(null);
|
||||
setIsFormOpen(false);
|
||||
}, []);
|
||||
|
||||
/**
|
||||
* Sempre que o emolumento_id ou o período mudar, busca novamente os dados.
|
||||
* Evita loop infinito e só dispara quando necessário.
|
||||
*/
|
||||
useEffect(() => {
|
||||
if (!emolumento_id) return;
|
||||
|
||||
// Evita execução duplicada no modo Strict
|
||||
if (isMounted.current) {
|
||||
indexGEmolumentoItem({
|
||||
emolumento_id,
|
||||
emolumento_periodo_id: getEmolumentoPeriodoId ?? 0,
|
||||
});
|
||||
} else {
|
||||
isMounted.current = true;
|
||||
indexGEmolumentoItem({
|
||||
emolumento_id,
|
||||
emolumento_periodo_id: getEmolumentoPeriodoId ?? 0,
|
||||
});
|
||||
}
|
||||
}, [emolumento_id, getEmolumentoPeriodoId]);
|
||||
|
||||
/**
|
||||
* Executa consulta ao selecionar um período
|
||||
*/
|
||||
const handleSelectedEmolumentoPeriodo = (emolumentoPeriodoId: number) => {
|
||||
setEmolumentoPeriodoId(emolumentoPeriodoId); // 🔥 Isso dispara o useEffect acima
|
||||
};
|
||||
|
||||
/**
|
||||
* Salva os dados do formulário
|
||||
*/
|
||||
const handleSave = useCallback(
|
||||
async (formData: GEmolumentoItemInterface) => {
|
||||
setButtonIsLoading(true);
|
||||
await saveGEmolumentoItem(formData);
|
||||
setButtonIsLoading(false);
|
||||
|
||||
// Recarrega a lista usando os valores atuais
|
||||
await indexGEmolumentoItem({
|
||||
emolumento_id,
|
||||
emolumento_periodo_id: getEmolumentoPeriodoId ?? 0,
|
||||
});
|
||||
},
|
||||
[saveGEmolumentoItem, indexGEmolumentoItem, emolumento_id, getEmolumentoPeriodoId]
|
||||
);
|
||||
|
||||
/**
|
||||
* Quando o usuário clica em "remover" na tabela
|
||||
*/
|
||||
const handleConfirmDelete = useCallback(
|
||||
(item: GEmolumentoItemInterface) => {
|
||||
setItemToDelete(item);
|
||||
openConfirmDialog();
|
||||
},
|
||||
[openConfirmDialog]
|
||||
);
|
||||
|
||||
/**
|
||||
* Executa a exclusão de fato quando o usuário confirma
|
||||
*/
|
||||
const handleDelete = useCallback(async () => {
|
||||
if (!itemToDelete) return;
|
||||
await deleteGEmolumentoItem(itemToDelete);
|
||||
await indexGEmolumentoItem({
|
||||
emolumento_id,
|
||||
emolumento_periodo_id: getEmolumentoPeriodoId ?? 0,
|
||||
});
|
||||
setItemToDelete(null);
|
||||
handleCancel();
|
||||
}, [itemToDelete, deleteGEmolumentoItem, indexGEmolumentoItem, emolumento_id, getEmolumentoPeriodoId, handleCancel]);
|
||||
|
||||
return (
|
||||
<div>
|
||||
{/* Cabeçalho */}
|
||||
<Header
|
||||
title="Itens de Emolumentos"
|
||||
description="Itens de Emolumentos"
|
||||
buttonText="Novo Item"
|
||||
buttonAction={() => handleOpenForm(null)}
|
||||
/>
|
||||
|
||||
{/* Tabela */}
|
||||
<GEmolumentoItemTable
|
||||
data={gEmolumentoItem}
|
||||
onEdit={handleOpenForm}
|
||||
onDelete={handleConfirmDelete}
|
||||
onSelectedEmolumentoPeriodo={handleSelectedEmolumentoPeriodo}
|
||||
/>
|
||||
|
||||
{/* 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 */}
|
||||
{isFormOpen && (
|
||||
<GEmolumentoItemForm
|
||||
isOpen={isFormOpen}
|
||||
data={selectedData}
|
||||
onClose={handleCloseForm}
|
||||
onSave={handleSave}
|
||||
buttonIsLoading={buttonIsLoading}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
'use client';
|
||||
|
||||
import { DataTable } from '@/shared/components/dataTable/DataTable';
|
||||
|
||||
import GEmolumentoItemColumns from './GEmolumentoItemColumns';
|
||||
import GEmolumentoItemTableInterface from '../../interfaces/GEmolumentoItem/GEmolumentoItemTableInterface';
|
||||
import GEmolumentoPeriodoSelect from '../GEmolumentoPeriodo/GEmolumentoPeriodoSelect';
|
||||
|
||||
/**
|
||||
* Componente principal da tabela de Naturezas
|
||||
*/
|
||||
export default function GEmolumentoItemTable({ data, onEdit, onDelete, onSelectedEmolumentoPeriodo }: GEmolumentoItemTableInterface) {
|
||||
const columns = GEmolumentoItemColumns(onEdit, onDelete);
|
||||
return (
|
||||
<div>
|
||||
<GEmolumentoPeriodoSelect
|
||||
onSelectedEmolumentoPeriodo={onSelectedEmolumentoPeriodo}
|
||||
/>
|
||||
<DataTable
|
||||
data={data}
|
||||
columns={columns}
|
||||
filterColumn="descricao"
|
||||
filterPlaceholder="Buscar por descrição da natureza..."
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
@ -0,0 +1,110 @@
|
|||
'use client';
|
||||
|
||||
import { CheckIcon, ChevronsUpDownIcon } from 'lucide-react';
|
||||
import { useCallback, useEffect, useMemo, useState } from 'react';
|
||||
|
||||
import { Button } from '@/components/ui/button';
|
||||
import {
|
||||
Command,
|
||||
CommandEmpty,
|
||||
CommandGroup,
|
||||
CommandInput,
|
||||
CommandItem,
|
||||
CommandList,
|
||||
} from '@/components/ui/command';
|
||||
import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover';
|
||||
import { cn } from '@/lib/utils';
|
||||
import GetCapitalize from '@/shared/actions/text/GetCapitalize';
|
||||
|
||||
import { useGEmolumentoPeriodoIndexHook } from '../../hooks/GEmolumentoPeriodo/useGEmolumentoPeriodoIndexHook';
|
||||
import GEmolumentoPeriodoSelectInterface from '../../interfaces/GEmolumentoPeriodo/GEmolumentoPeriodoSelectInterface';
|
||||
|
||||
export default function GEmolumentoPeriodoSelect({ onSelectedEmolumentoPeriodo }: GEmolumentoPeriodoSelectInterface) {
|
||||
|
||||
const [open, setOpen] = useState(false);
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const [selectedId, setSelectedId] = useState<number | null>(null);
|
||||
|
||||
const { gEmolumentoPeriodo, indexGEmolumentoPeriodo } = useGEmolumentoPeriodoIndexHook();
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Carrega os períodos apenas uma vez
|
||||
// ---------------------------------------------------------------------------
|
||||
const loadData = useCallback(async () => {
|
||||
if (gEmolumentoPeriodo.length) return;
|
||||
setIsLoading(true);
|
||||
await indexGEmolumentoPeriodo();
|
||||
setIsLoading(false);
|
||||
}, [gEmolumentoPeriodo.length, indexGEmolumentoPeriodo]);
|
||||
|
||||
useEffect(() => {
|
||||
loadData();
|
||||
}, [loadData]);
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Item selecionado
|
||||
// ---------------------------------------------------------------------------
|
||||
const selected = useMemo(
|
||||
() => gEmolumentoPeriodo.find((b) => String(b.emolumento_periodo_id) === String(selectedId ?? '')),
|
||||
[gEmolumentoPeriodo, selectedId]
|
||||
);
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Ao selecionar um item → dispara novo hook
|
||||
// ---------------------------------------------------------------------------
|
||||
const handleSelect = async (id: number) => {
|
||||
setSelectedId(id);
|
||||
setOpen(false);
|
||||
onSelectedEmolumentoPeriodo(id);
|
||||
};
|
||||
|
||||
return (
|
||||
<Popover open={open} onOpenChange={setOpen}>
|
||||
<PopoverTrigger asChild>
|
||||
<Button
|
||||
variant="outline"
|
||||
role="combobox"
|
||||
aria-expanded={open}
|
||||
disabled={isLoading}
|
||||
className="w-full justify-between"
|
||||
>
|
||||
{isLoading
|
||||
? 'Carregando...'
|
||||
: selected
|
||||
? GetCapitalize(selected.descricao)
|
||||
: 'Selecione...'}
|
||||
<ChevronsUpDownIcon className="ml-2 h-4 w-4 shrink-0 opacity-50" />
|
||||
</Button>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent className="w-full p-0 mb-5">
|
||||
<Command>
|
||||
<CommandInput placeholder="Buscar período..." disabled={isLoading} />
|
||||
<CommandList>
|
||||
<CommandEmpty>
|
||||
{isLoading ? 'Carregando...' : 'Nenhum resultado encontrado.'}
|
||||
</CommandEmpty>
|
||||
<CommandGroup>
|
||||
{gEmolumentoPeriodo.map((item) => (
|
||||
<CommandItem
|
||||
key={item.emolumento_periodo_id}
|
||||
value={item.descricao?.toLowerCase() ?? ''}
|
||||
onSelect={() => handleSelect(item.emolumento_periodo_id)}
|
||||
>
|
||||
<CheckIcon
|
||||
className={cn(
|
||||
'mr-2 h-4 w-4',
|
||||
String(selectedId ?? '') === String(item.emolumento_periodo_id)
|
||||
? 'opacity-100'
|
||||
: 'opacity-0'
|
||||
)}
|
||||
/>
|
||||
{GetCapitalize(item.descricao ?? '')}
|
||||
</CommandItem>
|
||||
))}
|
||||
</CommandGroup>
|
||||
</CommandList>
|
||||
</Command>
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
);
|
||||
}
|
||||
|
|
@ -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 GEmolumentoItemInterface from '../../interfaces/GEmolumentoItem/GEmolumentoItemInterface';
|
||||
|
||||
async function executeGEmolumentoItemDeleteData(data: GEmolumentoItemInterface): Promise<ApiResponseInterface> {
|
||||
const api = new API();
|
||||
|
||||
return api.send({
|
||||
method: Methods.DELETE,
|
||||
endpoint: `administrativo/g_emolumento_item/${data.emolumento_item_id}`,
|
||||
});
|
||||
}
|
||||
|
||||
export const GEmolumentoItemDeleteData = withClientErrorHandler(executeGEmolumentoItemDeleteData);
|
||||
|
|
@ -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 GEmolumentoItemIndexInterface from '../../interfaces/GEmolumentoItem/GEmolumentoItemIndexInterface';
|
||||
|
||||
async function executeGEmolumentoItemIndexData(data: GEmolumentoItemIndexInterface): Promise<ApiResponseInterface> {
|
||||
const api = new API();
|
||||
return api.send({
|
||||
method: Methods.GET,
|
||||
endpoint: `administrativo/g_emolumento_item/${data.emolumento_id}/1`,
|
||||
});
|
||||
}
|
||||
|
||||
export const GEmolumentoItemIndexData = withClientErrorHandler(executeGEmolumentoItemIndexData);
|
||||
|
|
@ -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 GEmolumentoItemInterface from '../../interfaces/GEmolumentoItem/GEmolumentoItemInterface';
|
||||
|
||||
async function executeGEmolumentoItemSaveData(data: GEmolumentoItemInterface): Promise<ApiResponseInterface> {
|
||||
// Verifica se existe ID para decidir se é atualização (PUT) ou criação (POST)
|
||||
const isUpdate = Boolean(data.emolumento_item_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_item/${data.emolumento_item_id || ''}`, // endpoint dinâmico
|
||||
body: data, // payload enviado para a API
|
||||
});
|
||||
}
|
||||
|
||||
export const GEmolumentoItemSaveData = withClientErrorHandler(executeGEmolumentoItemSaveData);
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
import { useState } from 'react';
|
||||
|
||||
import { useResponse } from '@/shared/components/response/ResponseContext';
|
||||
|
||||
import GEmolumentoItemInterface from '../../interfaces/GEmolumentoItem/GEmolumentoItemInterface';
|
||||
import { GEmolumentoItemDeleteService } from '../../services/GEmolumentoItem/GEmolumentoItemDeleteService';
|
||||
|
||||
export const useGEmolumentoItemDeleteHook = () => {
|
||||
const { setResponse } = useResponse();
|
||||
|
||||
const [gGramatica, setGEmolumentoItem] = useState<GEmolumentoItemInterface>();
|
||||
|
||||
const deleteGEmolumentoItem = async (data: GEmolumentoItemInterface) => {
|
||||
const response = await GEmolumentoItemDeleteService(data);
|
||||
|
||||
setGEmolumentoItem(data);
|
||||
setResponse(response);
|
||||
};
|
||||
|
||||
return { gGramatica, deleteGEmolumentoItem };
|
||||
};
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
import { zodResolver } from '@hookform/resolvers/zod';
|
||||
import { useForm } from 'react-hook-form';
|
||||
|
||||
import { GEmolumentoItemFormValues, GEmolumentoItemSchema } from '../../schemas/GEmolumentoItem/GEmolumentoItemSchema';
|
||||
|
||||
export function useGEmolumentoItemFormHook(defaults?: Partial<GEmolumentoItemFormValues>) {
|
||||
return useForm<GEmolumentoItemFormValues>({
|
||||
resolver: zodResolver(GEmolumentoItemSchema),
|
||||
defaultValues: {
|
||||
emolumento_id: 0,
|
||||
...defaults,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
'use client';
|
||||
|
||||
import { useState } from 'react';
|
||||
|
||||
import { useResponse } from '@/shared/components/response/ResponseContext';
|
||||
|
||||
import GEmolumentoItemIndexInterface from '../../interfaces/GEmolumentoItem/GEmolumentoItemIndexInterface';
|
||||
import GEmolumentoItemInterface from '../../interfaces/GEmolumentoItem/GEmolumentoItemInterface';
|
||||
import { GEmolumentoItemIndexService } from '../../services/GEmolumentoItem/GEmolumentoItemIndexService';
|
||||
|
||||
export const useGEmolumentoItemIndexHook = () => {
|
||||
const { setResponse } = useResponse();
|
||||
|
||||
const [gEmolumentoItem, setGEmolumentoItem] = useState<GEmolumentoItemInterface[]>([]);
|
||||
|
||||
const indexGEmolumentoItem = async (data: GEmolumentoItemIndexInterface) => {
|
||||
const response = await GEmolumentoItemIndexService(data);
|
||||
// Armazena os dados consultados
|
||||
setGEmolumentoItem(response.data);
|
||||
// Define a resposta (toast, modal, feedback, etc.)
|
||||
setResponse(response);
|
||||
};
|
||||
|
||||
return {
|
||||
gEmolumentoItem,
|
||||
indexGEmolumentoItem,
|
||||
};
|
||||
};
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
'use client';
|
||||
|
||||
import { useState } from 'react';
|
||||
|
||||
import { useResponse } from '@/shared/components/response/ResponseContext';
|
||||
|
||||
import GEmolumentoItemInterface from '../../interfaces/GEmolumentoItem/GEmolumentoItemInterface';
|
||||
import { GEmolumentoItemSaveService } from '../../services/GEmolumentoItem/GEmolumentoItemSaveService';
|
||||
|
||||
export const useGEmolumentoItemSaveHook = () => {
|
||||
const { setResponse } = useResponse();
|
||||
|
||||
const [gEmolumentoItem, setGEmolumentoItem] = useState<GEmolumentoItemInterface | null>(null);
|
||||
|
||||
// controla se o formulário está aberto ou fechado
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
|
||||
const saveGEmolumentoItem = async (data: GEmolumentoItemInterface) => {
|
||||
const response = await GEmolumentoItemSaveService(data);
|
||||
|
||||
// Armazena os dados da resposta
|
||||
setGEmolumentoItem(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 { gEmolumentoItem, saveGEmolumentoItem, isOpen, setIsOpen };
|
||||
};
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
import { GEmolumentoItemFormValues } from '@/packages/administrativo/schemas/GEmolumentoItem/GEmolumentoItemSchema';
|
||||
|
||||
export interface GEmolumentoItemFormInterface {
|
||||
isOpen: boolean;
|
||||
data: GEmolumentoItemFormValues | null;
|
||||
onClose: (item: null, isFormStatus: boolean) => void;
|
||||
onSave: (data: GEmolumentoItemFormValues) => void;
|
||||
buttonIsLoading: boolean;
|
||||
}
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
export default interface GEmolumentoItemIndexInterface {
|
||||
emolumento_id: number;
|
||||
emolumento_periodo_id?: number;
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
export default interface GEmolumentoItemInterface {
|
||||
emolumento_item_id?: number;
|
||||
emolumento_id?: number;
|
||||
descricao?: string;
|
||||
tipo?: string;
|
||||
tipo_lancamento?: string;
|
||||
reg_averb?: string;
|
||||
valor_fixo?: number;
|
||||
percentual?: number;
|
||||
situacao?: string;
|
||||
emolumento_item_ref?: number;
|
||||
observacao?: string;
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
import GEmolumentoItemInterface from './GEmolumentoItemInterface';
|
||||
|
||||
export default interface GEmolumentoItemTableInterface {
|
||||
data?: GEmolumentoItemInterface[];
|
||||
onEdit: (item: GEmolumentoItemInterface, isEditingFormStatus: boolean) => void;
|
||||
onDelete: (item: GEmolumentoItemInterface, isEditingFormStatus: boolean) => void;
|
||||
onSelectedEmolumentoPeriodo: (emolumentoPeriodoId: number) => void;
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
export default interface GEmolumentoPeriodoSelectInterface {
|
||||
onSelectedEmolumentoPeriodo: (emolumentoPeriodoId: number) => void;
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
import z from "zod";
|
||||
|
||||
export const GEmolumentoItemSchema = z.object({
|
||||
emolumento_item_id: z.number().optional(),
|
||||
emolumento_id: z.number().optional(),
|
||||
descricao: z.string().max(260).optional(),
|
||||
tipo: z.string().max(1).optional(),
|
||||
tipo_lancamento: z.string().max(1).optional(),
|
||||
reg_averb: z.string().max(1).optional(),
|
||||
valor_fixo: z.number().optional(),
|
||||
percentual: z.number().optional(),
|
||||
situacao: z.string().max(1).optional(),
|
||||
emolumento_item_ref: z.number().optional(),
|
||||
observacao: z.string().max(260).optional(),
|
||||
});
|
||||
|
||||
export type GEmolumentoItemFormValues = z.infer<typeof GEmolumentoItemSchema>;
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
|
||||
import { withClientErrorHandler } from '@/shared/actions/withClientErrorHandler/withClientErrorHandler';
|
||||
|
||||
import { GEmolumentoItemDeleteData } from '../../data/GEmolumentoItem/GEmolumentoItemDeleteData';
|
||||
import GEmolumentoItemInterface from '../../interfaces/GEmolumentoItem/GEmolumentoItemInterface';
|
||||
|
||||
|
||||
async function executeGEmolumentoItemDeleteService(data: GEmolumentoItemInterface) {
|
||||
const response = await GEmolumentoItemDeleteData(data);
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
export const GEmolumentoItemDeleteService = withClientErrorHandler(executeGEmolumentoItemDeleteService);
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
import { withClientErrorHandler } from '@/shared/actions/withClientErrorHandler/withClientErrorHandler';
|
||||
|
||||
import { GEmolumentoItemIndexData } from '../../data/GEmolumentoItem/GEmolumentoItemIndexData';
|
||||
import GEmolumentoItemIndexInterface from '../../interfaces/GEmolumentoItem/GEmolumentoItemIndexInterface';
|
||||
|
||||
export default async function executeGEmolumentoItemIndexService(data: GEmolumentoItemIndexInterface) {
|
||||
const response = await GEmolumentoItemIndexData(data);
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
export const GEmolumentoItemIndexService = withClientErrorHandler(executeGEmolumentoItemIndexService);
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
import { withClientErrorHandler } from '@/shared/actions/withClientErrorHandler/withClientErrorHandler';
|
||||
|
||||
import { GEmolumentoItemSaveData } from '../../data/GEmolumentoItem/GEmolumentoItemSaveData';
|
||||
import GEmolumentoItemInterface from '../../interfaces/GEmolumentoItem/GEmolumentoItemInterface';
|
||||
|
||||
async function executeGEmolumentoItemSaveService(data: GEmolumentoItemInterface) {
|
||||
const response = await GEmolumentoItemSaveData(data);
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
export const GEmolumentoItemSaveService = withClientErrorHandler(executeGEmolumentoItemSaveService);
|
||||
Loading…
Add table
Reference in a new issue