progress bar + better ui (fix)

This commit is contained in:
Ludwig Lehnert
2026-03-27 20:10:51 +01:00
parent 83fbeff16c
commit 085d5e26cf
3 changed files with 35 additions and 15 deletions

View File

@@ -77,7 +77,13 @@ export function UploadProgressForm({ csrfToken }) {
}
return (
<form className="form-grid" onSubmit={handleSubmit} encType="multipart/form-data">
<form
className="form-grid"
onSubmit={handleSubmit}
action="/manage/api/upload"
method="post"
encType="multipart/form-data"
>
<input type="hidden" name="csrfToken" value={csrfToken} />
<label className="field">

View File

@@ -101,38 +101,57 @@ function dashboardHref(params = {}) {
: `${managementBasePath}/dashboard`;
}
function jsonError(message, status = 400) {
function expectsHtml(request) {
return String(request.headers.get('accept') || '').includes('text/html');
}
function errorResponse(request, message, status = 400) {
if (expectsHtml(request)) {
const target = new URL(dashboardHref({ error: message }), request.url);
return NextResponse.redirect(target, { status: 303 });
}
return NextResponse.json({ ok: false, error: message }, { status });
}
function successResponse(request, message) {
const redirectPath = dashboardHref({ success: message });
if (expectsHtml(request)) {
const target = new URL(redirectPath, request.url);
return NextResponse.redirect(target, { status: 303 });
}
return NextResponse.json({ ok: true, redirect: redirectPath });
}
export async function POST(request) {
await runCleanupIfNeeded();
const user = await getAuthenticatedUser();
if (!user) {
return jsonError('Nicht angemeldet.', 401);
return errorResponse(request, 'Nicht angemeldet.', 401);
}
let formData;
try {
formData = await request.formData();
} catch {
return jsonError('Ungültige Formulardaten.', 400);
return errorResponse(request, 'Ungültige Formulardaten.', 400);
}
try {
await verifyCsrf(formData);
} catch {
return jsonError('CSRF-Prüfung fehlgeschlagen.', 403);
return errorResponse(request, 'CSRF-Prüfung fehlgeschlagen.', 403);
}
const uploadedFile = uploadedFileFromForm(formData, 'file');
if (!uploadedFile || Number(uploadedFile.size || 0) <= 0) {
return jsonError('Keine Datei hochgeladen.', 400);
return errorResponse(request, 'Keine Datei hochgeladen.', 400);
}
if (maxUploadBytes > 0 && Number(uploadedFile.size || 0) > maxUploadBytes) {
return jsonError(`Datei überschreitet das Größenlimit (${maxUploadBytes} Bytes).`, 413);
return errorResponse(request, `Datei überschreitet das Größenlimit (${maxUploadBytes} Bytes).`, 413);
}
const now = Date.now();
@@ -156,7 +175,7 @@ export async function POST(request) {
}
if (!storedName || !storedPath) {
return jsonError('Upload-ID konnte nicht erzeugt werden.', 500);
return errorResponse(request, 'Upload-ID konnte nicht erzeugt werden.', 500);
}
try {
@@ -183,11 +202,8 @@ export async function POST(request) {
await getRequestMeta()
);
} catch {
return jsonError('Upload fehlgeschlagen.', 500);
return errorResponse(request, 'Upload fehlgeschlagen.', 500);
}
return NextResponse.json({
ok: true,
redirect: dashboardHref({ success: 'Upload abgeschlossen.' }),
});
return successResponse(request, 'Upload abgeschlossen.');
}

View File

@@ -153,7 +153,6 @@ export async function clearAuthCookie() {
export async function requireAuthenticatedUser() {
const user = await getAuthenticatedUser();
if (!user) {
await clearAuthCookie();
redirect('/manage/login');
}
return user;
@@ -162,7 +161,6 @@ export async function requireAuthenticatedUser() {
export async function requireAdminUser() {
const user = await getAuthenticatedUser();
if (!user || !user.admin) {
await clearAuthCookie();
redirect('/manage/admin');
}
return user;