diff --git a/src/app/(protected)/(administrativo)/administrativo/censec/naturezas/page.tsx b/src/app/(protected)/(administrativo)/administrativo/censec/naturezas/page.tsx new file mode 100644 index 0000000..e77066d --- /dev/null +++ b/src/app/(protected)/(administrativo)/administrativo/censec/naturezas/page.tsx @@ -0,0 +1,9 @@ +'use client'; + +import TCensecTipoNaturezaIndex from "@/packages/administrativo/components/TCensecTipoNatureza/TCensecTipoNaturezaIndex"; + +export default function TCensecTipoNaturezaPage() { + return ( + < TCensecTipoNaturezaIndex /> + ); +} diff --git a/src/app/(protected)/(administrativo)/administrativo/censec/qualidades/page.tsx b/src/app/(protected)/(administrativo)/administrativo/censec/qualidades/page.tsx index 234dcb3..94b9d04 100644 --- a/src/app/(protected)/(administrativo)/administrativo/censec/qualidades/page.tsx +++ b/src/app/(protected)/(administrativo)/administrativo/censec/qualidades/page.tsx @@ -2,7 +2,7 @@ import TCensecQualidadeIndex from "@/packages/administrativo/components/TCensecQualidade/TCensecQualidadeIndex"; -export default function TImovelRuralPage() { +export default function TCensecQualidadePage() { return ( < TCensecQualidadeIndex /> ); diff --git a/src/components/app-sidebar.tsx b/src/components/app-sidebar.tsx index 60b7305..7d7d275 100644 --- a/src/components/app-sidebar.tsx +++ b/src/components/app-sidebar.tsx @@ -137,6 +137,10 @@ const data = { title: "Censec/Qualidades", url: "/administrativo/censec/qualidades" }, + { + title: "Censec/Qualidades", + url: "/administrativo/censec/naturezas" + }, { title: 'Censec/Centrais', url: '/cadastros/censec/', diff --git a/src/packages/administrativo/components/TCensecTipoAto/TCensecTipoAtoSelect.tsx b/src/packages/administrativo/components/TCensecTipoAto/TCensecTipoAtoSelect.tsx new file mode 100644 index 0000000..bcf5ab6 --- /dev/null +++ b/src/packages/administrativo/components/TCensecTipoAto/TCensecTipoAtoSelect.tsx @@ -0,0 +1,92 @@ +'use client'; + +import React from "react"; +import { Button } from "@/components/ui/button"; +import { + Command, + CommandEmpty, + CommandGroup, + CommandInput, + CommandItem, + CommandList, +} from "@/components/ui/command"; +import { FormControl } from "@/components/ui/form"; +import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover"; +import { cn } from "@/lib/utils"; +import { CheckIcon, ChevronsUpDownIcon } from "lucide-react"; +import GetCapitalize from "@/shared/actions/text/GetCapitalize"; +import { useTCensecTipoAtoReadHook } from "@/app/(protected)/(cadastros)/cadastros/_hooks/t_censec_tipoato/useTCensecTipoAtoReadHook"; + +export default function TCensecTipoAtoSelect({ field }: any) { + const [open, setOpen] = React.useState(false); + const [isLoading, setIsLoading] = React.useState(false); + const { tCensecTipoAto, fetchTCensecTipoAto } = useTCensecTipoAtoReadHook(); + // Busca os dados uma única vez ao montar + React.useEffect(() => { + const loadData = async () => { + if (!tCensecTipoAto.length) { + setIsLoading(true); + await fetchTCensecTipoAto(); + setIsLoading(false); + } + }; + loadData(); + }, []); + const selected = tCensecTipoAto.find( + (item) => String(item.censec_tipoato_id) === String(field.value) + ); + return ( + + + + + + + + + + + + {isLoading ? "Carregando..." : "Nenhum resultado encontrado."} + + + {tCensecTipoAto?.map((item) => ( + { + field.onChange(Number(item.censec_tipoato_id)); + setOpen(false); + }} + > + + {GetCapitalize(item.descricao)} + + ))} + + + + + + ); +} diff --git a/src/packages/administrativo/components/TCensecTipoNatureza/TCensecTipoNaturezaColumns.tsx b/src/packages/administrativo/components/TCensecTipoNatureza/TCensecTipoNaturezaColumns.tsx new file mode 100644 index 0000000..c01df6f --- /dev/null +++ b/src/packages/administrativo/components/TCensecTipoNatureza/TCensecTipoNaturezaColumns.tsx @@ -0,0 +1,97 @@ +import { ColumnDef } from "@tanstack/react-table"; +import TCensecTipoNaturezaInterface from "../../interfaces/TCensecTipoNatureza/TCensecTipoNaturezaInterface"; +import { Button } from "@/components/ui/button"; +import { + EllipsisIcon, + PencilIcon, + Trash2Icon, +} from "lucide-react"; +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuGroup, + DropdownMenuItem, + DropdownMenuSeparator, + DropdownMenuTrigger, +} from "@/components/ui/dropdown-menu"; +import { SortableHeader } from "@/shared/components/dataTable/SortableHeader"; +import GetCapitalize from "@/shared/actions/text/GetCapitalize"; +import { ConfirmacaoEnum } from "@/shared/enums/ConfirmacaoEnum"; +import { TipoAtoAnteriorEnum } from "@/shared/enums/TipoAtoAnteriorEnum"; + +export default function TCensecTipoNaturezaColumns( + onEdit: (item: TCensecTipoNaturezaInterface, isEditingFormStatus: boolean) => void, + onDelete: (item: TCensecTipoNaturezaInterface, isEditingFormStatus: boolean) => void +): ColumnDef[] { + return [ + // ID + { + accessorKey: "censec_tiponatureza_id", + header: ({ column }) => SortableHeader("#", column), + cell: ({ row }) => Number(row.getValue("censec_tiponatureza_id")), + enableSorting: false, + }, + // descricao + { + accessorKey: "descricao", + header: ({ column }) => SortableHeader("Descrição", column), + cell: ({ row }) => GetCapitalize(row.getValue("descricao")), + }, + // possui_ato_anterior + { + accessorKey: "possui_ato_anterior", + header: ({ column }) => SortableHeader("Possui Ato Anterior", column), + cell: ({ row }) => { + const value = row.getValue("possui_ato_anterior") as keyof typeof ConfirmacaoEnum; + return ConfirmacaoEnum[value] ?? "-"; + }, + }, + // situacao_ato_anterior + { + accessorKey: "situacao_ato_anterior", + header: ({ column }) => SortableHeader("Situação Ato Anterior", column), + cell: ({ row }) => { + const value = Number(row.getValue("situacao_ato_anterior")); + const label = Object.prototype.hasOwnProperty.call(TipoAtoAnteriorEnum, value) + ? TipoAtoAnteriorEnum[value as keyof typeof TipoAtoAnteriorEnum] + : "-"; + return label; + }, + }, + // Ações + { + id: "actions", + header: "Ações", + cell: ({ row }) => { + const imovel = row.original; + return ( + + + + + + + onEdit(imovel, true)}> + + Editar + + + onDelete(imovel, true)} + > + + Remover + + + + + ); + }, + enableSorting: false, + enableHiding: false, + }, + ]; +} diff --git a/src/packages/administrativo/components/TCensecTipoNatureza/TCensecTipoNaturezaForm.tsx b/src/packages/administrativo/components/TCensecTipoNatureza/TCensecTipoNaturezaForm.tsx new file mode 100644 index 0000000..cc746c6 --- /dev/null +++ b/src/packages/administrativo/components/TCensecTipoNatureza/TCensecTipoNaturezaForm.tsx @@ -0,0 +1,199 @@ +'use client'; + +import React, { useEffect } from 'react'; + +import { Button } from '@/components/ui/button'; +import { + Dialog, + DialogClose, + DialogContent, + DialogDescription, + DialogFooter, + DialogHeader, + DialogTitle, +} from '@/components/ui/dialog'; +import { + Form, + FormControl, + FormField, + FormItem, + FormLabel, + FormMessage, +} from '@/components/ui/form'; +import { Input } from '@/components/ui/input'; + +import LoadingButton from '@/shared/components/loadingButton/LoadingButton'; +import { ResetFormIfData } from '@/shared/actions/form/ResetFormIfData'; +import { useTCensecTipoNaturezaFormHook } from '../../hooks/TCensecTipoNatureza/useTCensecTipoNaturezaFormHook'; +import { TCensecTipoNaturezaFormInterface } from '../../interfaces/TCensecTipoNatureza/TCensecTipoNaturezaFormInterface'; +import { parseNumberInput } from '@/shared/actions/form/parseNumberInput'; +import TCensecTipoAtoSelect from '../TCensecTipoAto/TCensecTipoAtoSelect'; +import ConfirmacaoSelect from '@/shared/components/confirmacao/ConfirmacaoSelect'; +import TipoAtoAnteriorSelect from '@/shared/components/tipoAtoAnterior/TipoAtoAnteriorSelect'; +import TipoNaturezaSelect from '@/shared/components/tipoNatureza/TipoNaturezaSelect'; + +export default function TCensecTipoNaturezaForm({ isOpen, data, onClose, onSave, buttonIsLoading }: TCensecTipoNaturezaFormInterface) { + + // Inicializa o react-hook-form com schema zod + const form = useTCensecTipoNaturezaFormHook({}); + + // Atualiza o formulário quando recebe dados para edição + useEffect(() => { + + // Se existir dados, reseta o formulário com os mesmos + ResetFormIfData(form, data); + + }, [data, form]); + + function onError(error: any) { + console.log(error); + } + + return ( + { + if (!open) onClose(null, false); + }} + > + + + + Censec tipos de natureza + + + Censec tipos de natureza + + +
+ +
+ {/* Descrição */} +
+ ( + + Descrição + + + + + + )} + /> +
+ + {/* Tipo do Ato */} +
+ ( + + Tipo do Ato + < TCensecTipoAtoSelect field={field} /> + + + )} + /> +
+ + {/* Possui Ato Anterior */} +
+ ( + + Possui Ato Anterior + + + + + + )} + /> +
+ {/* tipo_ato_anterior */} +
+ ( + + Natureza + + + + )} + /> +
+ {/* Situação */} +
+ ( + + Situação + + + + )} + /> +
+ {/* Código CENSEC */} +
+ ( + + Código CENSEC + + + + + + )} + /> +
+ {/* Código */} +
+ ( + + Código + + field.onChange(parseNumberInput(e))} /> + + + + )} + /> +
+
+ {/* Rodapé do Dialog */} + + + + + + +
+ +
+
+ ); +} \ No newline at end of file diff --git a/src/packages/administrativo/components/TCensecTipoNatureza/TCensecTipoNaturezaIndex.tsx b/src/packages/administrativo/components/TCensecTipoNatureza/TCensecTipoNaturezaIndex.tsx new file mode 100644 index 0000000..74bed20 --- /dev/null +++ b/src/packages/administrativo/components/TCensecTipoNatureza/TCensecTipoNaturezaIndex.tsx @@ -0,0 +1,172 @@ +'use client'; + +import { useEffect, useState, useCallback } from 'react'; + +import Loading from '@/shared/components/loading/loading'; + +import { useTCensecTipoNaturezaIndexHook } from '@/packages/administrativo/hooks/TCensecTipoNatureza/useTCensecTipoNaturezaIndexHook'; +import { useTCensecTipoNaturezaSaveHook } from '@/packages/administrativo/hooks/TCensecTipoNatureza/useTCensecTipoNaturezaSaveHook'; +import { useTCensecTipoNaturezaDeleteHook } from '@/packages/administrativo/hooks/TCensecTipoNatureza/useTCensecTipoNaturezaDeleteHook'; + +import ConfirmDialog from '@/shared/components/confirmDialog/ConfirmDialog'; +import { useConfirmDialog } from '@/shared/components/confirmDialog/useConfirmDialog'; + +import TCensecTipoNaturezaInterface from '@/packages/administrativo/interfaces/TCensecTipoNatureza/TCensecTipoNaturezaInterface'; +import Header from '@/shared/components/structure/Header'; +import TCensecTipoNaturezaTable from './TCensecTipoNaturezaTable'; +import TCensecTipoNaturezaForm from './TCensecTipoNaturezaForm'; + +export default function TCensecTipoNaturezaIndex() { + + // Controle de estado do botão + const [buttonIsLoading, setButtonIsLoading] = useState(false); + + // Hooks para leitura e salvamento + const { tCensecNaturezaTipo, indexTCensecTipoNatureza } = useTCensecTipoNaturezaIndexHook(); + const { saveTCensecTipoNatureza } = useTCensecTipoNaturezaSaveHook(); + const { deleteTCensecTipoNatureza } = useTCensecTipoNaturezaDeleteHook(); + + // Estados + const [selectedData, setSelectedData] = useState(null); + const [isFormOpen, setIsFormOpen] = useState(false); + + // Estado para saber qual item será deletado + const [itemToDelete, setItemToDelete] = useState(null); + + /** + * Hook do modal de confirmação + */ + const { + isOpen: isConfirmOpen, + openDialog: openConfirmDialog, + handleConfirm, + handleCancel, + } = useConfirmDialog(); + + /** + * Abre o formulário no modo de edição ou criação + */ + const handleOpenForm = useCallback((data: TCensecTipoNaturezaInterface | null) => { + // Se não houver dados (criação), cria um objeto inicial com pessoa_tipo + 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: TCensecTipoNaturezaInterface) => { + // Coloca o botão em estado de loading + setButtonIsLoading(true); + + // Aguarda salvar o registro + await saveTCensecTipoNatureza(formData); + + // Remove o botão em estado de loading + setButtonIsLoading(false); + + // Atualiza a lista de dados + indexTCensecTipoNatureza(); + }, + [saveTCensecTipoNatureza, indexTCensecTipoNatureza, handleCloseForm], + ); + + /** + * Quando o usuário clica em "remover" na tabela + */ + const handleConfirmDelete = useCallback( + (item: TCensecTipoNaturezaInterface) => { + // 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 deleteTCensecTipoNatureza(itemToDelete); + + // Atualiza a lista + await indexTCensecTipoNatureza(); + + // Limpa o item selecionado + setItemToDelete(null); + + // Fecha o modal + handleCancel(); + }, [itemToDelete, indexTCensecTipoNatureza, handleCancel]); + + /** + * Busca inicial dos dados + */ + useEffect(() => { + indexTCensecTipoNatureza(); + }, []); + + /** + * Tela de loading enquanto carrega os dados + */ + if (tCensecNaturezaTipo?.length == 0) { + return ; + } + + return ( +
+ {/* Cabeçalho */} +
{ + handleOpenForm(null); + }} + /> + {/* Tabela de andamentos */} + + {/* Modal de confirmação */} + {isConfirmOpen && ( + + )} + {/* Formulário de criação/edição */} + {isFormOpen && ( + + )} +
+ ); +} diff --git a/src/packages/administrativo/components/TCensecTipoNatureza/TCensecTipoNaturezaTable.tsx b/src/packages/administrativo/components/TCensecTipoNatureza/TCensecTipoNaturezaTable.tsx new file mode 100644 index 0000000..602d0a4 --- /dev/null +++ b/src/packages/administrativo/components/TCensecTipoNatureza/TCensecTipoNaturezaTable.tsx @@ -0,0 +1,22 @@ +'use client'; + +import { DataTable } from '@/shared/components/dataTable/DataTable'; +import TCensecTipoNaturezaColumns from './TCensecTipoNaturezaColumns'; +import TCensecTipoNaturezaTableInterface from '../../interfaces/TCensecTipoNatureza/TCensecTipoNaturezaTableInterface'; + +/** + * Componente principal da tabela + */ +export default function TCensecTipoNaturezaTable({ data, onEdit, onDelete }: TCensecTipoNaturezaTableInterface) { + const columns = TCensecTipoNaturezaColumns(onEdit, onDelete); + return ( +
+ +
+ ); +} \ No newline at end of file diff --git a/src/packages/administrativo/data/TCensecTipoNatureza/TCensecTipoNaturezaDeleteData.ts b/src/packages/administrativo/data/TCensecTipoNatureza/TCensecTipoNaturezaDeleteData.ts new file mode 100644 index 0000000..0a4d210 --- /dev/null +++ b/src/packages/administrativo/data/TCensecTipoNatureza/TCensecTipoNaturezaDeleteData.ts @@ -0,0 +1,18 @@ +import { withClientErrorHandler } from "@/shared/actions/withClientErrorHandler/withClientErrorHandler"; +import ApiResponseInterface from "@/shared/services/api/interfaces/ApiResponseInterface"; +import API from "@/shared/services/api/Api"; +import { Methods } from "@/shared/services/api/enums/ApiMethodEnum"; +import TCensecTipoNaturezaInterface from "../../interfaces/TCensecTipoNatureza/TCensecTipoNaturezaInterface"; + +async function executeTCensecTipoNaturezaDeleteData(data: TCensecTipoNaturezaInterface): Promise { + + const api = new API(); + + return await api.send({ + method: Methods.DELETE, + endpoint: `administrativo/t_censec_tiponatureza/${data.censec_tiponatureza_id}` + }); + +} + +export const TCensecTipoNaturezaDeleteData = withClientErrorHandler(executeTCensecTipoNaturezaDeleteData); \ No newline at end of file diff --git a/src/packages/administrativo/data/TCensecTipoNatureza/TCensecTipoNaturezaIndexData.ts b/src/packages/administrativo/data/TCensecTipoNatureza/TCensecTipoNaturezaIndexData.ts new file mode 100644 index 0000000..829179f --- /dev/null +++ b/src/packages/administrativo/data/TCensecTipoNatureza/TCensecTipoNaturezaIndexData.ts @@ -0,0 +1,14 @@ +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 executeTCensecTipoNaturezaIndexData(): Promise { + const api = new API(); + return api.send({ + method: Methods.GET, + endpoint: `administrativo/t_censec_tiponatureza` + }); +} + +export const TCensecTipoNaturezaIndexData = withClientErrorHandler(executeTCensecTipoNaturezaIndexData); \ No newline at end of file diff --git a/src/packages/administrativo/data/TCensecTipoNatureza/TCensecTipoNaturezaSaveData.ts b/src/packages/administrativo/data/TCensecTipoNatureza/TCensecTipoNaturezaSaveData.ts new file mode 100644 index 0000000..cfa9cd2 --- /dev/null +++ b/src/packages/administrativo/data/TCensecTipoNatureza/TCensecTipoNaturezaSaveData.ts @@ -0,0 +1,26 @@ +import { withClientErrorHandler } from "@/shared/actions/withClientErrorHandler/withClientErrorHandler"; +import TCensecTipoNaturezaInterface from "../../interfaces/TCensecTipoNatureza/TCensecTipoNaturezaInterface"; +import ApiResponseInterface from "@/shared/services/api/interfaces/ApiResponseInterface"; +import API from "@/shared/services/api/Api"; +import { Methods } from "@/shared/services/api/enums/ApiMethodEnum"; + +async function executeTCensecTipoNaturezaSaveData(data: TCensecTipoNaturezaInterface): Promise { + + console.log('executeTCensecTipoNaturezaSaveData', data) + + // Verifica se existe ID da cidade para decidir se é atualização (PUT) ou criação (POST) + const isUpdate = Boolean(data.censec_tiponatureza_id); + + // Instancia o cliente da API para enviar a requisição + const api = new API(); + + // Executa a requisição para a API com o método apropriado e envia os dados no corpo + return await api.send({ + method: isUpdate ? Methods.PUT : Methods.POST, // PUT se atualizar, POST se criar + endpoint: `administrativo/t_censec_tiponatureza/${data.censec_tiponatureza_id || ''}`, // endpoint dinâmico + body: data, // payload enviado para a API + }); + +} + +export const TCensecTipoNaturezaSaveData = withClientErrorHandler(executeTCensecTipoNaturezaSaveData); \ No newline at end of file diff --git a/src/packages/administrativo/hooks/TCensecTipoNatureza/useTCensecTipoNaturezaDeleteHook.ts b/src/packages/administrativo/hooks/TCensecTipoNatureza/useTCensecTipoNaturezaDeleteHook.ts new file mode 100644 index 0000000..f30e164 --- /dev/null +++ b/src/packages/administrativo/hooks/TCensecTipoNatureza/useTCensecTipoNaturezaDeleteHook.ts @@ -0,0 +1,20 @@ +import { useResponse } from '@/shared/components/response/ResponseContext'; +import { useState } from 'react'; +import TCensecTipoNaturezaInterface from '../../interfaces/TCensecTipoNatureza/TCensecTipoNaturezaInterface'; +import { TCensecTipoNaturezaDeleteService } from '../../services/TCensecTipoNatureza/TCensecTipoNaturezaDeleteService'; + +export const useTCensecTipoNaturezaDeleteHook = () => { + const { setResponse } = useResponse(); + + const [tAtoParteTipo, setTCensecTipoNatureza] = useState(); + + const deleteTCensecTipoNatureza = async (data: TCensecTipoNaturezaInterface) => { + const response = await TCensecTipoNaturezaDeleteService(data); + + setTCensecTipoNatureza(data); + + setResponse(response); + }; + + return { tAtoParteTipo, deleteTCensecTipoNatureza }; +}; diff --git a/src/packages/administrativo/hooks/TCensecTipoNatureza/useTCensecTipoNaturezaFormHook.ts b/src/packages/administrativo/hooks/TCensecTipoNatureza/useTCensecTipoNaturezaFormHook.ts new file mode 100644 index 0000000..75d0c83 --- /dev/null +++ b/src/packages/administrativo/hooks/TCensecTipoNatureza/useTCensecTipoNaturezaFormHook.ts @@ -0,0 +1,13 @@ +import { useForm } from "react-hook-form"; +import { TCensecTipoNaturezaFormValues, TCensecTipoNaturezaSchema } from "../../schemas/TCensecTipoNatureza/TCensecTipoNaturezaSchema"; +import { zodResolver } from "@hookform/resolvers/zod"; + +export function useTCensecTipoNaturezaFormHook(defaults?: Partial) { + return useForm({ + resolver: zodResolver(TCensecTipoNaturezaSchema), + defaultValues: { + censec_tiponatureza_id: 0, + ...defaults, + }, + }); +} \ No newline at end of file diff --git a/src/packages/administrativo/hooks/TCensecTipoNatureza/useTCensecTipoNaturezaIndexHook.ts b/src/packages/administrativo/hooks/TCensecTipoNatureza/useTCensecTipoNaturezaIndexHook.ts new file mode 100644 index 0000000..2e0f39f --- /dev/null +++ b/src/packages/administrativo/hooks/TCensecTipoNatureza/useTCensecTipoNaturezaIndexHook.ts @@ -0,0 +1,25 @@ +'use client'; + +import { useResponse } from '@/shared/components/response/ResponseContext'; +import { useState } from 'react'; +import TCensecTipoNaturezaInterface from '../../interfaces/TCensecTipoNatureza/TCensecTipoNaturezaInterface'; +import { TCensecTipoNaturezaIndexService } from '../../services/TCensecTipoNatureza/TCensecTipoNaturezaIndexService'; + +export const useTCensecTipoNaturezaIndexHook = () => { + const { setResponse } = useResponse(); + + const [tCensecNaturezaTipo, setTCensecTipoNatureza] = useState([]); + + const indexTCensecTipoNatureza = async () => { + const response = await TCensecTipoNaturezaIndexService(); + // Armazena os dados consultados + setTCensecTipoNatureza(response.data); + // Define os dados do componente de resposta (toast, modal, etc) + setResponse(response); + }; + + return { + tCensecNaturezaTipo, + indexTCensecTipoNatureza + }; +}; diff --git a/src/packages/administrativo/hooks/TCensecTipoNatureza/useTCensecTipoNaturezaSaveHook.ts b/src/packages/administrativo/hooks/TCensecTipoNatureza/useTCensecTipoNaturezaSaveHook.ts new file mode 100644 index 0000000..fae2805 --- /dev/null +++ b/src/packages/administrativo/hooks/TCensecTipoNatureza/useTCensecTipoNaturezaSaveHook.ts @@ -0,0 +1,33 @@ +'use client'; + +import { useResponse } from '@/shared/components/response/ResponseContext'; +import { useState } from 'react'; +import TCensecTipoNaturezaInterface from '../../interfaces/TCensecTipoNatureza/TCensecTipoNaturezaInterface'; +import { TCensecTipoNaturezaSaveService } from '../../services/TCensecTipoNatureza/TCensecTipoNaturezaSaveService'; + +export const useTCensecTipoNaturezaSaveHook = () => { + const { setResponse } = useResponse(); + + const [tAtoParteTipo, setTCensecTipoNatureza] = useState(); + + // controla se o formulário está aberto ou fechado + const [isOpen, setIsOpen] = useState(false); + + const saveTCensecTipoNatureza = async (data: TCensecTipoNaturezaInterface) => { + const response = await TCensecTipoNaturezaSaveService(data); + + // Armazena os dados da repsota + setTCensecTipoNatureza(response.data); + + // Define os dados da respota(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 { tAtoParteTipo, saveTCensecTipoNatureza }; +}; diff --git a/src/packages/administrativo/interfaces/TCensecTipoNatureza/TCensecTipoNaturezaFormInterface.ts b/src/packages/administrativo/interfaces/TCensecTipoNatureza/TCensecTipoNaturezaFormInterface.ts new file mode 100644 index 0000000..19f59c7 --- /dev/null +++ b/src/packages/administrativo/interfaces/TCensecTipoNatureza/TCensecTipoNaturezaFormInterface.ts @@ -0,0 +1,9 @@ +import { TCensecTipoNaturezaFormValues } from "../../schemas/TCensecTipoNatureza/TCensecTipoNaturezaSchema"; + +export interface TCensecTipoNaturezaFormInterface { + isOpen: boolean; + data: TCensecTipoNaturezaFormValues | null; + onClose: (item: null, isFormStatus: boolean) => void; + onSave: (data: TCensecTipoNaturezaFormValues) => void; + buttonIsLoading: boolean; +} \ No newline at end of file diff --git a/src/packages/administrativo/interfaces/TCensecTipoNatureza/TCensecTipoNaturezaInterface.ts b/src/packages/administrativo/interfaces/TCensecTipoNatureza/TCensecTipoNaturezaInterface.ts new file mode 100644 index 0000000..6837b49 --- /dev/null +++ b/src/packages/administrativo/interfaces/TCensecTipoNatureza/TCensecTipoNaturezaInterface.ts @@ -0,0 +1,10 @@ +export default interface TCensecTipoNaturezaInterface { + censec_tiponatureza_id?: number; + censec_tipoato_id?: number; + descricao?: string; + possui_ato_anterior?: string; + codigo?: number; + obrigatorio?: string; + tipo_ato_anterior?: string; + situacao_ato_anterior?: string; +} \ No newline at end of file diff --git a/src/packages/administrativo/interfaces/TCensecTipoNatureza/TCensecTipoNaturezaTableInterface.ts b/src/packages/administrativo/interfaces/TCensecTipoNatureza/TCensecTipoNaturezaTableInterface.ts new file mode 100644 index 0000000..b241f15 --- /dev/null +++ b/src/packages/administrativo/interfaces/TCensecTipoNatureza/TCensecTipoNaturezaTableInterface.ts @@ -0,0 +1,7 @@ +import TCensecTipoNaturezaInterface from "./TCensecTipoNaturezaInterface"; + +export default interface TCensecTipoNaturezaTableInterface { + data?: TCensecTipoNaturezaInterface[]; + onEdit: (item: TCensecTipoNaturezaInterface, isEditingFormStatus: boolean) => void; + onDelete: (item: TCensecTipoNaturezaInterface, isEditingFormStatus: boolean) => void; +} \ No newline at end of file diff --git a/src/packages/administrativo/schemas/TCensecTipoNatureza/TCensecTipoNaturezaSchema.ts b/src/packages/administrativo/schemas/TCensecTipoNatureza/TCensecTipoNaturezaSchema.ts new file mode 100644 index 0000000..13ce350 --- /dev/null +++ b/src/packages/administrativo/schemas/TCensecTipoNatureza/TCensecTipoNaturezaSchema.ts @@ -0,0 +1,14 @@ +import z from "zod"; + +export const TCensecTipoNaturezaSchema = z.object({ + censec_tiponatureza_id: z.number().optional(), + censec_tipoato_id: z.number().optional(), + descricao: z.string().optional(), + possui_ato_anterior: z.string().optional(), + codigo: z.number().optional(), + obrigatorio: z.string().optional(), + tipo_ato_anterior: z.string().optional(), + situacao_ato_anterior: z.string().optional(), +}); + +export type TCensecTipoNaturezaFormValues = z.infer; \ No newline at end of file diff --git a/src/packages/administrativo/services/TCensecTipoNatureza/TCensecTipoNaturezaDeleteService.ts b/src/packages/administrativo/services/TCensecTipoNatureza/TCensecTipoNaturezaDeleteService.ts new file mode 100644 index 0000000..52e3665 --- /dev/null +++ b/src/packages/administrativo/services/TCensecTipoNatureza/TCensecTipoNaturezaDeleteService.ts @@ -0,0 +1,11 @@ +import { withClientErrorHandler } from '@/shared/actions/withClientErrorHandler/withClientErrorHandler'; +import TCensecTipoNaturezaInterface from '../../interfaces/TCensecTipoNatureza/TCensecTipoNaturezaInterface'; +import { TCensecTipoNaturezaDeleteData } from '../../data/TCensecTipoNatureza/TCensecTipoNaturezaDeleteData'; + +async function executeTCensecTipoNaturezaDeleteService(data: TCensecTipoNaturezaInterface) { + const response = await TCensecTipoNaturezaDeleteData(data); + + return response; +} + +export const TCensecTipoNaturezaDeleteService = withClientErrorHandler(executeTCensecTipoNaturezaDeleteService); diff --git a/src/packages/administrativo/services/TCensecTipoNatureza/TCensecTipoNaturezaIndexService.ts b/src/packages/administrativo/services/TCensecTipoNatureza/TCensecTipoNaturezaIndexService.ts new file mode 100644 index 0000000..1a4ce87 --- /dev/null +++ b/src/packages/administrativo/services/TCensecTipoNatureza/TCensecTipoNaturezaIndexService.ts @@ -0,0 +1,9 @@ +import { withClientErrorHandler } from '@/shared/actions/withClientErrorHandler/withClientErrorHandler'; +import { TCensecTipoNaturezaIndexData } from '../../data/TCensecTipoNatureza/TCensecTipoNaturezaIndexData'; + +export default async function executeTCensecTipoNaturezaIndexService() { + const response = await TCensecTipoNaturezaIndexData(); + return response; +} + +export const TCensecTipoNaturezaIndexService = withClientErrorHandler(executeTCensecTipoNaturezaIndexService); diff --git a/src/packages/administrativo/services/TCensecTipoNatureza/TCensecTipoNaturezaSaveService.ts b/src/packages/administrativo/services/TCensecTipoNatureza/TCensecTipoNaturezaSaveService.ts new file mode 100644 index 0000000..02689f1 --- /dev/null +++ b/src/packages/administrativo/services/TCensecTipoNatureza/TCensecTipoNaturezaSaveService.ts @@ -0,0 +1,11 @@ +import { withClientErrorHandler } from '@/shared/actions/withClientErrorHandler/withClientErrorHandler'; +import TCensecTipoNaturezaInterface from '../../interfaces/TCensecTipoNatureza/TCensecTipoNaturezaInterface'; +import { TCensecTipoNaturezaSaveData } from '../../data/TCensecTipoNatureza/TCensecTipoNaturezaSaveData'; + +async function executeTCensecTipoNaturezaSaveService(data: TCensecTipoNaturezaInterface) { + const response = await TCensecTipoNaturezaSaveData(data); + + return response; +} + +export const TCensecTipoNaturezaSaveService = withClientErrorHandler(executeTCensecTipoNaturezaSaveService); \ No newline at end of file diff --git a/src/shared/components/tipoAtoAnterior/TipoAtoAnteriorSelect.tsx b/src/shared/components/tipoAtoAnterior/TipoAtoAnteriorSelect.tsx new file mode 100644 index 0000000..3370a9b --- /dev/null +++ b/src/shared/components/tipoAtoAnterior/TipoAtoAnteriorSelect.tsx @@ -0,0 +1,61 @@ +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 { TipoAtoAnteriorEnum } from "@/shared/enums/TipoAtoAnteriorEnum"; +import { Command } from "cmdk"; +import { CheckIcon, ChevronsUpDownIcon } from "lucide-react"; +import React from "react"; + +export default function TipoAtoAnteriorSelect({ field }: any) { + const [open, setOpen] = React.useState(false); + + const options = Object.entries(TipoAtoAnteriorEnum).map(([value, label]) => ({ + value, + label, + })); + + return ( + + + + + + + + + + + Nenhum resultado encontrado. + + {options.map((item) => ( + { + field.onChange(item.value); + setOpen(false); + }} + > + + {item.label} + + ))} + + + + + + ); +} diff --git a/src/shared/components/tipoNatureza/TipoNaturezaSelect.tsx b/src/shared/components/tipoNatureza/TipoNaturezaSelect.tsx new file mode 100644 index 0000000..f848f5e --- /dev/null +++ b/src/shared/components/tipoNatureza/TipoNaturezaSelect.tsx @@ -0,0 +1,107 @@ +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 { TipoNaturezaEnum } from "@/shared/enums/TipoNaturezaEnum"; +import { Command } from "cmdk"; +import { CheckIcon, ChevronsUpDownIcon } from "lucide-react"; +import React from "react"; + +export default function TipoNaturezaSelect({ field }: any) { + const [open, setOpen] = React.useState(false); + + // Gera opções a partir do Enum + const options = Object.entries(TipoNaturezaEnum).map(([id, label]) => ({ + value: Number(id), + label, + })); + + // 🔹 Converte valor recebido (string tipo ";0,1,2,3") para array de números + const parseToArray = (value: any): number[] => { + if (!value) return []; + if (Array.isArray(value)) return value.map(Number); + if (typeof value === "string") { + return value + .replace(/^;/, "") // remove o primeiro ";" + .split(",") + .filter(Boolean) + .map((v) => Number(v.trim())); + } + return []; + }; + + // Array de valores selecionados + const selectedValues: number[] = parseToArray(field.value); + + // Atualiza valor selecionado (e reenvia como string ";0,1,2,3") + const toggleSelect = (value: number) => { + let newValues; + if (selectedValues.includes(value)) { + newValues = selectedValues.filter((v) => v !== value); + } else { + newValues = [...selectedValues, value]; + } + // Converte para formato ";0,1,2,3" + const formatted = ";" + newValues.join(","); + field.onChange(formatted); + }; + + // Label do botão (nomes selecionados) + const selectedLabels = options + .filter((opt) => selectedValues.includes(opt.value)) + .map((opt) => opt.label) + .join(", "); + + return ( + + + + + + + + + + + + Nenhum resultado encontrado. + + {options.map((item) => ( + toggleSelect(item.value)} + > + + {item.label} + + ))} + + + + + + ); +} diff --git a/src/shared/enums/TipoAtoAnteriorEnum.ts b/src/shared/enums/TipoAtoAnteriorEnum.ts new file mode 100644 index 0000000..68e0946 --- /dev/null +++ b/src/shared/enums/TipoAtoAnteriorEnum.ts @@ -0,0 +1,8 @@ +export const TipoAtoAnteriorEnum = { + 1: 'Substabelecido', + 2: 'Revogado', + 3: 'Reratificado', + 4: 'Renunciado', + 5: 'Renúncia', + 6: 'Renúncia Parcial' +} as const; \ No newline at end of file diff --git a/src/shared/enums/TipoNaturezaEnum.ts b/src/shared/enums/TipoNaturezaEnum.ts new file mode 100644 index 0000000..d6cb0a0 --- /dev/null +++ b/src/shared/enums/TipoNaturezaEnum.ts @@ -0,0 +1,6 @@ +export const TipoNaturezaEnum = { + 1: 'Escritura', + 2: 'Procuração', + 3: 'Substabelecimento', + 4: 'Testamento', +} as const; \ No newline at end of file