dashboard: reimaginacao
Signed-off-by: Rodrigo B. de Sousa Martins <rodrigo.sousa.577@gmail.com>
This commit is contained in:
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>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|||||||
@@ -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,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
Reference in new issue
Block a user