feat(enrich): add metadata enrichment queue UI
Some checks failed
CI / Unit & Component Tests (pull_request) Successful in 2m19s
CI / Backend Unit Tests (pull_request) Successful in 2m11s
CI / E2E Tests (pull_request) Failing after 29m32s
CI / Unit & Component Tests (push) Successful in 2m21s
CI / Backend Unit Tests (push) Successful in 2m12s
CI / E2E Tests (push) Failing after 28m54s

Home page shows "Needs metadata" card when incomplete documents exist.
/enrich list shows all incomplete documents; /enrich/[id] provides a
split PDF-preview + compact form view with Skip / Save / Save & reviewed
actions that auto-advance through the queue.

New document page gets Save vs Save & reviewed split. Edit page gets
"Mark for review" secondary button to push a document back into the queue.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit was merged in pull request #77.
This commit is contained in:
Marcel
2026-03-26 13:45:16 +01:00
parent 0ce18e1eed
commit aab9e9a4b0
16 changed files with 762 additions and 27 deletions

View File

@@ -0,0 +1,106 @@
<script lang="ts">
import { m } from '$lib/paraglide/messages.js';
let { data } = $props();
const documents = $derived(data.documents);
const count = $derived(documents.length);
function formatUploadDate(createdAt: string): string {
return new Intl.DateTimeFormat('de-DE', {
day: 'numeric',
month: 'long',
year: 'numeric'
}).format(new Date(createdAt));
}
</script>
<div class="mx-auto max-w-4xl px-4 py-10">
<!-- Back Link -->
<a
href="/"
class="group mb-4 inline-flex items-center font-sans text-xs font-bold tracking-widest text-gray-500 uppercase transition-colors hover:text-brand-navy"
>
<img
src="/degruyter-icons/Simple/Medium-24px/SVG/Action/Arrow/Arrow-Left-MD.svg"
alt=""
aria-hidden="true"
class="mr-2 h-4 w-4 transform transition-transform group-hover:-translate-x-1"
/>
{m.enrich_list_back()}
</a>
<!-- Page Header -->
<div class="border-brand-sand mb-8 flex items-center justify-between border-b pb-6">
<div>
<h1 class="font-serif text-3xl font-medium text-brand-navy">
{m.enrich_list_heading()}
</h1>
{#if count > 0}
<p class="mt-2 font-sans text-sm text-brand-navy/60">
{count}
{m.enrich_list_count()}
</p>
{/if}
</div>
{#if count > 0}
<a
href="/enrich/{documents[0].id}"
class="bg-brand-navy px-5 py-2 font-sans text-xs font-bold tracking-widest text-white uppercase transition-colors hover:bg-brand-navy/90"
>
{m.enrich_list_start()}
</a>
{/if}
</div>
<!-- Empty State -->
{#if count === 0}
<div
class="border-brand-sand flex flex-col items-center justify-center rounded-sm border border-dashed bg-white py-20 text-center"
>
<div class="bg-brand-sand/60 mb-4 flex h-14 w-14 items-center justify-center rounded-full">
<img
src="/degruyter-icons/Simple/Medium-24px/SVG/Action/Check/Check-Circle-MD.svg"
alt=""
aria-hidden="true"
class="h-7 w-7 opacity-50"
/>
</div>
<p class="font-serif text-lg font-medium text-brand-navy">
{m.enrich_list_empty_heading()}
</p>
<p class="mt-2 max-w-xs font-sans text-sm text-brand-navy/60">
{m.enrich_list_empty_body()}
</p>
</div>
{:else}
<!-- Document Rows -->
<div class="border-brand-sand border bg-white shadow-sm">
<ul class="divide-brand-sand divide-y">
{#each documents as doc (doc.id)}
<li class="group hover:bg-brand-sand/30 transition-colors duration-200">
<a href="/enrich/{doc.id}" class="flex items-center justify-between p-6">
<div class="min-w-0 flex-1">
<p
class="font-serif text-lg font-medium text-brand-navy decoration-brand-mint decoration-2 underline-offset-4 group-hover:underline"
>
{doc.title || doc.originalFilename}
</p>
<p class="mt-1 font-sans text-xs text-brand-navy/50">
{formatUploadDate(doc.createdAt)}
</p>
</div>
<img
src="/degruyter-icons/Simple/Medium-24px/SVG/Action/Arrow/Arrow-Right-MD.svg"
alt=""
aria-hidden="true"
class="ml-4 h-5 w-5 shrink-0 opacity-30 transition-opacity group-hover:opacity-70"
/>
</a>
</li>
{/each}
</ul>
</div>
{/if}
</div>