dashboard: reimaginacao

Signed-off-by: Rodrigo B. de Sousa Martins <rodrigo.sousa.577@gmail.com>
This commit is contained in:
rodrigo committed 2025-07-15 20:39:56 -03:00
1 parent a4206a7611
commit b713e24fbf
3 files changed
+77 -46

No files matched your search

@@ -1,50 +1,31 @@
import React, { useEffect, useState } from 'react'; import React from 'react';
import { useBenchmarking } from '../../hooks/useBenchmarking';
interface Benchmarking {
ajuizados15dias: number;
emTramitacao: number;
}
export const BenchmarkingEscritorio: React.FC = () => { export const BenchmarkingEscritorio: React.FC = () => {
const [benchmarking, setBenchmarking] = useState<Benchmarking | null>(null); // Hook para buscar e calcular benchmarking
const [loading, setLoading] = useState(true); const { data: benchmarking, isLoading, error } = useBenchmarking();
const [error, setError] = useState<string | null>(null);
useEffect(() => { if (isLoading) return <div>Carregando benchmarking...</div>;
async function fetchBenchmarking() { if (error) return <div className="text-red-600">Erro ao buscar benchmarking</div>;
try {
setLoading(true);
setError(null);
const res = await fetch('/api/benchmarking', {
headers: {
'Content-Type': 'application/json',
},
});
if (!res.ok) throw new Error('Erro ao buscar benchmarking');
const data = await res.json();
setBenchmarking(data);
} catch (err: any) {
setError(err.message);
} finally {
setLoading(false);
}
}
fetchBenchmarking();
}, []);
if (loading) return <div>Carregando benchmarking...</div>;
if (error) return <div className="text-red-600">{error}</div>;
if (!benchmarking) return null; if (!benchmarking) return null;
return ( return (
<div className="border rounded p-4 shadow flex flex-col gap-4"> <div className="border rounded p-4 shadow flex flex-col gap-4">
<div> <div>
<span className="font-semibold">Processos ajuizados (últimos 15 dias):</span> <span className="font-semibold">Total de processos:</span>
<span className="ml-2 text-blue-700 font-bold">{benchmarking.ajuizados15dias}</span> <span className="ml-2 text-blue-700 font-bold">{benchmarking.totalProcessos}</span>
</div> </div>
<div> <div>
<span className="font-semibold">Processos em tramitação:</span> <span className="font-semibold">Processos ativos:</span>
<span className="ml-2 text-green-700 font-bold">{benchmarking.emTramitacao}</span> <span className="ml-2 text-green-700 font-bold">{benchmarking.ativos}</span>
</div>
<div>
<span className="font-semibold">Julgados procedentes:</span>
<span className="ml-2 text-green-700 font-bold">{benchmarking.procedentes}</span>
</div>
<div>
<span className="font-semibold">Improcedentes/Sem análise de mérito:</span>
<span className="ml-2 text-red-700 font-bold">{benchmarking.improcedentesOuSemMerito}</span>
</div> </div>
</div> </div>
); );
+24 -9
View File
@@ -47,15 +47,30 @@ export const WorkflowTarefas: React.FC = () => {
return ( return (
<div className="flex flex-col gap-4"> <div className="flex flex-col gap-4">
{tarefasAtivas.map((tarefa: Tarefa) => ( {tarefasAtivas.map((tarefa: Tarefa) => (
<div key={tarefa.id} className="border rounded p-4 shadow flex flex-col gap-2"> <div key={tarefa.id} className="border rounded-lg p-4 shadow flex flex-col gap-2 bg-white dark:bg-gray-800">
<div className="flex justify-between items-center"> <div className="flex flex-col md:flex-row md:justify-between md:items-center gap-2">
<span className="font-medium">{tarefa.titulo}</span> <div className="flex items-center gap-3">
<span className={`px-2 py-1 rounded text-xs ${ <span className="font-medium text-lg text-gray-900 dark:text-white">{tarefa.titulo}</span>
tarefa.status === 'CONCLUIDA' ? 'bg-green-100 text-green-700' : tarefa.status === 'EM_ANDAMENTO' ? 'bg-yellow-100 text-yellow-700' : 'bg-gray-100 text-gray-700' {/* Exibe o grau de prioridade com cor */}
}`}> <span className={`px-2 py-1 rounded text-xs font-semibold border ${
{tarefa.status.replace('_', ' ')} tarefa.prioridade === 'URGENTE' ? 'bg-red-100 text-red-700 border-red-300' :
</span> tarefa.prioridade === 'ALTA' ? 'bg-orange-100 text-orange-700 border-orange-300' :
<div className="flex items-center gap-2"> tarefa.prioridade === 'MEDIA' ? 'bg-yellow-100 text-yellow-700 border-yellow-300' :
'bg-green-100 text-green-700 border-green-300'
}`}>
{tarefa.prioridade === 'URGENTE' ? 'Urgente' : tarefa.prioridade === 'ALTA' ? 'Alta' : tarefa.prioridade === 'MEDIA' ? 'Média' : 'Baixa'}
</span>
</div>
<div className="flex items-center gap-3">
{/* Status da tarefa */}
<span className={`px-2 py-1 rounded text-xs font-semibold border ${
tarefa.status === 'CONCLUIDA' ? 'bg-green-100 text-green-700 border-green-300' :
tarefa.status === 'EM_ANDAMENTO' ? 'bg-blue-100 text-blue-700 border-blue-300' :
tarefa.status === 'PENDENTE' ? 'bg-gray-100 text-gray-700 border-gray-300' :
'bg-red-100 text-red-700 border-red-300'
}`}>
{tarefa.status.replace('_', ' ')}
</span>
<button <button
onClick={() => handleEdit(tarefa)} onClick={() => handleEdit(tarefa)}
className="text-blue-600 dark:text-blue-400 hover:text-blue-900 dark:hover:text-blue-300" className="text-blue-600 dark:text-blue-400 hover:text-blue-900 dark:hover:text-blue-300"
+35
View File
@@ -0,0 +1,35 @@
import { useQuery } from 'react-query';
import { Processo } from '../types/entities';
import api from '../services/api';
interface Benchmarking {
totalProcessos: number;
ativos: number;
procedentes: number;
improcedentesOuSemMerito: number;
}
// Hook para calcular benchmarking do escritório
export function useBenchmarking() {
return useQuery<Benchmarking>('benchmarking', async () => {
// Buscar todos os processos
const res = await api.get<Processo[]>('/processos');
const processos = res.data;
// Total de processos
const totalProcessos = processos.length;
// Total de processos ativos
const ativos = processos.filter(p => p.statusAtividade === 'ATIVO').length;
// Julgados procedentes
const procedentes = processos.filter(p => p.resultado === 'PROCEDENTE').length;
// Julgados improcedentes ou sem análise de mérito
const improcedentesOuSemMerito = processos.filter(p => p.resultado === 'IMPROCEDENTE' || p.resultado === 'SEM_ANALISE_MERITO').length;
return {
totalProcessos,
ativos,
procedentes,
improcedentesOuSemMerito,
};
});
}