first commit

This commit is contained in:
rodrigo committed 2025-04-10 23:07:21 -03:00
commit c9fb67e751
423 files changed
+53287

No files matched your search

+57
View File
@@ -0,0 +1,57 @@
import { useMutation, useQueryClient } from "react-query";
import axios from "axios";
export function useAudiencias(processoId: string) {
const queryClient = useQueryClient();
const addAudiencia = useMutation(
async (data: any) => {
if (!data.tipo || !data.data || !data.local) {
throw new Error("Campos obrigatórios não preenchidos");
}
const response = await axios.post(
`/api/processos/${processoId}/audiencias`,
data,
);
return response.data;
},
{
onSuccess: () => {
queryClient.invalidateQueries(["processo", processoId]);
},
},
);
const updateAudiencia = useMutation(
async ({ id, data }: { id: string; data: any }) => {
const response = await axios.put(
`/api/processos/${processoId}/audiencias/${id}`,
data,
);
return response.data;
},
{
onSuccess: () => {
queryClient.invalidateQueries(["processo", processoId]);
},
},
);
const deleteAudiencia = useMutation(
async (id: string) => {
await axios.delete(`/api/processos/${processoId}/audiencias/${id}`);
},
{
onSuccess: () => {
queryClient.invalidateQueries(["processo", processoId]);
},
},
);
return {
addAudiencia: addAudiencia.mutateAsync,
updateAudiencia: updateAudiencia.mutateAsync,
deleteAudiencia: deleteAudiencia.mutateAsync,
};
}
+16
View File
@@ -0,0 +1,16 @@
import { useContext } from 'react';
import { AuthContext } from '../contexts/AuthContext';
export function useAuth() {
const context = useContext(AuthContext);
if (!context) {
console.error('useAuth deve ser usado dentro de um AuthProvider');
throw new Error('useAuth deve ser usado dentro de um AuthProvider');
}
// Adicionar log para debug
console.log('useAuth - Current user:', context.user);
return context;
}
+70
View File
@@ -0,0 +1,70 @@
import { useQuery, useMutation, useQueryClient } from "react-query";
import axios from "axios";
import { Cliente } from "../types/entities";
export function useClientes() {
const queryClient = useQueryClient();
const { data: clientes = [], isLoading } = useQuery("clientes", async () => {
try {
const response = await axios.get<Cliente[]>("/api/clientes");
return response.data;
} catch (error) {
console.error("Erro ao buscar clientes:", error);
return [];
}
});
const createCliente = useMutation(
async (data: Partial<Cliente>) => {
const response = await axios.post<Cliente>("/api/clientes", data);
return response.data;
},
{
onSuccess: () => {
queryClient.invalidateQueries("clientes");
},
},
);
const updateCliente = useMutation(
async ({ id, data }: { id: string; data: Partial<Cliente> }) => {
console.log("Enviando atualização:", { id, data });
const response = await axios.put<Cliente>(`/api/clientes/${id}`, data);
return response.data;
},
{
onSuccess: () => {
queryClient.invalidateQueries("clientes");
},
onError: (error) => {
console.error("Erro ao atualizar cliente:", error);
if (axios.isAxiosError(error)) {
throw new Error(
error.response?.data?.error || "Erro ao atualizar cliente",
);
}
throw error;
},
},
);
const deleteCliente = useMutation(
async (id: string) => {
await axios.delete(`/api/clientes/${id}`);
},
{
onSuccess: () => {
queryClient.invalidateQueries("clientes");
},
},
);
return {
clientes,
isLoading,
createCliente: createCliente.mutateAsync,
updateCliente: updateCliente.mutateAsync,
deleteCliente: deleteCliente.mutateAsync,
};
}
+23
View File
@@ -0,0 +1,23 @@
import { useMutation, useQueryClient } from 'react-query';
import api from '../services/api';
import { Comentario } from '../types/entities';
export const useComentarios = (tarefaId: string) => {
const queryClient = useQueryClient();
const addComentario = useMutation(
async (texto: string) => {
const response = await api.post(`/tarefas/${tarefaId}/comentarios`, { texto });
return response.data;
},
{
onSuccess: () => {
queryClient.invalidateQueries(['tarefas', tarefaId]);
}
}
);
return {
addComentario
};
};
+148
View File
@@ -0,0 +1,148 @@
import { useState } from "react";
import api from "../services/api";
/**
* Hook para gerenciar operações de custas processuais
*/
export const useCustasProcessuais = (processoId: string) => {
const [isLoading, setIsLoading] = useState(false);
const [error, setError] = useState<string | null>(null);
/**
* Adiciona uma nova custa processual
*/
const addCusta = async (data: any) => {
setIsLoading(true);
setError(null);
try {
// Validações
if (!data.tipo) throw new Error("Tipo da custa é obrigatório");
if (!data.descricao) throw new Error("Descrição da custa é obrigatória");
if (!data.valor) throw new Error("Valor da custa é obrigatório");
// Preparar dados
const payload = {
processoId,
tipo: data.tipo,
descricao: data.descricao,
valor: Number(data.valor),
percentual: data.percentual ? Number(data.percentual) : null,
status: data.status || "PENDENTE",
vencimento: data.vencimento || null,
dataPagamento: data.dataPagamento || null,
observacoes: data.observacoes || null,
numeroParcelas: Number(data.numeroParcelas || 1),
parcelaAtual: Number(data.parcelaAtual || 1),
comprovante: data.comprovante || null,
};
// Fazer requisição
const response = await api.post(
`/processos/${processoId}/custas`,
payload,
);
return response.data;
} catch (err: any) {
const errorMsg =
err.response?.data?.details ||
err.response?.data?.error ||
err.message ||
"Erro ao adicionar custa processual";
setError(errorMsg);
throw new Error(errorMsg);
} finally {
setIsLoading(false);
}
};
/**
* Atualiza uma custa processual existente
*/
const updateCusta = async ({ id, data }: { id: string; data: any }) => {
setIsLoading(true);
setError(null);
try {
// Preparar dados
const payload = {
tipo: data.tipo,
descricao: data.descricao,
valor: Number(data.valor),
percentual: data.percentual ? Number(data.percentual) : null,
status: data.status,
vencimento: data.vencimento,
dataPagamento: data.dataPagamento,
observacoes: data.observacoes,
numeroParcelas: Number(data.numeroParcelas || 1),
parcelaAtual: Number(data.parcelaAtual || 1),
comprovante: data.comprovante,
};
// Fazer requisição
const response = await api.put(`/custas/${id}`, payload);
return response.data;
} catch (err: any) {
const errorMsg =
err.response?.data?.error ||
err.message ||
"Erro ao atualizar custa processual";
setError(errorMsg);
throw new Error(errorMsg);
} finally {
setIsLoading(false);
}
};
/**
* Remove uma custa processual
*/
const deleteCusta = async (id: string) => {
setIsLoading(true);
setError(null);
try {
await api.delete(`/custas/${id}`);
} catch (err: any) {
const errorMsg =
err.response?.data?.error ||
err.message ||
"Erro ao excluir custa processual";
setError(errorMsg);
throw new Error(errorMsg);
} finally {
setIsLoading(false);
}
};
/**
* Busca todas as custas do processo
*/
const getCustas = async () => {
setIsLoading(true);
setError(null);
try {
const response = await api.get(`/processos/${processoId}/custas`);
return response.data;
} catch (err: any) {
const errorMsg =
err.response?.data?.error ||
err.message ||
"Erro ao buscar custas processuais";
setError(errorMsg);
throw new Error(errorMsg);
} finally {
setIsLoading(false);
}
};
return {
addCusta,
updateCusta,
deleteCusta,
getCustas,
isLoading,
error,
};
};
+68
View File
@@ -0,0 +1,68 @@
import { useQuery } from 'react-query';
import api from '../services/api';
export const useDashboardStats = () => {
const queryKeys = {
processos: 'dashboard-processos-stats',
tarefas: 'dashboard-tarefas-stats',
atendimentos: 'dashboard-atendimentos-stats',
financeiro: 'dashboard-financeiro-stats',
prazos: 'dashboard-prazos',
atividades: 'dashboard-atividades'
};
const processosStats = useQuery(queryKeys.processos, async () => {
try {
const response = await api.get('/dashboard/processos/stats');
return response.data;
} catch (error) {
console.error('Erro ao buscar estatísticas:', error);
return null;
}
});
const tarefasStats = useQuery(queryKeys.tarefas, async () => {
try {
const response = await api.get('/dashboard/tarefas/stats');
return response.data;
} catch (error) {
console.error('Erro ao buscar estatísticas de tarefas:', error);
return {
pendentes: 0,
atrasadas: 0,
concluidas: 0,
total: 0,
taxaConclusao: 0
};
}
});
const atendimentosStats = useQuery(queryKeys.atendimentos, async () => {
const response = await api.get('/dashboard/atendimentos/stats');
return response.data;
});
const financeiroStats = useQuery(queryKeys.financeiro, async () => {
const response = await api.get('/dashboard/financeiro/stats');
return response.data;
});
const proximosPrazos = useQuery(queryKeys.prazos, async () => {
const response = await api.get('/dashboard/prazos/proximos');
return response.data;
});
const atividades = useQuery(queryKeys.atividades, async () => {
const response = await api.get('/dashboard/atividades');
return response.data;
});
return {
processosStats,
tarefasStats,
atendimentosStats,
financeiroStats,
proximosPrazos,
atividades
};
};
+38
View File
@@ -0,0 +1,38 @@
import { useState } from "react";
import { datajudApi } from "../services/datajud";
import { DatajudResponse } from "../types/datajud";
export function useDatajud() {
const [loading, setLoading] = useState(false);
const [error, setError] = useState<string | null>(null);
const [data, setData] = useState<DatajudResponse["_source"] | null>(null);
const consultarProcesso = async (
numeroProcesso: string,
tribunal: string,
) => {
setLoading(true);
setError(null);
try {
const response = await datajudApi.consultarProcesso(
numeroProcesso,
tribunal,
);
setData(response);
return response;
} catch (err) {
setError("Erro ao consultar processo no DataJud");
throw err;
} finally {
setLoading(false);
}
};
return {
consultarProcesso,
loading,
error,
data,
};
}
+171
View File
@@ -0,0 +1,171 @@
import { useState } from "react";
import api from "../services/api";
/**
* Hook para gerenciar operações de honorários
*/
export const useHonorarios = (processoId: string) => {
const [isLoading, setIsLoading] = useState(false);
const [error, setError] = useState<string | null>(null);
/**
* Adiciona um novo honorário
*/
const addHonorario = async (data: any) => {
setIsLoading(true);
setError(null);
try {
// Validações
if (!data.formaPagamento) {
throw new Error("Forma de pagamento é obrigatória");
}
// Preparar dados
const payload = {
processoId,
formaPagamento: data.formaPagamento,
status: data.status || "PENDENTE",
dataVencimento: data.dataVencimento || new Date(),
observacoes: data.observacoes || null,
valorFixo: data.valorFixo ? Number(data.valorFixo) : null,
percentualCausa: data.percentualCausa
? Number(data.percentualCausa)
: null,
percentualExito: data.percentualExito
? Number(data.percentualExito)
: null,
valorEntrada: data.valorEntrada ? Number(data.valorEntrada) : null,
numeroParcelas: data.numeroParcelas ? Number(data.numeroParcelas) : 1,
valorParcela: data.valorParcela ? Number(data.valorParcela) : null,
diaVencimento: data.diaVencimento ? Number(data.diaVencimento) : 10,
};
// Fazer requisição
const response = await api.post(
`/processos/${processoId}/honorarios`,
payload,
);
return response.data;
} catch (err: any) {
const errorMsg =
err.response?.data?.details ||
err.response?.data?.error ||
err.message ||
"Erro ao adicionar honorário";
setError(errorMsg);
throw new Error(errorMsg);
} finally {
setIsLoading(false);
}
};
/**
* Atualiza um honorário existente
*/
const updateHonorario = async ({ id, data }: { id: string; data: any }) => {
setIsLoading(true);
setError(null);
try {
// Preparar dados
const payload = {
formaPagamento: data.formaPagamento,
status: data.status,
dataVencimento: data.dataVencimento,
observacoes: data.observacoes,
valorFixo: data.valorFixo ? Number(data.valorFixo) : null,
percentualCausa: data.percentualCausa
? Number(data.percentualCausa)
: null,
percentualExito: data.percentualExito
? Number(data.percentualExito)
: null,
valorEntrada: data.valorEntrada ? Number(data.valorEntrada) : null,
numeroParcelas: data.numeroParcelas ? Number(data.numeroParcelas) : 1,
valorParcela: data.valorParcela ? Number(data.valorParcela) : null,
diaVencimento: data.diaVencimento ? Number(data.diaVencimento) : 10,
};
// Fazer requisição
const response = await api.put(`/honorarios/${id}`, payload);
return response.data;
} catch (err: any) {
const errorMsg =
err.response?.data?.error ||
err.message ||
"Erro ao atualizar honorário";
setError(errorMsg);
throw new Error(errorMsg);
} finally {
setIsLoading(false);
}
};
/**
* Remove um honorário
*/
const deleteHonorario = async (id: string) => {
setIsLoading(true);
setError(null);
try {
await api.delete(`/honorarios/${id}`);
} catch (err: any) {
const errorMsg =
err.response?.data?.error || err.message || "Erro ao excluir honorário";
setError(errorMsg);
throw new Error(errorMsg);
} finally {
setIsLoading(false);
}
};
/**
* Busca todos os honorários do processo
*/
const getHonorarios = async () => {
setIsLoading(true);
setError(null);
try {
const response = await api.get(`/processos/${processoId}/honorarios`);
return response.data;
} catch (err: any) {
const errorMsg =
err.response?.data?.error || err.message || "Erro ao buscar honorários";
setError(errorMsg);
throw new Error(errorMsg);
} finally {
setIsLoading(false);
}
};
// Adicionar função para atualizar parcela
const updateParcela = async ({ id, data }: { id: string; data: any }) => {
setIsLoading(true);
setError(null);
try {
const response = await api.put(`/honorarios/parcelas/${id}`, data);
return response.data;
} catch (err: any) {
const errorMsg =
err.response?.data?.error || err.message || "Erro ao atualizar parcela";
setError(errorMsg);
throw new Error(errorMsg);
} finally {
setIsLoading(false);
}
};
return {
addHonorario,
updateHonorario,
deleteHonorario,
getHonorarios,
isLoading,
error,
updateParcela,
};
};
+71
View File
@@ -0,0 +1,71 @@
import { useMutation, useQueryClient } from "react-query";
import axios from "axios";
export function usePartesProcesso(processoId: string) {
const queryClient = useQueryClient();
const addParte = useMutation(
async (data: any) => {
console.log("Dados recebidos em addParte:", data); // Debug
if (!data.tipo) {
throw new Error("Tipo da parte é obrigatório");
}
if (!data.nome) {
throw new Error("Nome é obrigatório");
}
const response = await axios.post(`/api/processos/${processoId}/partes`, {
tipo: data.tipo,
nome: data.nome,
cpfCnpj: data.cpfCnpj,
clienteId: data.clienteId,
principal: data.principal || false,
observacoes: data.observacoes,
});
return response.data;
},
{
onSuccess: () => {
queryClient.invalidateQueries(["processo", processoId]);
},
onError: (error) => {
console.error("Erro ao adicionar parte:", error);
throw error;
},
},
);
const updateParte = useMutation(
async ({ id, data }: { id: string; data: any }) => {
const response = await axios.put(
`/api/processos/${processoId}/partes/${id}`,
data,
);
return response.data;
},
{
onSuccess: () => {
queryClient.invalidateQueries(["processo", processoId]);
},
},
);
const deleteParte = useMutation(
async (id: string) => {
await axios.delete(`/api/processos/${processoId}/partes/${id}`);
},
{
onSuccess: () => {
queryClient.invalidateQueries(["processo", processoId]);
},
},
);
return {
addParte: addParte.mutateAsync,
updateParte: updateParte.mutateAsync,
deleteParte: deleteParte.mutateAsync,
};
}
+49
View File
@@ -0,0 +1,49 @@
import { useState, useEffect } from "react";
import { useDatajud } from "./useDatajud";
export function useProcessoMovimentacoes(processo: any) {
const { consultarProcesso, loading, error } = useDatajud();
const [movimentacoes, setMovimentacoes] = useState<any[]>([]);
useEffect(() => {
const fetchMovimentacoes = async () => {
if (!processo?.numero || !processo?.tribunal) {
console.log("Dados do processo incompletos:", processo);
return;
}
try {
const data = await consultarProcesso(
processo.numero,
processo.tribunal,
);
if (data?.movimentos) {
// Remover duplicatas usando Map com chave composta
const movimentacoesMap = new Map();
data.movimentos.forEach((mov: any) => {
const key = `${mov.codigo}-${mov.nome}-${mov.dataHora}`;
movimentacoesMap.set(key, mov);
});
// Converter de volta para array e ordenar
const movimentacoesUnicas = Array.from(
movimentacoesMap.values(),
).sort(
(a, b) =>
new Date(b.dataHora).getTime() - new Date(a.dataHora).getTime(),
);
setMovimentacoes(movimentacoesUnicas);
}
} catch (error) {
console.error("Erro ao buscar movimentações:", error);
}
};
if (processo) {
fetchMovimentacoes();
}
}, [processo?.id]); // Mudando a dependência para processo.id
return { movimentacoes, loading, error };
}
+80
View File
@@ -0,0 +1,80 @@
import { useQuery, useMutation, useQueryClient } from 'react-query';
import api from '../services/api';
import { Processo } from '../types/entities';
export const useProcessos = () => {
const queryClient = useQueryClient();
const { data: processos = [], isLoading } = useQuery<Processo[]>(
'processos',
async () => {
const response = await api.get('/processos');
return response.data;
}
);
const getProcesso = async (id: string) => {
const response = await api.get(`/processos/${id}`);
return response.data;
};
// Corrigido para usar createProcesso como mutação
const createProcesso = useMutation(
async (data: Partial<Processo>) => {
const response = await api.post('/processos', data);
return response.data;
},
{
onSuccess: () => {
queryClient.invalidateQueries('processos');
}
}
);
// Corrigido para usar updateProcesso como mutação
const updateProcesso = useMutation(
async ({ id, data }: { id: string; data: Partial<Processo> }) => {
const response = await api.put(`/processos/${id}`, data);
return response.data;
},
{
onSuccess: () => {
queryClient.invalidateQueries('processos');
}
}
);
// Corrigido para usar deleteProcesso como mutação
const deleteProcesso = useMutation(
async (id: string) => {
await api.delete(`/processos/${id}`);
},
{
onSuccess: () => {
queryClient.invalidateQueries('processos');
}
}
);
const updateResultado = useMutation(
async ({ id, resultado }: { id: string; resultado: string }) => {
const response = await api.patch(`/processos/${id}/resultado`, { resultado });
return response.data;
},
{
onSuccess: () => {
queryClient.invalidateQueries('processos');
}
}
);
return {
processos,
isLoading,
getProcesso,
createProcesso,
updateProcesso,
deleteProcesso, // Retornando a mutação
updateResultado
};
};
+59
View File
@@ -0,0 +1,59 @@
import { useMutation, useQuery, useQueryClient } from 'react-query';
import api from '../services/api';
import { ProcessoAdministrativo } from '../types/processoAdministrativo';
export function useProcessosAdministrativos() {
const queryClient = useQueryClient();
const { data: processos, isLoading, error } = useQuery<ProcessoAdministrativo[]>(
'processos-administrativos',
async () => {
const response = await api.get('/processos-administrativos');
return response.data;
}
);
const createProcesso = useMutation(
async (data: Partial<ProcessoAdministrativo>) => {
const response = await api.post('/processos-administrativos', data);
return response.data;
},
{
onSuccess: () => {
queryClient.invalidateQueries('processos-administrativos');
},
}
);
const updateProcesso = useMutation(
async ({ id, data }: { id: string; data: Partial<ProcessoAdministrativo> }) => {
const response = await api.put(`/processos-administrativos/${id}`, data);
return response.data;
},
{
onSuccess: () => {
queryClient.invalidateQueries('processos-administrativos');
},
}
);
const deleteProcesso = useMutation(
async (id: string) => {
await api.delete(`/processos-administrativos/${id}`);
},
{
onSuccess: () => {
queryClient.invalidateQueries('processos-administrativos');
},
}
);
return {
processos,
isLoading,
error,
createProcesso,
updateProcesso,
deleteProcesso,
};
}
+23
View File
@@ -0,0 +1,23 @@
import { useMutation, useQueryClient } from 'react-query';
import api from '../services/api';
import { SubTarefa } from '../types/entities';
export const useSubtarefas = (tarefaId: string) => {
const queryClient = useQueryClient();
const toggleSubtarefa = useMutation(
async ({ id, concluida }: { id: string; concluida: boolean }) => {
const response = await api.patch(`/tarefas/${tarefaId}/subtarefas/${id}`, { concluida });
return response.data;
},
{
onSuccess: () => {
queryClient.invalidateQueries(['tarefas', tarefaId]);
}
}
);
return {
toggleSubtarefa
};
};
+81
View File
@@ -0,0 +1,81 @@
import { useQuery, useMutation, useQueryClient } from 'react-query';
import api from '../services/api';
import { Tarefa } from '../types/entities';
export const useTarefas = () => {
const queryClient = useQueryClient();
const { data: tarefas = [], isLoading } = useQuery<Tarefa[]>('tarefas', async () => {
const response = await api.get('/tarefas');
return response.data;
});
const createTarefa = useMutation(
async (data: Partial<Tarefa>) => {
const response = await api.post('/tarefas', data);
return response.data;
},
{
onSuccess: () => {
queryClient.invalidateQueries('tarefas');
}
}
);
const updateTarefa = useMutation(
async ({ id, data }: { id: string; data: Partial<Tarefa> }) => {
const response = await api.put(`/tarefas/${id}`, data);
return response.data;
},
{
onSuccess: () => {
queryClient.invalidateQueries('tarefas');
}
}
);
const updateStatus = useMutation(
async ({ id, status, progresso }: { id: string; status: string; progresso?: number }) => {
const response = await api.patch(`/tarefas/${id}/status`, { status, progresso });
return response.data;
},
{
onSuccess: () => {
queryClient.invalidateQueries('tarefas');
}
}
);
const deleteTarefa = useMutation(
async (id: string) => {
await api.delete(`/tarefas/${id}`); // Remover o /api duplicado
},
{
onSuccess: () => {
queryClient.invalidateQueries('tarefas');
},
onMutate: async (deletedId) => {
await queryClient.cancelQueries('tarefas');
const previousTarefas = queryClient.getQueryData<any[]>('tarefas');
queryClient.setQueryData('tarefas', (old: any[] = []) =>
old.filter(tarefa => tarefa.id !== deletedId)
);
return { previousTarefas };
},
onError: (err, variables, context: any) => {
if (context?.previousTarefas) {
queryClient.setQueryData('tarefas', context.previousTarefas);
}
}
}
);
return {
tarefas,
isLoading,
createTarefa,
updateTarefa,
updateStatus,
deleteTarefa
};
};