frontend: fix PublicProvaUpload

Signed-off-by: Rodrigo B. de Sousa Martins <rodrigo@martinsevieira.adv.br>
This commit is contained in:
Rodrigo B. de Sousa Martins committed 2025-05-26 13:08:32 -03:00
1 parent fe54b55af0
commit 59ea762227
1 file changed
+52 -9
+52 -9
View File
@@ -3,6 +3,8 @@ import { useNavigate } from 'react-router-dom';
import { useDropzone } from 'react-dropzone';
import { toast } from 'react-toastify';
// Página pública: NÃO requer autenticação do usuário
export function ClientProvaUpload() {
const [file, setFile] = useState<File | null>(null);
const [uploading, setUploading] = useState(false);
@@ -43,9 +45,31 @@ export function ClientProvaUpload() {
}
}, []);
// Validação extra do arquivo antes do upload
function validateFile(file: File | null): string | null {
if (!file) return 'Nenhum arquivo selecionado.';
const allowedTypes = [
'image/jpeg', 'image/png', 'image/gif', 'image/webp', 'application/pdf'
];
if (!allowedTypes.includes(file.type)) {
return 'Tipo de arquivo não suportado. Use JPG, PNG, GIF, WEBP ou PDF.';
}
if (file.size > 10 * 1024 * 1024) {
return 'Arquivo excede o tamanho máximo de 10MB.';
}
return null;
}
const onDrop = useCallback(async (acceptedFiles: File[]) => {
if (acceptedFiles.length > 0) {
const selectedFile = acceptedFiles[0];
const validationError = validateFile(selectedFile);
if (validationError) {
toast.error(validationError);
setFile(null);
setFilePreview(null);
return;
}
setFile(selectedFile);
// Criar preview para imagens
@@ -77,6 +101,12 @@ export function ClientProvaUpload() {
toast.error('Por favor, selecione um arquivo primeiro');
return;
}
// Validação extra antes do envio
const validationError = validateFile(file);
if (validationError) {
toast.error(validationError);
return;
}
setUploading(true);
setUploadProgress(0);
@@ -120,7 +150,7 @@ export function ClientProvaUpload() {
// Adicionar timestamp preciso do cliente
formData.append('client_timestamp', new Date().toISOString());
// Criar simulação de progresso
// Simulação de progresso
const progressInterval = setInterval(() => {
setUploadProgress(prev => {
if (prev >= 95) {
@@ -131,10 +161,18 @@ export function ClientProvaUpload() {
});
}, 300);
const response = await fetch('/api/provas/upload', {
method: 'POST',
body: formData,
});
// Upload sem autenticação (página pública)
let response: Response;
try {
response = await fetch('/api/provas/upload', {
method: 'POST',
body: formData,
});
} catch (networkError) {
clearInterval(progressInterval);
setUploadProgress(0);
throw new Error('Erro de conexão. Verifique sua internet e tente novamente.');
}
clearInterval(progressInterval);
setUploadProgress(100);
@@ -155,9 +193,14 @@ export function ClientProvaUpload() {
}
// Ler o corpo da resposta
const result = await response.json();
let result: any;
try {
result = await response.json();
} catch {
throw new Error('Resposta inesperada do servidor.');
}
if (result.id) {
if (result && result.id) {
toast.success('Arquivo enviado com sucesso!');
// Navegar para a página de status
navigate(`/public/provas/status/${result.id}`);
@@ -165,10 +208,10 @@ export function ClientProvaUpload() {
throw new Error('ID do documento não encontrado na resposta');
}
} catch (error) {
} catch (error: any) {
console.error('Erro detalhado no upload:', error);
setError(error.message || 'Erro ao enviar arquivo. Por favor, tente novamente.');
toast.error('Falha no upload: ' + error.message);
toast.error('Falha no upload: ' + (error.message || 'Erro desconhecido'));
} finally {
setUploading(false);
}