'use client'; import { useState } from 'react'; function parseErrorMessage(xhr) { const response = xhr.response; if (response && typeof response === 'object' && response.error) { return String(response.error); } try { const parsed = JSON.parse(xhr.responseText || '{}'); if (parsed && typeof parsed.error === 'string') { return parsed.error; } } catch { } return `Upload fehlgeschlagen (HTTP ${xhr.status}).`; } export function UploadProgressForm({ csrfToken }) { const [uploading, setUploading] = useState(false); const [progress, setProgress] = useState(0); const [localError, setLocalError] = useState(''); function handleSubmit(event) { event.preventDefault(); if (uploading) { return; } const form = event.currentTarget; const formData = new FormData(form); const uploadedFile = formData.get('file'); if (!uploadedFile || typeof uploadedFile === 'string' || !uploadedFile.size) { setLocalError('Bitte zuerst eine Datei auswählen.'); return; } setUploading(true); setProgress(0); setLocalError(''); const xhr = new XMLHttpRequest(); xhr.open('POST', '/manage/api/upload', true); xhr.responseType = 'json'; xhr.setRequestHeader('x-csrf-token', csrfToken); xhr.upload.onprogress = (uploadEvent) => { if (!uploadEvent.lengthComputable || uploadEvent.total <= 0) { return; } const nextValue = Math.round((uploadEvent.loaded / uploadEvent.total) * 100); setProgress(Math.max(0, Math.min(100, nextValue))); }; xhr.onerror = () => { setUploading(false); setLocalError('Netzwerkfehler beim Upload.'); }; xhr.onload = () => { if (xhr.status >= 200 && xhr.status < 300) { const redirectPath = xhr.response?.redirect || '/manage/dashboard?success=Upload%20abgeschlossen.'; window.location.assign(redirectPath); return; } setUploading(false); setProgress(0); setLocalError(parseErrorMessage(xhr)); }; xhr.send(formData); } return (
{uploading ? (
Upload läuft … {progress}%
) : null} {localError ?
{localError}
: null} ); }