Files
familienarchiv/frontend/src/lib/components/PanelMetadata.svelte
Marcel fcff7fbdb1
Some checks failed
CI / Unit & Component Tests (push) Has been cancelled
CI / Backend Unit Tests (push) Has been cancelled
CI / E2E Tests (push) Has been cancelled
fix(#94): replace text-white with text-primary-fg on all primary buttons
In dark mode --c-primary switches from navy (#012851) to mint (#a1dcd8).
Buttons using bg-primary+text-white showed white text on mint at 1.4:1
contrast — invisible. bg-brand-navy buttons were also invisible (navy on
near-black canvas, 1.3:1).

Replaced in 28 components app-wide:
- bg-primary ... text-white → text-primary-fg
- hover:bg-primary hover:text-white → hover:text-primary-fg
- bg-brand-navy ... text-white + hover:bg-brand-navy/90 →
  bg-primary ... text-primary-fg + hover:bg-primary/90

Light mode is unchanged: primary-fg = white in light mode.
Dark mode: primary-fg = navy (#012851) on mint bg = readable.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-27 16:07:37 +01:00

201 lines
5.8 KiB
Svelte

<script lang="ts">
import { m } from '$lib/paraglide/messages.js';
import { formatDate } from '$lib/utils/date';
type Person = { id: string; firstName: string; lastName: string; alias?: string | null };
type Tag = { id: string; name: string };
type Doc = {
documentDate?: string | null;
location?: string | null;
documentLocation?: string | null;
tags?: Tag[] | null;
sender?: Person | null;
receivers?: Person[] | null;
};
let { doc }: { doc: Doc } = $props();
</script>
<div class="space-y-10 p-6">
<!-- DETAILS GROUP -->
<div>
<h3
class="mb-4 border-b border-line pb-2 font-sans text-xs font-bold tracking-widest text-ink uppercase"
>
{m.doc_section_details()}
</h3>
<div class="space-y-5">
<!-- Date -->
<div class="flex items-start">
<span class="mt-0.5 w-8 text-accent">
<img
src="/degruyter-icons/Simple/Medium-24px/SVG/Action/Calendar/Calendar-Add-MD.svg"
alt=""
aria-hidden="true"
class="h-5 w-5"
/>
</span>
<div>
<span class="block font-serif text-lg text-ink">
{doc.documentDate ? formatDate(doc.documentDate) : '—'}
</span>
<span class="font-sans text-xs text-ink-2">{m.doc_label_document_date()}</span>
</div>
</div>
<!-- Creation Location -->
<div class="flex items-start">
<span class="mt-0.5 w-8 text-accent">
<img
src="/degruyter-icons/Simple/Medium-24px/SVG/Action/Location-MD.svg"
alt=""
aria-hidden="true"
class="h-5 w-5"
/>
</span>
<div>
<span class="block font-serif text-lg text-ink">
{doc.location ? doc.location : '—'}
</span>
<span class="font-sans text-xs text-ink-2">{m.doc_label_creation_location()}</span>
</div>
</div>
<!-- Physical Archive Location -->
{#if doc.documentLocation}
<div class="flex items-start">
<span class="mt-0.5 w-8 text-accent">
<img
src="/degruyter-icons/Simple/Medium-24px/SVG/Action/Folder-MD.svg"
alt=""
aria-hidden="true"
class="h-5 w-5"
/>
</span>
<div>
<span class="block font-serif text-lg text-ink">
{doc.documentLocation}
</span>
<span class="font-sans text-xs text-ink-2"
>{m.doc_label_archive_location_original()}</span
>
</div>
</div>
{/if}
<!-- Tags -->
{#if doc.tags && doc.tags.length > 0}
<div class="flex items-start">
<span class="mt-0.5 w-8 text-accent">
<img
src="/degruyter-icons/Simple/Medium-24px/SVG/Action/Bookmark/Bookmark-Outline-MD.svg"
alt=""
aria-hidden="true"
class="h-5 w-5"
/>
</span>
<div class="flex-1">
<div class="mb-1 flex flex-wrap gap-2">
{#each doc.tags as tag (tag.id)}
<a
href="/?tag={encodeURIComponent(tag.name)}"
class="inline-flex items-center rounded bg-muted px-2 py-0.5 text-xs font-bold tracking-wide text-ink uppercase transition-colors hover:bg-primary hover:text-primary-fg"
title={m.doc_tag_filter_title({ name: tag.name })}
>
{tag.name}
</a>
{/each}
</div>
<span class="font-sans text-xs text-ink-2">{m.form_label_tags()}</span>
</div>
</div>
{/if}
</div>
</div>
<!-- PERSONEN GROUP -->
<div>
<h3
class="mb-4 border-b border-line pb-2 font-sans text-xs font-bold tracking-widest text-ink uppercase"
>
{m.doc_section_persons()}
</h3>
<div class="mb-6">
<span class="mb-2 block font-sans text-xs text-ink-3 uppercase">{m.form_label_sender()}</span>
{#if doc.sender}
<a
href="/persons/{doc.sender.id}"
class="group block rounded border border-line bg-muted p-3 transition hover:border-accent hover:bg-accent/10"
>
<div class="flex items-center gap-3">
<div
class="flex h-8 w-8 items-center justify-center rounded-full bg-primary font-serif text-sm text-primary-fg"
>
{doc.sender.firstName[0]}{doc.sender.lastName[0]}
</div>
<div>
<p
class="font-serif text-ink decoration-brand-mint underline-offset-2 group-hover:underline"
>
{doc.sender.firstName}
{doc.sender.lastName}
</p>
{#if doc.sender.alias}
<p class="font-sans text-xs text-ink-2">{doc.sender.alias}</p>
{/if}
</div>
</div>
</a>
{:else}
<span class="font-serif text-sm text-ink-3 italic">{m.doc_sender_not_specified()}</span>
{/if}
</div>
<div>
<span class="mb-2 block font-sans text-xs text-ink-3 uppercase"
>{m.form_label_receivers()}</span
>
{#if doc.receivers && doc.receivers.length > 0}
<div class="space-y-2">
{#each doc.receivers as receiver (receiver.id)}
<div
class="group flex items-center justify-between rounded border border-line bg-surface p-3 transition hover:border-primary"
>
<a href="/persons/{receiver.id}" class="flex min-w-0 flex-1 items-center gap-3">
<div
class="flex h-6 w-6 items-center justify-center rounded-full bg-muted font-serif text-xs text-ink-2"
>
{receiver.firstName[0]}{receiver.lastName[0]}
</div>
<span class="truncate font-serif text-sm text-ink">
{receiver.firstName}
{receiver.lastName}
</span>
</a>
{#if doc.sender}
<a
href="/conversations?senderId={doc.sender.id}&receiverId={receiver.id}"
class="text-ink-3 transition hover:text-accent"
title={m.doc_conversation_title()}
>
<img
src="/degruyter-icons/Simple/Medium-24px/SVG/Action/Chat-MD.svg"
alt=""
aria-hidden="true"
class="h-5 w-5"
/>
</a>
{/if}
</div>
{/each}
</div>
{:else}
<span class="font-serif text-sm text-ink-3 italic">{m.doc_no_receivers()}</span>
{/if}
</div>
</div>
</div>