diff --git a/src/app/(protected)/servicos/atos/ato/page.tsx b/src/app/(protected)/servicos/atos/ato/page.tsx new file mode 100644 index 0000000..4ff23d1 --- /dev/null +++ b/src/app/(protected)/servicos/atos/ato/page.tsx @@ -0,0 +1,5 @@ +import TAtoForm from '@/packages/servicos/components/TAto/TAtoForm'; + +export default function TAtoFormPage() { + return ; +} diff --git a/src/app/(protected)/servicos/atos/page.tsx b/src/app/(protected)/servicos/atos/page.tsx new file mode 100644 index 0000000..1f4315a --- /dev/null +++ b/src/app/(protected)/servicos/atos/page.tsx @@ -0,0 +1,5 @@ +import TAtoIndex from '@/packages/servicos/components/TAto/TAtoIndex'; + +export default function TServicoAToPag() { + return ; +} diff --git a/src/components/app-sidebar.tsx b/src/components/app-sidebar.tsx index 57e3990..aaa5c44 100644 --- a/src/components/app-sidebar.tsx +++ b/src/components/app-sidebar.tsx @@ -57,6 +57,10 @@ const data = { title: 'Pedidos', url: '/servicos/pedidos/', }, + { + title: 'Atos', + url: '/servicos/atos/', + }, ], }, { diff --git a/src/middleware.ts b/src/middleware.ts index 7c4c99b..e3f993a 100644 --- a/src/middleware.ts +++ b/src/middleware.ts @@ -17,7 +17,6 @@ export function middleware(request: NextRequest) { return NextResponse.next(); } // ----------------------------------------- - const publicRoute = publicRoutes.find((route) => route.path === path); const authToken = request.cookies.get('access_token'); diff --git a/src/packages/servicos/components/TAto/TAtoColumns.tsx b/src/packages/servicos/components/TAto/TAtoColumns.tsx new file mode 100644 index 0000000..94b1805 --- /dev/null +++ b/src/packages/servicos/components/TAto/TAtoColumns.tsx @@ -0,0 +1,138 @@ +import { ColumnDef } from '@tanstack/react-table'; +import { EllipsisIcon, EyeIcon, PencilIcon, Trash2Icon } from 'lucide-react'; +import Link from 'next/link'; + +import { Button } from '@/components/ui/button'; +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuGroup, + DropdownMenuItem, + DropdownMenuSeparator, + DropdownMenuTrigger, +} from '@/components/ui/dropdown-menu'; +import { FormatDateTime } from '@/shared/actions/dateTime/FormatDateTime'; +import { SortableHeader } from '@/shared/components/dataTable/SortableHeader'; +import { ServicosPedidosSituacoesBadge } from '@/shared/components/servicosPedidosSituacoes/ServicosPedidosSituacoesBadge'; + +import TAtoInterface from '../../interfaces/TAto/TAtoInterface'; + +export default function TAtoColumns( + onEdit: (item: TAtoInterface, isEditingFormStatus: boolean) => void, + onDelete: (item: TAtoInterface, isEditingFormStatus: boolean) => void, +): ColumnDef[] { + return [ + // ID + { + accessorKey: 'ato_id', + header: ({ column }) => SortableHeader('#', column), + cell: ({ row }) => Number(row.getValue('ato_id')), + enableSorting: true, + }, + + // Usuário + { + accessorKey: 'protocolo', + header: ({ column }) => SortableHeader('Protocolo', column), + cell: ({ row }) => row.getValue('protocolo'), + }, + + // Situação + { + accessorKey: 'situacao', + header: ({ column }) => SortableHeader('Situação', column), + cell: ({ row }) => { + return ( + + ); + }, + }, + + // Data Pedido + { + accessorKey: 'data_abertura', + header: ({ column }) => SortableHeader('Abertura', column), + cell: ({ row }) => FormatDateTime(row.getValue('data_abertura')), + }, + + // Data Pedido + { + accessorKey: 'data_lavratura', + header: ({ column }) => SortableHeader('Lavratura', column), + cell: ({ row }) => FormatDateTime(row.getValue('data_lavratura')), + }, + + // Descrição + { + accessorKey: 'descricao', + header: ({ column }) => SortableHeader('Situação', column), + cell: ({ row }) => { + return
{row.getValue('descricao') || '---'}
+ }, + }, + + // Descrição + { + accessorKey: 'numero_livro', + header: ({ column }) => SortableHeader('Livro', column), + cell: ({ row }) => row.getValue('numero_livro'), + }, + + // Descrição + { + accessorKey: 'folha_inicial', + header: ({ column }) => SortableHeader('Fl. Inicial', column), + cell: ({ row }) => row.getValue('folha_inicial'), + }, + + // Descrição + { + accessorKey: 'folha_final', + header: ({ column }) => SortableHeader('Fl. Final', column), + cell: ({ row }) => row.getValue('folha_final'), + }, + + // Ações + { + id: 'actions', + header: 'Ações', + cell: ({ row }) => { + const servicoPedido = row.original; + return ( + + + + + + + + + + Detalhes + + + + + + + Editar + + + + onDelete(servicoPedido, true)}> + + Remover + + + + + ); + }, + enableSorting: false, + enableHiding: false, + }, + ]; +} diff --git a/src/packages/servicos/components/TAto/TAtoForm.tsx b/src/packages/servicos/components/TAto/TAtoForm.tsx new file mode 100644 index 0000000..6fed190 --- /dev/null +++ b/src/packages/servicos/components/TAto/TAtoForm.tsx @@ -0,0 +1,406 @@ +'use client'; + + +import { CreditCardIcon, PackageIcon, UserSquare2Icon } from 'lucide-react'; +import { useMemo } from 'react'; + +import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'; +import { + Form, + FormField, + FormItem, + FormLabel, + FormMessage +} from '@/components/ui/form'; +import { Separator } from '@/components/ui/separator'; +import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table'; +import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'; +import GUsuarioSelect from '@/packages/administrativo/components/GUsuario/GUsuarioSelect'; +import useTAtoFormControllerHook from '@/packages/servicos/hooks/TAto/useTAtoFormControllerHook'; +import TAtoFormInterface from '@/packages/servicos/interfaces/TAto/TAtoFormInterface'; +import OnlyOfficeEditor from '@/shared/components/editor/onlyoffice/OnlyOfficeEditor'; +import { StepNavigator, StepSection } from '@/shared/components/step/stepNavigator'; + + +export default function TAtoForm({ ato_id }: TAtoFormInterface) { + + const tAtoController = useTAtoFormControllerHook() + + const { form } = tAtoController + + const configAto = useMemo(() => { + + return { + documentType: "word", + document: { + fileType: 'docx', + title: 'modelo.docx', + key: 'Ato', + permissions: { + edit: true, + download: true, + } + }, + editorConfig: { + mode: "edit", + lang: "pt-BR" + }, + }; + + }, []); + + // Memoriza os dados para não renderizar novamente + const sections: StepSection[] = useMemo( + () => [ + { + key: 'pedido', + id: 'selectPedido', + icon: , + title: 'Pedido', + description: 'Dados gerais do pedido.', + }, + { + key: 'servicoPedidoItem', + id: 'selectAtoItem', + icon: , + title: 'Itens', + description: 'Itens/serviços do pedido.', + }, + { + key: 'payment', + id: 'selectPayment', + icon: , + title: 'Pagamento', + description: 'Forma e dados de pagamento.', + }, + { + key: 'imoveis', + id: 'selectedImoveis', + icon: , + title: 'Imóveis', + description: 'Forma e dados de pagamento.', + }, + { + key: 'divisao', + id: 'selectedDivisao', + icon: , + title: 'Divisão', + description: 'Forma e dados de pagamento.', + }, + { + key: 'emolumentos', + id: 'selectedEmolumento', + icon: , + title: 'Emolumentos', + description: 'Forma e dados de pagamento.', + }, + ], + [], + ); + + // Memoriza os dados para não renderizar novamente + const sectionsText: StepSection[] = useMemo( + () => [ + { + key: 'texto', + id: 'selectedAto', + icon: , + title: 'Ato', + description: 'Dados gerais do pedido.', + }, + { + key: 'finalizacaoLivro', + id: 'selectedFinalizacaoLivro', + icon: , + title: 'Livro', + description: 'Itens/serviços do pedido.', + }, + { + key: 'finalizacaoTraslado', + id: 'selectedFinalizacaoTraslado', + icon: , + title: 'Traslado', + description: 'Forma e dados de pagamento.', + }, + ], + [], + ); + + return ( +
+

