Files
familienarchiv/frontend/src/lib/components/DocumentThumbnail.svelte
Marcel 817749889a refactor(document-thumbnail): read doc.thumbnailUrl instead of composing locally
The backend now exposes thumbnailUrl as a serialised computed property
on Document, so the component drops its dependency on the frontend
URL-builder. PersonDocumentList's inline Doc prop type follows the
same shift (#309).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-24 07:26:23 +02:00

57 lines
2.2 KiB
Svelte
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<script lang="ts">
import type { components } from '$lib/generated/api';
type Doc = Pick<components['schemas']['Document'], 'id' | 'thumbnailUrl' | 'contentType'>;
let { doc, size = 'sm' }: { doc: Doc; size?: 'sm' | 'lg' } = $props();
const url = $derived(doc.thumbnailUrl ?? null);
const containerClass = $derived(
size === 'lg'
? 'relative h-[168px] w-[120px] flex-shrink-0 overflow-hidden rounded-sm border border-line bg-white'
: 'relative h-[84px] w-[60px] flex-shrink-0 overflow-hidden rounded-sm border border-line bg-white'
);
const iconClass = $derived(size === 'lg' ? 'h-16 w-16' : 'h-8 w-8');
</script>
<!--
Fixed-aspect (5:7, ≈A4) tile used wherever a document row appears. `sm` is
60×84 (compact rows, person sublists); `lg` is 120×168 (main document list).
When the backend has generated a thumbnail we render it with `object-cover`
+ `object-top` so letter salutations stay visible; otherwise we fall back
to the file-type icon so the row never shows an empty rectangle. Dark mode
uses `mix-blend-multiply` to keep bright paper scans from glaring against
the dark page background.
-->
<div class={containerClass}>
{#if url}
<img
src={url}
alt=""
class="h-full w-full object-cover object-top dark:mix-blend-multiply"
loading="lazy"
decoding="async"
/>
{:else}
<div class="flex h-full w-full items-center justify-center text-ink-3" aria-hidden="true">
<!-- Generic document icon (heroicons document-text outline). Shown when the
thumbnail hasn't been generated yet — applies equally to PDFs and to
image scans, so we deliberately avoid a PDF-specific glyph here. -->
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width="1.5"
stroke="currentColor"
class={iconClass}
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M19.5 14.25v-2.625a3.375 3.375 0 0 0-3.375-3.375h-1.5A1.125 1.125 0 0 1 13.5 7.125v-1.5a3.375 3.375 0 0 0-3.375-3.375H8.25m2.25 0H5.625c-.621 0-1.125.504-1.125 1.125v17.25c0 .621.504 1.125 1.125 1.125h12.75c.621 0 1.125-.504 1.125-1.125V11.25a9 9 0 0 0-9-9Z M9 12.75h6M9 15.75h6M9 18.75h3"
/>
</svg>
</div>
{/if}
</div>