164 lines
5.2 KiB
TypeScript
164 lines
5.2 KiB
TypeScript
import { useEffect, useState } from 'react';
|
|
import { useParams, useNavigate } from 'react-router-dom';
|
|
import { Card } from '../../components/ui/Card';
|
|
import { format } from 'date-fns';
|
|
|
|
interface ProvaStatus {
|
|
id: string;
|
|
status: 'PENDENTE' | 'PROCESSANDO' | 'CONCLUIDO' | 'ERRO';
|
|
fileName: string;
|
|
checksumSha256: string;
|
|
checksumSha512: string;
|
|
checksumMd5: string;
|
|
reportPath: string;
|
|
error?: string;
|
|
}
|
|
|
|
export function ProvaStatus() {
|
|
const { id } = useParams<{ id: string }>();
|
|
const [status, setStatus] = useState<ProvaStatus | null>(null);
|
|
const [error, setError] = useState<string | null>(null);
|
|
const navigate = useNavigate();
|
|
|
|
useEffect(() => {
|
|
const checkStatus = async () => {
|
|
try {
|
|
const response = await fetch(`/api/provas/${id}/status`);
|
|
|
|
// Verificar se a resposta foi bem-sucedida
|
|
if (!response.ok) {
|
|
const errorText = await response.text();
|
|
throw new Error(errorText || 'Erro ao buscar status');
|
|
}
|
|
|
|
const data = await response.json();
|
|
setStatus(data);
|
|
|
|
// Continuar verificando se ainda estiver processando
|
|
if (data.status === 'PENDENTE' || data.status === 'PROCESSANDO') {
|
|
setTimeout(checkStatus, 2000);
|
|
}
|
|
} catch (error) {
|
|
console.error('Erro detalhado ao verificar status:', error);
|
|
setError('Erro ao verificar status da prova');
|
|
}
|
|
};
|
|
|
|
checkStatus();
|
|
}, [id]);
|
|
|
|
const handleDownloadReport = () => {
|
|
if (status && status.status === 'CONCLUIDO') {
|
|
window.open(`/api/provas/relatorio/${status.checksumSha256}`, '_blank');
|
|
}
|
|
};
|
|
|
|
const handleViewVerification = () => {
|
|
if (status && status.checksumSha256) {
|
|
navigate(`/provas/verificar/${status.checksumSha256}`);
|
|
}
|
|
};
|
|
|
|
if (error) return (
|
|
<div className="max-w-3xl mx-auto p-4">
|
|
<Card>
|
|
<div className="p-6 text-center">
|
|
<div className="text-red-600 mb-4">{error}</div>
|
|
<button
|
|
onClick={() => navigate('/provas/upload')}
|
|
className="px-4 py-2 bg-blue-600 text-white rounded-lg"
|
|
>
|
|
Voltar para Upload
|
|
</button>
|
|
</div>
|
|
</Card>
|
|
</div>
|
|
);
|
|
|
|
if (!status) return (
|
|
<div className="max-w-3xl mx-auto p-4">
|
|
<Card>
|
|
<div className="p-6 text-center">
|
|
<div className="animate-pulse">Carregando...</div>
|
|
</div>
|
|
</Card>
|
|
</div>
|
|
);
|
|
|
|
return (
|
|
<div className="max-w-3xl mx-auto p-4">
|
|
<Card>
|
|
<div className="p-6">
|
|
<h2 className="text-2xl font-bold mb-4">Status da Validação</h2>
|
|
|
|
<div className="space-y-4">
|
|
<div>
|
|
<p className="text-sm text-gray-500">Arquivo</p>
|
|
<p className="font-medium">{status.fileName}</p>
|
|
</div>
|
|
|
|
<div>
|
|
<p className="text-sm text-gray-500">Status</p>
|
|
<p className={`font-medium ${
|
|
status.status === 'CONCLUIDO' ? 'text-green-600' :
|
|
status.status === 'ERRO' ? 'text-red-600' :
|
|
'text-blue-600'
|
|
}`}>
|
|
{status.status === 'PENDENTE' ? 'Em fila de processamento' :
|
|
status.status === 'PROCESSANDO' ? 'Processando...' :
|
|
status.status === 'CONCLUIDO' ? 'Concluído' :
|
|
'Erro ao processar'}
|
|
</p>
|
|
</div>
|
|
|
|
{status.status === 'CONCLUIDO' && (
|
|
<>
|
|
<div>
|
|
<p className="text-sm text-gray-500">Checksums</p>
|
|
<div className="space-y-1 mt-1 text-xs font-mono">
|
|
<p>SHA-256: {status.checksumSha256}</p>
|
|
<p>SHA-512: {status.checksumSha512}</p>
|
|
<p>MD5: {status.checksumMd5}</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="pt-4 flex flex-col sm:flex-row gap-3">
|
|
<button
|
|
onClick={handleDownloadReport}
|
|
className="inline-flex items-center px-4 py-2 border border-transparent text-sm font-medium rounded-md shadow-sm text-white bg-blue-600 hover:bg-blue-700"
|
|
>
|
|
Baixar Relatório
|
|
</button>
|
|
|
|
<button
|
|
onClick={handleViewVerification}
|
|
className="inline-flex items-center px-4 py-2 border border-gray-300 text-sm font-medium rounded-md shadow-sm text-gray-700 bg-white hover:bg-gray-50"
|
|
>
|
|
Ver Verificação
|
|
</button>
|
|
</div>
|
|
</>
|
|
)}
|
|
|
|
{status.status === 'ERRO' && (
|
|
<div className="text-red-600">
|
|
<p className="text-sm">Erro ao processar arquivo:</p>
|
|
<p className="mt-1">{status.error}</p>
|
|
|
|
<div className="mt-4">
|
|
<button
|
|
onClick={() => navigate('/provas/upload')}
|
|
className="px-4 py-2 bg-blue-600 text-white rounded-lg"
|
|
>
|
|
Tentar Novamente
|
|
</button>
|
|
</div>
|
|
</div>
|
|
)}
|
|
</div>
|
|
</div>
|
|
</Card>
|
|
</div>
|
|
);
|
|
}
|