Ato

+ + + Ato + Texto + Imagem + Andamento + Lavratura + + +
+ +
+ {/* Seção1 */} +
+
+ + + +

Dados Inicias

+
+
+ +
+ {/* Escrevente */} +
+ ( + + Escrevente/Tabelião + + + + )} + /> +
+
+
+
+ + {/* Seção 2 */} + + + +

Dados Adicionais

+
+
+ +
+ {/* Seção 3 */} + + + +

Partes

+
+
+ +
+ {/* Seção 3 */} + + + +

Imóveis

+
+
+ +
+ {/* Seção 3 */} + + + +

Divisao

+
+
+ +
+ {/* Seção 3 */} + + + +

Emolumentos

+
+
+ +
+
+
+ + {/* Sidebar */} + +
+
+ + +
+ +
+
+ +
+ {/* Sidebar */} + +
+
+ Imagem + andamento + +
+ {/* Seção1 */} +
+ + + +

Lavratura

+
+
+ +
+ + + {/* ================= HEADER ================= */} +
+ {/* Left */} +
+ + +

Cecilia Chapman

+

+ P.O. Box 283 8562 Fusce Rd., 20620 +

+

+ ypurdomain@example.com +

+
+ + {/* Right */} +
+

+ Invoice +

+

+ #INV-0033970 +

+

+ Created Date:{" "} + September 28 2022 +

+

+ Due Date:{" "} + September 28 2022 +

+
+
+ + + + {/* ================= ADDRESSES ================= */} +
+
+

Billed To

+
+ Cecilia Chapman +
+ P.O. Box 283 8562 Fusce Rd., 20620 +
+ ypurdomain@example.com +
+
+ +
+

Shipped To

+
+ Cecilia Chapman +
+ P.O. Box 283 8562 Fusce Rd., 20620 +
+ ypurdomain@example.com +
+
+
+ + {/* ================= TABLE ================= */} +
+ + + + S.No + Product + Quantity + Unit + Amount + + + + + + 1 + +

Logo Creation

+

+ Photoshop +

