feat(frontend): render DocumentThumbnail in DocumentRow and PersonDocumentList

Home search rows and person detail sidebars now show the real
first-page preview when one exists, falling back to the PDF icon
for documents the backfill hasn't processed yet. The old `variant`
prop on PersonDocumentList is removed — it tinted the icon
differently for sent vs received, which no longer applies with a
uniform thumbnail tile.

Refs #307

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Marcel
2026-04-22 22:36:20 +02:00
parent be184d8faf
commit 04ebd2a5bd
3 changed files with 12 additions and 22 deletions

View File

@@ -6,6 +6,7 @@ import { formatDate } from '$lib/utils/date';
import * as m from '$lib/paraglide/messages.js';
import ProgressRing from './ProgressRing.svelte';
import ContributorStack from './ContributorStack.svelte';
import DocumentThumbnail from './DocumentThumbnail.svelte';
type DocumentSearchItem = components['schemas']['DocumentSearchItem'];
@@ -37,7 +38,10 @@ function safeTagColor(color: string | null | undefined): string {
<li class="group transition-colors duration-200 hover:bg-muted/50">
<a href="/documents/{doc.id}" class="block px-4 py-4 sm:py-5">
<div class="flex gap-0 sm:gap-5">
<div class="flex gap-3 sm:gap-5">
<!-- Thumbnail tile -->
<DocumentThumbnail doc={doc} />
<!-- Left column -->
<div class="flex-1 sm:border-r sm:border-line sm:pr-5">
<!-- Title -->

View File

@@ -72,14 +72,12 @@ const coCorrespondents = $derived.by(() => {
documents={sentDocuments}
heading={m.person_docs_heading()}
emptyMessage={m.person_no_docs()}
variant="sent"
/>
<PersonDocumentList
documents={receivedDocuments}
heading={m.person_received_docs_heading()}
emptyMessage={m.person_no_received_docs()}
variant="received"
/>
</div>
</div>

View File

@@ -3,14 +3,14 @@ import { m } from '$lib/paraglide/messages.js';
import { formatDate } from '$lib/utils/date';
import { formatDocumentStatus } from '$lib/utils/documentStatusLabel';
import { sortDocumentsByDate, type SortDir } from '$lib/utils/sort';
import DocumentThumbnail from '$lib/components/DocumentThumbnail.svelte';
const DOCS_PREVIEW_LIMIT = 5;
let {
documents,
heading,
emptyMessage,
variant = 'sent'
emptyMessage
}: {
documents: {
id: string;
@@ -19,10 +19,12 @@ let {
documentDate?: string | null;
location?: string | null;
status: string;
contentType?: string;
thumbnailKey?: string;
thumbnailGeneratedAt?: string;
}[];
heading: string;
emptyMessage: string;
variant?: 'sent' | 'received';
} = $props();
const yearRange = $derived.by(() => {
@@ -42,11 +44,6 @@ const sortedDocuments = $derived(sortDocumentsByDate(documents, sortDir));
const visibleDocuments = $derived(
showAll ? sortedDocuments : sortedDocuments.slice(0, DOCS_PREVIEW_LIMIT)
);
// Spec: sent = navy-tint icon bg, received = teal-tint icon bg
const iconClasses = $derived(
variant === 'sent' ? 'bg-primary/10 text-primary' : 'bg-accent/20 text-accent-fg'
);
</script>
<div class="mb-4 rounded-sm border border-line bg-surface">
@@ -81,17 +78,8 @@ const iconClasses = $derived(
href="/documents/{doc.id}"
class="group flex items-center gap-3 border-b border-line px-4 py-3 transition-colors last:border-b-0 hover:bg-muted"
>
<!-- Tinted doc icon -->
<div
class="flex h-8 w-8 flex-shrink-0 items-center justify-center rounded {iconClasses}"
>
<img
src="/degruyter-icons/Simple/Medium-24px/SVG/Action/PDF-Document-MD.svg"
alt=""
aria-hidden="true"
class="h-4 w-4"
/>
</div>
<!-- Thumbnail tile -->
<DocumentThumbnail doc={doc} />
<!-- Title + meta -->
<div class="min-w-0 flex-1">