fix(bulk-upload): spec-compliant split-panel layout with local PDF preview
Rewrites BulkDocumentEditLayout to match the spec exactly: - Fixed viewport layout (same as DocumentEditLayout) filling viewport below nav - Split panel visible in all states (N=0/1/≥2) — was fullscreen dark drop zone - N=0: centered drop-zone-box in left panel; shared form visible but greyed out - N≥1: real PDF preview via URL.createObjectURL (no server upload required) - N≥2: FileSwitcherStrip at bottom of left panel; count pill + discard in topbar - FileEntry gains previewUrl; blob URLs created on add, revoked on remove/destroy - save() checks response.ok and marks failed files with status: 'error' - BulkDropZone redesigned: spec-accurate box with circular mint icon, serif title - FileSwitcherStrip: number badges, arrows, keyboard nav via data-chip-id selector - ScopeCard, UploadSaveBar: hardcoded German replaced with Paraglide i18n keys - +page.svelte simplified to bare component render (layout is self-contained) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,4 +1,6 @@
|
||||
<script lang="ts">
|
||||
import { m } from '$lib/paraglide/messages.js';
|
||||
|
||||
let {
|
||||
onFilesAdded
|
||||
}: {
|
||||
@@ -8,30 +10,35 @@ let {
|
||||
let isDragging = $state(false);
|
||||
</script>
|
||||
|
||||
<div class="flex min-h-[300px] flex-1 flex-col items-center justify-center bg-pdf-bg">
|
||||
<div
|
||||
role="region"
|
||||
aria-label="Dateien ablegen"
|
||||
data-testid="bulk-drop-zone"
|
||||
class="flex flex-1 flex-col items-center justify-center p-6"
|
||||
ondragover={(e) => {
|
||||
e.preventDefault();
|
||||
isDragging = true;
|
||||
}}
|
||||
ondragleave={() => (isDragging = false)}
|
||||
ondrop={(e) => {
|
||||
e.preventDefault();
|
||||
isDragging = false;
|
||||
if (e.dataTransfer && e.dataTransfer.files.length > 0) {
|
||||
onFilesAdded(Array.from(e.dataTransfer.files));
|
||||
}
|
||||
}}
|
||||
>
|
||||
<div
|
||||
role="region"
|
||||
aria-label="Dateien ablegen"
|
||||
data-testid="bulk-drop-zone"
|
||||
class="flex flex-col items-center gap-4 rounded-sm border border-dashed p-12 text-center transition-colors
|
||||
{isDragging ? 'border-brand-mint ring-2 ring-brand-mint' : 'border-white/20'}"
|
||||
ondragover={(e) => {
|
||||
e.preventDefault();
|
||||
isDragging = true;
|
||||
}}
|
||||
ondragleave={() => (isDragging = false)}
|
||||
ondrop={(e) => {
|
||||
e.preventDefault();
|
||||
isDragging = false;
|
||||
if (e.dataTransfer && e.dataTransfer.files.length > 0) {
|
||||
onFilesAdded(Array.from(e.dataTransfer.files));
|
||||
}
|
||||
}}
|
||||
class={[
|
||||
'flex w-full max-w-sm flex-col items-center gap-3 rounded-md border-2 border-dashed px-6 py-9 text-center transition-colors',
|
||||
isDragging ? 'border-accent bg-accent/10' : 'border-accent/50 bg-white/[0.04]'
|
||||
].join(' ')}
|
||||
>
|
||||
<div class="flex h-8 w-8 items-center justify-center rounded-full bg-white/10 text-white/40">
|
||||
<!-- Circular mint icon -->
|
||||
<div class="flex h-14 w-14 items-center justify-center rounded-full bg-accent text-primary">
|
||||
<svg
|
||||
width="16"
|
||||
height="16"
|
||||
width="22"
|
||||
height="22"
|
||||
viewBox="0 0 32 32"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
aria-hidden="true"
|
||||
@@ -42,11 +49,20 @@ let isDragging = $state(false);
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<p class="text-sm font-medium text-white/60">PDF-Dateien hier ablegen</p>
|
||||
<p class="text-xs text-white/30">oder</p>
|
||||
|
||||
<!-- Serif title -->
|
||||
<p class="font-serif text-sm font-bold text-ink">{m.bulk_drop_hint()}</p>
|
||||
|
||||
<!-- Sub description -->
|
||||
<p class="text-xs leading-relaxed text-ink-2">
|
||||
Für jede Datei wird ein eigenes Dokument erstellt.<br />
|
||||
<strong class="text-ink">Der Titel</strong> wird aus dem Dateinamen vorausgefüllt —
|
||||
<strong class="text-ink">alle anderen Felder</strong> gelten für alle gemeinsam.
|
||||
</p>
|
||||
|
||||
<!-- CTA button -->
|
||||
<label
|
||||
class="flex min-h-[44px] cursor-pointer items-center rounded-sm bg-brand-navy px-4 py-1.5 text-xs font-bold tracking-widest text-white/90 uppercase"
|
||||
aria-label="Dateien auswählen"
|
||||
class="flex min-h-[44px] cursor-pointer items-center rounded-sm bg-primary px-4 py-2 text-xs font-bold tracking-widest text-primary-fg uppercase transition-opacity hover:opacity-90"
|
||||
>
|
||||
Dateien auswählen
|
||||
<input
|
||||
@@ -60,5 +76,8 @@ let isDragging = $state(false);
|
||||
}}
|
||||
/>
|
||||
</label>
|
||||
|
||||
<!-- Format hint -->
|
||||
<p class="text-[11px] text-ink-3">{m.bulk_drop_sub()}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user