+
+ 2 + $60.00 + + $120.00 + +
+ +
+
+
+
+
+
+
+
+
+ {/* Sidebar */} + +
+
+
+ + +
+ ); +} diff --git a/src/packages/servicos/components/TAto/TAtoIndex.tsx b/src/packages/servicos/components/TAto/TAtoIndex.tsx new file mode 100644 index 0000000..e645e3c --- /dev/null +++ b/src/packages/servicos/components/TAto/TAtoIndex.tsx @@ -0,0 +1,143 @@ +'use client'; + +import { useCallback, useEffect, useState } from 'react'; + +import { useTAtoDeleteHook } from '@/packages/servicos/hooks/TAto/useTAtoDeleteHook'; +import { useTAtoIndexHook } from '@/packages/servicos/hooks/TAto/useTAtoIndexHook'; +import { useTAtoSaveHook } from '@/packages/servicos/hooks/TAto/useTAtoSaveHook'; +import TAtoInterface from '@/packages/servicos/interfaces/TAto/TAtoInterface'; +import ConfirmDialog from '@/shared/components/confirmDialog/ConfirmDialog'; +import { useConfirmDialog } from '@/shared/components/confirmDialog/useConfirmDialog'; +import Header from '@/shared/components/structure/Header'; + +import TAtoTable from './TAtoTable'; + +export default function TAtoIndex() { + + // Controle de estado do botão + const [buttonIsLoading, setButtonIsLoading] = useState(false); + + // Hooks para leitura e salvamento + const { TAto, indexTAto } = useTAtoIndexHook(); + const { saveTAto } = useTAtoSaveHook(); + const { deleteTAto } = useTAtoDeleteHook(); + + // 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, handleCancel } = useConfirmDialog(); + + /** + * Abre o formulário no modo de edição ou criação + */ + const handleOpenForm = useCallback((data: TAtoInterface | 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: TAtoInterface) => { + // Coloca o botão em estado de loading + setButtonIsLoading(true); + + // Aguarda salvar o registro + await saveTAto(formData); + + // Remove o botão em estado de loading + setButtonIsLoading(false); + + // Atualiza a lista de dados + indexTAto(); + }, + [saveTAto, indexTAto, handleCloseForm], + ); + + /** + * Quando o usuário clica em "remover" na tabela + */ + const handleConfirmDelete = useCallback( + (item: TAtoInterface) => { + // 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 deleteTAto(itemToDelete); + + // Atualiza a lista + await indexTAto(); + + // Limpa o item selecionado + setItemToDelete(null); + + // Fecha o modal + handleCancel(); + }, [itemToDelete, indexTAto, handleCancel]); + + /** + * Busca inicial dos dados + */ + useEffect(() => { + indexTAto(); + }, []); + + return ( +
+ {/* Cabeçalho */} +
+ {/* Tabela de andamentos */} + + {/* Modal de confirmação */} + {isConfirmOpen && ( + + )} +
+ ); +} diff --git a/src/packages/servicos/components/TAto/TAtoTable.tsx b/src/packages/servicos/components/TAto/TAtoTable.tsx new file mode 100644 index 0000000..e19041b --- /dev/null +++ b/src/packages/servicos/components/TAto/TAtoTable.tsx @@ -0,0 +1,32 @@ +'use client'; + +import { Card, CardContent } from '@/components/ui/card'; +import TAtoTableInterface from '@/packages/servicos/interfaces/TAto/TAtoTableInterface'; +import { DataTable } from '@/shared/components/dataTable/DataTable'; + +import TAtoColumns from './TAtoColumns'; + +/** + * Componente principal da tabela de Naturezas + */ +export default function TAtoTable({ + data, + onEdit, + onDelete, +}: TAtoTableInterface) { + const columns = TAtoColumns(onEdit, onDelete); + return ( +
+ + + + + +
+ ); +} diff --git a/src/packages/servicos/components/TAto/TAtoTableFormDialog.tsx b/src/packages/servicos/components/TAto/TAtoTableFormDialog.tsx index 787ff87..6c6f933 100644 --- a/src/packages/servicos/components/TAto/TAtoTableFormDialog.tsx +++ b/src/packages/servicos/components/TAto/TAtoTableFormDialog.tsx @@ -35,19 +35,19 @@ export default function TAtoTableFormDialog({ const formCertidao = useTServicoItemPedidoCertidaoFormHook({}); - const { tAto, fetchTAto } = useTAtoIndexHook(); - const [atos, setAtos] = useState(); + const { TAto, indexTAto } = useTAtoIndexHook(); + const [atos, seTAtos] = useState(); const [selectedAto, setSelectedAto] = useState(null); // Atualiza a variavel de pessoa quando tiver alteração na variavel de pessoas fisicas useEffect(() => { - setAtos(tAto); - }, [tAto]); + seTAtos(TAto); + }, [TAto]); // Executa o hook correspondente ao tipo de pessoa, sempre que o tipo pessoa mudar useEffect(() => { // Dispara o carregamento de informações - fetchTAto() + indexTAto() }, []); const columns = TAtoTableFormColumnsDialog(setSelectedAto); diff --git a/src/packages/servicos/components/TServicoItemPedido/TServicoItemPedidoCertidaoForm.tsx b/src/packages/servicos/components/TServicoItemPedido/TServicoItemPedidoCertidaoForm.tsx index 569d861..f6ed913 100644 --- a/src/packages/servicos/components/TServicoItemPedido/TServicoItemPedidoCertidaoForm.tsx +++ b/src/packages/servicos/components/TServicoItemPedido/TServicoItemPedidoCertidaoForm.tsx @@ -23,15 +23,18 @@ export default function TServicoItemPedidoCertidaForm({ return { documentType: "word", document: { - fileType: GetFileExtension(selectedItem?.certidao_texto,), title: selectedItem?.certidao_texto, - name: selectedItem?.certidao_texto, - key: `etiqueta_${selectedItem?.servico_itempedido_id}_${new Date().getTime()}`, + key: selectedItem?.certidao_texto, + permissions: { + edit: true, + download: true, + } }, editorConfig: { mode: "edit", lang: "pt-BR", + orius_api_endpoint: `servicos/pedidos/t_servico_itempedido/${selectedItem?.servico_itempedido_id}/certidao/salvar` }, }; @@ -53,7 +56,7 @@ export default function TServicoItemPedidoCertidaForm({ {/* Só renderiza o Editor se o config estiver pronto */} {isOpen && config && ( )} diff --git a/src/packages/servicos/data/TAto/TAtoDeleteData.ts b/src/packages/servicos/data/TAto/TAtoDeleteData.ts new file mode 100644 index 0000000..b75bd68 --- /dev/null +++ b/src/packages/servicos/data/TAto/TAtoDeleteData.ts @@ -0,0 +1,19 @@ +import TAtoInterface from '@/packages/servicos/interfaces/TAto/TAtoInterface'; +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 executeTAtoDeleteData( + data: TAtoInterface, +): Promise { + const api = new API(); + + return api.send({ + method: Methods.DELETE, + endpoint: `administrativo/g_gramatica/${data.ato_id}`, + }); +} + +export const TAtoDeleteData = withClientErrorHandler(executeTAtoDeleteData); diff --git a/src/packages/servicos/data/TAto/TAtoSaveData.ts b/src/packages/servicos/data/TAto/TAtoSaveData.ts new file mode 100644 index 0000000..048c00a --- /dev/null +++ b/src/packages/servicos/data/TAto/TAtoSaveData.ts @@ -0,0 +1,23 @@ +import TAtoInterface from '@/packages/servicos/interfaces/TAto/TAtoInterface'; +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 executeTAtoSaveData(data: TAtoInterface): Promise { + // Verifica se existe ID para decidir se é atualização (PUT) ou criação (POST) + const isUpdate = Boolean(data.ato_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_gramatica/${data.ato_id || ''}`, // endpoint dinâmico + body: data, // payload enviado para a API + }); +} + +export const TAtoSaveData = withClientErrorHandler(executeTAtoSaveData); diff --git a/src/packages/servicos/data/TServicoItemPedido/TServicoItemPedidoSaveCertidaoData.ts b/src/packages/servicos/data/TServicoItemPedido/TServicoItemPedidoSaveCertidaoData.ts new file mode 100644 index 0000000..b89dd76 --- /dev/null +++ b/src/packages/servicos/data/TServicoItemPedido/TServicoItemPedidoSaveCertidaoData.ts @@ -0,0 +1,21 @@ +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 TServicoItemPedidoInterface from '../../interfaces/TServicoItemPedido/TServicoItemPedidoIntefarce'; + +async function executeTServicoItemPedidoSaveCertidaoData( + data: TServicoItemPedidoInterface, +): Promise { + + const api = new API(); + + return api.send({ + method: Methods.PUT, + endpoint: `servicos/pedidos/t_servico_itempedido/${data.servico_itempedido_id || ''}/certidao/salvar`, // endpoint dinâmico + body: data, + }); +} + +export const TServicoItemPedidoSaveCertidaoData = withClientErrorHandler(executeTServicoItemPedidoSaveCertidaoData); diff --git a/src/packages/servicos/hooks/TAto/useTAtoDeleteHook.ts b/src/packages/servicos/hooks/TAto/useTAtoDeleteHook.ts new file mode 100644 index 0000000..ab0effb --- /dev/null +++ b/src/packages/servicos/hooks/TAto/useTAtoDeleteHook.ts @@ -0,0 +1,21 @@ +import { useState } from 'react'; + + +import TAtoInterface from '@/packages/servicos/interfaces/TAto/TAtoInterface'; +import { TAtoDeleteService } from '@/packages/servicos/services/TAto/TAtoDeleteService'; +import { useResponse } from '@/shared/components/response/ResponseContext'; + +export const useTAtoDeleteHook = () => { + const { setResponse } = useResponse(); + + const [gGramatica, setTAto] = useState(); + + const deleteTAto = async (data: TAtoInterface) => { + const response = await TAtoDeleteService(data); + + setTAto(data); + setResponse(response); + }; + + return { gGramatica, deleteTAto }; +}; diff --git a/src/packages/servicos/hooks/TAto/useTAtoFormControllerHook.ts b/src/packages/servicos/hooks/TAto/useTAtoFormControllerHook.ts new file mode 100644 index 0000000..79c1810 --- /dev/null +++ b/src/packages/servicos/hooks/TAto/useTAtoFormControllerHook.ts @@ -0,0 +1,69 @@ +'use client'; + +import { useRouter } from 'next/navigation'; +import { useCallback, useRef, useState } from 'react'; + +import { useTAtoFormHook } from '@/packages/servicos/hooks/TAto/useTAtoFormHook'; +import { useTAtoSaveHook } from '@/packages/servicos/hooks/TAto/useTAtoSaveHook'; +import { useTServicoItemPedidoCalculoHook } from '@/packages/servicos/hooks/TServicoItemPedido/useTServicoItemPedidoCalculoHook'; +import { useTServicoItemPedidoIndexHook } from '@/packages/servicos/hooks/TServicoItemPedido/useTServicoItemPedidoIndexHook'; +import { useTServicoItemPedidoLocalHandleHook } from '@/packages/servicos/hooks/TServicoItemPedido/useTServicoItemPedidoLocalHandleHook'; +import { useResponse } from '@/shared/components/response/ResponseContext'; +import { StepNavigatorRef } from '@/shared/components/step/stepNavigator'; + + +export default function useTAtoFormControllerHook(ato_id?: number) { + + const router = useRouter(); + const form = useTAtoFormHook({}); + const { setValue, reset, watch } = form; + + const [isSaving, setIsSaving] = useState(false); + const [isAdding, setIsAdding] = useState(false); + const [isPessoaFormOpen, setIsPessoaFormOpen] = useState(false); + const [isAtoFormOpen, setAtoFormOpen] = useState(false); + const [isSaveConfirmOpen, setIsSaveConfirmOpen] = useState(false); + const [isCancelDialogOpen, setIsCancelDialogOpen] = useState(false); + const [selectedPessoaTipo, setSelectedPessoaTipo] = useState(''); + const [shouldKeepFormOpen, setShouldKeepFormOpen] = useState(false); + + const ref = useRef(null); + + // Controles de formulário + const handleClosePessoaForm = useCallback(() => setIsPessoaFormOpen(false), []); + const handleCloseAtoForm = useCallback(() => setAtoFormOpen(false), []); + const handleOpenSaveConfirm = useCallback(() => setIsSaveConfirmOpen(true), []); + const handleCloseSaveConfirm = useCallback(() => setIsSaveConfirmOpen(false), []); + + // const playSuccess = useSoundHook("/sounds/success.mp3"); + const { setResponse } = useResponse(); + const { saveTAto } = useTAtoSaveHook(); + const { TServicoItemPedidoLocal, localAddTServicoItemPedido, localRemoveTServicoItemPedido, setLocalTServicoItemPedido } = useTServicoItemPedidoLocalHandleHook(setValue); + const { calculoTServicoItemPedido } = useTServicoItemPedidoCalculoHook(setValue); + const { indexTServicoItemPedido } = useTServicoItemPedidoIndexHook(); + + return { + form, + ref, + isSaving, + isAdding, + isPessoaFormOpen, + isAtoFormOpen, + isSaveConfirmOpen, + isCancelDialogOpen, + shouldKeepFormOpen, + selectedPessoaTipo, + TServicoItemPedidoLocal, + + // setters diretos + setIsSaveConfirmOpen, + setIsCancelDialogOpen, + setShouldKeepFormOpen, + + // handlers principais + handleCloseSaveConfirm, + handleClosePessoaForm, + handleCloseAtoForm, + handleOpenSaveConfirm, + }; +} \ No newline at end of file diff --git a/src/packages/servicos/hooks/TAto/useTAtoFormHook.ts b/src/packages/servicos/hooks/TAto/useTAtoFormHook.ts new file mode 100644 index 0000000..b524215 --- /dev/null +++ b/src/packages/servicos/hooks/TAto/useTAtoFormHook.ts @@ -0,0 +1,17 @@ +import { zodResolver } from '@hookform/resolvers/zod'; +import { useForm } from 'react-hook-form'; + +import { + TAtoFormValues, + TAtoSchema, +} from '@/packages/servicos/schemas/TAto/TAtoSchema'; + +export function useTAtoFormHook(defaults?: Partial) { + return useForm({ + resolver: zodResolver(TAtoSchema), + defaultValues: { + ato_id: 0, + ...defaults, + }, + }); +} diff --git a/src/packages/servicos/hooks/TAto/useTAtoIndexHook.ts b/src/packages/servicos/hooks/TAto/useTAtoIndexHook.ts index d7158fe..d1ecdfd 100644 --- a/src/packages/servicos/hooks/TAto/useTAtoIndexHook.ts +++ b/src/packages/servicos/hooks/TAto/useTAtoIndexHook.ts @@ -7,9 +7,9 @@ import { useResponse } from '@/shared/components/response/ResponseContext'; export const useTAtoIndexHook = () => { const { setResponse } = useResponse(); - const [tAto, setTAto] = useState([]); + const [TAto, setTAto] = useState([]); - const fetchTAto = async () => { + const indexTAto = async () => { const response = await TAtoIndexService(); setTAto(response.data); @@ -19,5 +19,5 @@ export const useTAtoIndexHook = () => { return response.data; }; - return { tAto, fetchTAto }; + return { TAto, indexTAto }; }; diff --git a/src/packages/servicos/hooks/TAto/useTAtoSaveHook.ts b/src/packages/servicos/hooks/TAto/useTAtoSaveHook.ts new file mode 100644 index 0000000..223b270 --- /dev/null +++ b/src/packages/servicos/hooks/TAto/useTAtoSaveHook.ts @@ -0,0 +1,35 @@ +'use client'; + +import { useState } from 'react'; + + +import TAtoInterface from '@/packages/servicos/interfaces/TAto/TAtoInterface'; +import { TAtoSaveService } from '@/packages/servicos/services/TAto/TAtoSaveService'; +import { useResponse } from '@/shared/components/response/ResponseContext'; + +export const useTAtoSaveHook = () => { + const { setResponse } = useResponse(); + + const [gGramatica, setTAto] = useState(null); + + // controla se o formulário está aberto ou fechado + const [isOpen, setIsOpen] = useState(false); + + const saveTAto = async (data: TAtoInterface) => { + const response = await TAtoSaveService(data); + + // Armazena os dados da resposta + setTAto(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, saveTAto, isOpen, setIsOpen }; +}; diff --git a/src/packages/servicos/hooks/TServicoItemPedido/useTServicoItemPedidoCertidaoSaveHook.ts b/src/packages/servicos/hooks/TServicoItemPedido/useTServicoItemPedidoCertidaoSaveHook.ts new file mode 100644 index 0000000..e873424 --- /dev/null +++ b/src/packages/servicos/hooks/TServicoItemPedido/useTServicoItemPedidoCertidaoSaveHook.ts @@ -0,0 +1,39 @@ +'use client'; + +import { useState } from 'react'; + +import { useResponse } from '@/shared/components/response/ResponseContext'; + +import TServicoItemPedidoInterface from '../../interfaces/TServicoItemPedido/TServicoItemPedidoIntefarce'; +import { TServicoItemPedidoSaveCertidaoService } from '../../services/TServicoItemPedido/TServicoItemPedidoSaveCertidaoService'; + +export const useTServicoItemPedidoCertidaoSaveHook = () => { + + const { setResponse } = useResponse(); + + const [TServicoItemPedido, setTServicoItemPedido] = useState( + null, + ); + + // controla se o formulário está aberto ou fechado + const [isOpen, setIsOpen] = useState(false); + + const saveCertidaoTServicoItemPedido = async (data: TServicoItemPedidoInterface) => { + + const response = await TServicoItemPedidoSaveCertidaoService(data); + + // Armazena os dados da resposta + setTServicoItemPedido(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 { TServicoItemPedido, saveCertidaoTServicoItemPedido, isOpen, setIsOpen }; +}; diff --git a/src/packages/servicos/interfaces/TAto/TAtoFormInterface.ts b/src/packages/servicos/interfaces/TAto/TAtoFormInterface.ts new file mode 100644 index 0000000..443791a --- /dev/null +++ b/src/packages/servicos/interfaces/TAto/TAtoFormInterface.ts @@ -0,0 +1,3 @@ +export default interface TAtoFormInterface { + ato_id?: number +} \ No newline at end of file diff --git a/src/packages/servicos/interfaces/TAto/TAtoTableInterface.ts b/src/packages/servicos/interfaces/TAto/TAtoTableInterface.ts new file mode 100644 index 0000000..11bb346 --- /dev/null +++ b/src/packages/servicos/interfaces/TAto/TAtoTableInterface.ts @@ -0,0 +1,7 @@ +import TAtoInterface from './TAtoInterface'; + +export default interface TAtoTableInterface { + data?: TAtoInterface[]; + onEdit: (item: TAtoInterface, isEditingFormStatus: boolean) => void; + onDelete: (item: TAtoInterface, isEditingFormStatus: boolean) => void; +} diff --git a/src/packages/servicos/schemas/TAto/TAtoInterface.ts b/src/packages/servicos/schemas/TAto/TAtoSchema.ts similarity index 77% rename from src/packages/servicos/schemas/TAto/TAtoInterface.ts rename to src/packages/servicos/schemas/TAto/TAtoSchema.ts index e1c9ce3..085c69e 100644 --- a/src/packages/servicos/schemas/TAto/TAtoInterface.ts +++ b/src/packages/servicos/schemas/TAto/TAtoSchema.ts @@ -1,17 +1,17 @@ import z from "zod"; export const TAtoSchema = z.object({ - ato_id: z.string().optional(), - ato_tipo_id: z.string().optional(), - escrevente_ato_id: z.string().optional(), - escrevente_assina_id: z.string().optional(), - livro_andamento_id: z.string().optional(), + ato_id: z.number().optional(), + ato_tipo_id: z.number().optional(), + escrevente_ato_id: z.number().optional(), + escrevente_assina_id: z.number().optional(), + livro_andamento_id: z.number().optional(), data_abertura: z.string().optional(), data_lavratura: z.string().optional(), - usuario_id: z.string().optional(), + usuario_id: z.number().optional(), protocolo: z.string().optional(), alienacao_data: z.string().optional(), - qualificacao_imovel_id: z.string().optional(), + qualificacao_imovel_id: z.number().optional(), folha_inicial: z.string().optional(), folha_final: z.string().optional(), folha_total: z.string().optional(), @@ -19,7 +19,7 @@ export const TAtoSchema = z.object({ grs_numero: z.string().optional(), texto: z.string().optional(), texto_finalizacao: z.string().optional(), - natureza_id: z.string().optional(), + natureza_id: z.number().optional(), valor_pagamento: z.string().optional(), situacao_ato: z.string().optional(), texto_imovel_geral: z.string().optional(), @@ -27,16 +27,16 @@ export const TAtoSchema = z.object({ cancelado_data: z.string().optional(), cancelado_motivo: z.string().optional(), cancelado_observacao: z.string().optional(), - cancelado_usuario_id: z.string().optional(), + cancelado_usuario_id: z.number().optional(), data_cancelamento: z.string().optional(), alienacao_datalavratura: z.string().optional(), ato_antigo: z.string().optional(), folha_letra: z.string().optional(), qtd_imovel: z.string().optional(), minuta_protegida: z.string().optional(), - havido_marcacao_id: z.string().optional(), + havido_marcacao_id: z.number().optional(), observacao: z.string().optional(), - selo_livro_id: z.string().optional(), + selo_livro_id: z.number().optional(), usar_tabela_auxiliar: z.string().optional(), ato_antigo_ocorrencia: z.string().optional(), fonte_tamanho: z.string().optional(), @@ -45,13 +45,13 @@ export const TAtoSchema = z.object({ ato_anterior_origem: z.string().optional(), ato_anterior_livro: z.string().optional(), ato_anterior_finicial: z.string().optional(), - ato_anterior_tb_cartorio_id: z.string().optional(), + ato_anterior_tb_cartorio_id: z.number().optional(), ato_anterior_outorgante: z.string().optional(), ato_anterior_observacao: z.string().optional(), - ato_anterior_ato_id: z.string().optional(), + ato_anterior_ato_id: z.number().optional(), ato_anterior_data: z.string().optional(), ato_anterior_anotacao_adicional: z.string().optional(), - ato_anterior_ato_tipo_id: z.string().optional(), + ato_anterior_ato_tipo_id: z.number().optional(), ato_anterior_valor_documento: z.string().optional(), cadastrar_imovel: z.string().optional(), filho_maior_qtd: z.string().optional(), @@ -59,16 +59,16 @@ export const TAtoSchema = z.object({ filho_menor_qtd: z.string().optional(), filho_menor_descricao: z.string().optional(), casamento_data: z.string().optional(), - casamento_tb_regime_id: z.string().optional(), + casamento_tb_regime_id: z.number().optional(), ato_anterior_ffinal: z.string().optional(), resp_filhos_maiores: z.string().optional(), resp_filhos_menores: z.string().optional(), - censec_naturezalitigio_id: z.string().optional(), + censec_naturezalitigio_id: z.number().optional(), censec_acordo: z.string().optional(), nlote: z.string().optional(), especie_pagamento: z.string().optional(), fora_cartorio: z.string().optional(), - nfse_id: z.string().optional(), + nfse_id: z.number().optional(), acao: z.string().optional(), data_protocolo: z.string().optional(), frente_verso: z.string().optional(), @@ -82,4 +82,6 @@ export const TAtoSchema = z.object({ ato_oneroso: z.string().optional(), mne: z.string().optional(), eh_restrito: z.string().optional(), -}) \ No newline at end of file +}) + +export type TAtoFormValues = z.infer; \ No newline at end of file diff --git a/src/packages/servicos/services/TAto/TAtoDeleteService.ts b/src/packages/servicos/services/TAto/TAtoDeleteService.ts new file mode 100644 index 0000000..567e224 --- /dev/null +++ b/src/packages/servicos/services/TAto/TAtoDeleteService.ts @@ -0,0 +1,14 @@ +'use server'; + + +import { TAtoDeleteData } from '@/packages/servicos/data/TAto/TAtoDeleteData'; +import TAtoInterface from '@/packages/servicos/interfaces/TAto/TAtoInterface'; +import { withClientErrorHandler } from '@/shared/actions/withClientErrorHandler/withClientErrorHandler'; + +async function executeTAtoDeleteService(data: TAtoInterface) { + const response = await TAtoDeleteData(data); + + return response; +} + +export const TAtoDeleteService = withClientErrorHandler(executeTAtoDeleteService); diff --git a/src/packages/servicos/services/TAto/TAtoSaveService.ts b/src/packages/servicos/services/TAto/TAtoSaveService.ts new file mode 100644 index 0000000..5856def --- /dev/null +++ b/src/packages/servicos/services/TAto/TAtoSaveService.ts @@ -0,0 +1,14 @@ +'use server'; + + +import { TAtoSaveData } from '@/packages/servicos/data/TAto/TAtoSaveData'; +import TAtoInterface from '@/packages/servicos/interfaces/TAto/TAtoInterface'; +import { withClientErrorHandler } from '@/shared/actions/withClientErrorHandler/withClientErrorHandler'; + +async function executeTAtoSaveService(data: TAtoInterface) { + const response = await TAtoSaveData(data); + + return response; +} + +export const TAtoSaveService = withClientErrorHandler(executeTAtoSaveService); diff --git a/src/packages/servicos/services/TServicoItemPedido/TServicoItemPedidoSaveCertidaoService.ts b/src/packages/servicos/services/TServicoItemPedido/TServicoItemPedidoSaveCertidaoService.ts new file mode 100644 index 0000000..700f0d4 --- /dev/null +++ b/src/packages/servicos/services/TServicoItemPedido/TServicoItemPedidoSaveCertidaoService.ts @@ -0,0 +1,13 @@ +import { withClientErrorHandler } from '@/shared/actions/withClientErrorHandler/withClientErrorHandler'; + +import { TServicoItemPedidoSaveCertidaoData } from '../../data/TServicoItemPedido/TServicoItemPedidoSaveCertidaoData'; +import TServicoItemPedidoInterface from '../../interfaces/TServicoItemPedido/TServicoItemPedidoIntefarce'; + +async function executeTServicoItemPedidoSaveCertidaoService(data: TServicoItemPedidoInterface) { + const response = await TServicoItemPedidoSaveCertidaoData(data); + return response; +} + +export const TServicoItemPedidoSaveCertidaoService = withClientErrorHandler( + executeTServicoItemPedidoSaveCertidaoService, +); diff --git a/src/shared/components/editor/onlyoffice/OnlyOfficeEditor.tsx b/src/shared/components/editor/onlyoffice/OnlyOfficeEditor.tsx index 91632f3..a1f64b7 100644 --- a/src/shared/components/editor/onlyoffice/OnlyOfficeEditor.tsx +++ b/src/shared/components/editor/onlyoffice/OnlyOfficeEditor.tsx @@ -1,12 +1,16 @@ import { DocumentEditor } from "@onlyoffice/document-editor-react"; import { useEffect, useState } from "react"; + +import GetCallbackUrl from "./actions/GetCallbackUrl"; import GetServerUrl from "./actions/GetServerUrl"; import { usePrepareOnlyOfficeEditorHook } from "./hooks/usePrepareOnlyOfficeEditorHook"; +import { useTokenOnlyOfficeEditorHook } from "./hooks/useTokenOnlyOfficeEditorHook"; import OnlyOfficeInteface from "./interface/OnlyOfficeInterface"; export default function OnlyOfficeEditor({ id, config }: OnlyOfficeInteface) { + const { tokenOnlyOfficeEditorHook } = useTokenOnlyOfficeEditorHook() const { prepareOnlyOfficeEditorHook } = usePrepareOnlyOfficeEditorHook(); const [serverUrl, setServerUrl] = useState(null); @@ -22,9 +26,13 @@ export default function OnlyOfficeEditor({ id, config }: OnlyOfficeInteface) { setServerUrl(GetServerUrl(response.data, 1)) // Atualiza o caminho do documento - config.document.url = GetServerUrl(response.data, 2) + '/temp/' + config.document.name + config.document.url = GetServerUrl(response.data, 2) + '/temp/' + config.document.title - console.log('config', config) + // Configura a url de callback + config.editorConfig.callbackUrl = GetCallbackUrl(response.data) + config.editorConfig.orius_api_endpoint + + // Obtem o token assinado, deve ser sempre a ultima etapa + config.token = await tokenOnlyOfficeEditorHook(config); }; diff --git a/src/shared/components/editor/onlyoffice/actions/GetCallbackUrl.ts b/src/shared/components/editor/onlyoffice/actions/GetCallbackUrl.ts new file mode 100644 index 0000000..a365ec7 --- /dev/null +++ b/src/shared/components/editor/onlyoffice/actions/GetCallbackUrl.ts @@ -0,0 +1,5 @@ +export default function GetCallbackUrl(data) { + + return `http://${data.ip}:${data.port_api}/${data.prefix_api}`; + +} \ No newline at end of file diff --git a/src/shared/components/editor/onlyoffice/data/OnlyOfficeEditorPrepareData.ts b/src/shared/components/editor/onlyoffice/data/OnlyOfficeEditorPrepareData.ts index dc463ff..a8bf12f 100644 --- a/src/shared/components/editor/onlyoffice/data/OnlyOfficeEditorPrepareData.ts +++ b/src/shared/components/editor/onlyoffice/data/OnlyOfficeEditorPrepareData.ts @@ -10,6 +10,7 @@ async function executeOnlyOfficeEditorPrepareData(): Promise { - - const timeoutMs = 2000; // Defina o tempo limite desejado - const controller = new AbortController(); - const timeoutId = setTimeout(() => controller.abort(), timeoutMs); - - try { - - const response = await fetch(url, { - method: 'HEAD', - signal: controller.signal - }); - - // O fetch nativo não lança erro em 404 ou 500, então verificamos manualmente. - if (!response.ok) { - throw new Error(`Serviço indisponível. Status: ${response.status}`); - } - - return { - status: 200, - message: "Editor inicializado com sucesso", - data: { - online: true, - status: response.status - } - }; - - } finally { - - // Isso garante que o timer seja limpo, quer a requisição funcione ou falhe (erro propagado) - clearTimeout(timeoutId); - - } -} - -export const OnlyOfficeEditorServiceUpData = withClientErrorHandler(executeOnlyOfficeEditorServiceUpData); \ No newline at end of file diff --git a/src/shared/components/editor/onlyoffice/hooks/usePrepareOnlyOfficeEditorHook.ts b/src/shared/components/editor/onlyoffice/hooks/usePrepareOnlyOfficeEditorHook.ts index ace44ab..c4f398a 100644 --- a/src/shared/components/editor/onlyoffice/hooks/usePrepareOnlyOfficeEditorHook.ts +++ b/src/shared/components/editor/onlyoffice/hooks/usePrepareOnlyOfficeEditorHook.ts @@ -1,12 +1,10 @@ 'use client'; import { useState } from 'react'; -import { object } from 'zod'; import GGramaticaInterface from '@/packages/administrativo/interfaces/GGramatica/GGramaticaInterface'; import { useResponse } from '@/shared/components/response/ResponseContext'; -import { OnlyOfficeEditorServiceUpData } from '../data/OnlyOfficeEditorServiceUpData'; import { OnlyOfficeEditorPrepareService } from '../services/OnlyOfficeEditorPrepareService'; export const usePrepareOnlyOfficeEditorHook = () => { @@ -14,27 +12,12 @@ export const usePrepareOnlyOfficeEditorHook = () => { const { setResponse } = useResponse(); const [onlyOfficeEditor, setOnlyOfficeEditor] = useState([]); - const [serviceUpData, setServiceUpData] = useState(object); const prepareOnlyOfficeEditorHook = async () => { // Busca as confgiurações do editor const response = await OnlyOfficeEditorPrepareService(); - // Define a url do editor - const urlServer = `http://${response.data.ip}:${response.data.port_only_office}` - - // Busca as confgiurações do editor - const responseServiceUp = await OnlyOfficeEditorServiceUpData(urlServer); - - if (responseServiceUp.status != 200) { - setResponse({ - status: responseServiceUp.status, - detail: 'Não foi possivel conectar ao editor', - message: 'Não foi possivel conectar ao editor' - }) - } - // Armazena os dados consultados setOnlyOfficeEditor(response.data); diff --git a/src/shared/components/editor/onlyoffice/hooks/useTokenOnlyOfficeEditorHook.ts b/src/shared/components/editor/onlyoffice/hooks/useTokenOnlyOfficeEditorHook.ts new file mode 100644 index 0000000..83dba53 --- /dev/null +++ b/src/shared/components/editor/onlyoffice/hooks/useTokenOnlyOfficeEditorHook.ts @@ -0,0 +1,36 @@ +'use client'; + +import { useState } from 'react'; + +import { useResponse } from '@/shared/components/response/ResponseContext'; + +import { OnlyOfficeEditorTokenService } from '../services/OnlyOfficeEditorTokenService'; + + +export const useTokenOnlyOfficeEditorHook = () => { + + const { setResponse } = useResponse(); + + const [onlyOfficeToken, setOnlyOfficeToken] = useState(); + + const tokenOnlyOfficeEditorHook = async (data: object) => { + + // Busca as confgiurações do editor + const response = await OnlyOfficeEditorTokenService(data); + + // Armazena os dados consultados + setOnlyOfficeToken(response.data); + + // Define a resposta (toast, modal, feedback, etc.) + setResponse(response); + + // Retorna os dados imediatamente + return response; + + }; + + return { + onlyOfficeToken, + tokenOnlyOfficeEditorHook, + }; +}; diff --git a/src/shared/components/editor/onlyoffice/services/OnlyOfficeEditorTokenService.ts b/src/shared/components/editor/onlyoffice/services/OnlyOfficeEditorTokenService.ts new file mode 100644 index 0000000..dcba5f3 --- /dev/null +++ b/src/shared/components/editor/onlyoffice/services/OnlyOfficeEditorTokenService.ts @@ -0,0 +1,19 @@ +'use server'; + +import jwt from 'jsonwebtoken'; + +import { withClientErrorHandler } from '@/shared/actions/withClientErrorHandler/withClientErrorHandler'; + +export default async function executeOnlyOfficeEditorTokenService(data: object) { + + const response = jwt.sign(data, 'WYe1zwtlDkh39_X3X3qTSICFDxts4VQrMyGLxnEpGUg', { + + algorithm: 'HS256', + expiresIn: '5m', + + }) + + return response; +} + +export const OnlyOfficeEditorTokenService = withClientErrorHandler(executeOnlyOfficeEditorTokenService); \ No newline at end of file