Files
familienarchiv/frontend/src/lib/components/TranscriptionColumn.svelte
Marcel 94b5d1a5a8 fix(#240): align Mission Control Strip UI with final spec
- Strip heading: "Mitarbeiten" → "Was braucht Aufmerksamkeit?"
- Column 1 heading: "Segmentierung" → "Rahmen einzeichnen"; add green
  skill pill "✓ Ohne Vorkenntnisse"; heading color gray → ink (navy)
- Column 2 heading: "Transkription" → "Text eintippen"; add navy skill
  pill "Kurrent hilfreich"; heading color gray → ink; weekly pulse
  color green → ink (task, not achievement); progress bar track
  bg-gray-200/h-1.5 → bg-ink/20/h-1; add transition-all to fill
- Column 3 heading: "Lesefertig" → "Lesefertig ✓"; heading color
  gray → green-800; add "N Dokumente bereit" subtitle in green; add
  "Alle N lesen →" link at bottom; reviewed % color gray → green-800
- All columns: add CTA buttons at bottom (Jetzt einzeichnen /
  Jetzt tippen); empty state removed from cols 1 & 2 (columns
  hide when empty); empty-state ghost CTA in col 3 restyled as
  bordered button with hover:bg-ink
- Strip: add visibility guard — hides when all three lists are empty
- i18n: add mission_control_seg_skill_pill, mission_control_trans_skill_pill,
  mission_control_ready_subtitle, mission_control_ready_all_cta in
  de/en/es; update heading and CTA copy in all three locales

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-16 10:42:18 +02:00

100 lines
3.1 KiB
Svelte

<script lang="ts">
import * as m from '$lib/paraglide/messages.js';
import { getLocale } from '$lib/paraglide/runtime.js';
import ExpertBadge from './ExpertBadge.svelte';
type TranscriptionQueueItemDTO = {
id: string;
title: string;
documentDate?: string;
needsExpert: boolean;
annotationCount: number;
textedBlockCount: number;
reviewedBlockCount: number;
};
interface Props {
docs: TranscriptionQueueItemDTO[];
weeklyCount: number;
}
let { docs, weeklyCount }: Props = $props();
function formatDate(dateStr: string): string {
return new Intl.DateTimeFormat(getLocale(), {
day: 'numeric',
month: 'short',
year: 'numeric'
}).format(new Date(dateStr + 'T12:00:00'));
}
function blockProgress(doc: TranscriptionQueueItemDTO): number {
if (doc.annotationCount === 0) return 0;
return (doc.textedBlockCount / doc.annotationCount) * 100;
}
</script>
{#if docs.length > 0}
<div class="flex flex-col gap-3 rounded-sm border border-line bg-surface p-4">
<div>
<h3 class="mb-1 font-sans text-xs font-bold tracking-widest text-ink uppercase">
{m.mission_control_transcription_heading()}
</h3>
<span
class="inline-flex items-center gap-1 rounded-full border border-line bg-surface px-2 py-0.5 text-xs font-semibold text-ink"
>
{m.mission_control_trans_skill_pill()}
</span>
{#if weeklyCount > 0}
<p class="mt-1 text-xs font-semibold text-ink">
{m.mission_control_weekly_pulse({ count: weeklyCount })}
</p>
{/if}
</div>
<ul class="space-y-1">
{#each docs as doc (doc.id)}
<li>
<a
href="/documents/{doc.id}"
class="hover:bg-brand-sand/30 flex min-h-[44px] flex-col justify-center rounded px-1 py-2 focus-visible:ring-2 focus-visible:ring-brand-navy focus-visible:ring-offset-2 focus-visible:outline-none"
>
<div class="flex flex-wrap items-center gap-1.5">
<span class="font-serif text-sm text-ink">{doc.title}</span>
{#if doc.needsExpert}
<ExpertBadge />
{/if}
</div>
{#if doc.documentDate}
<span class="mt-0.5 text-xs text-gray-400">{formatDate(doc.documentDate)}</span>
{/if}
{#if doc.textedBlockCount > 0}
<div class="mt-1.5 flex items-center gap-2">
<span class="shrink-0 text-xs text-gray-400">
{m.mission_control_blocks_progress({
texted: doc.textedBlockCount,
total: doc.annotationCount
})}
</span>
<div class="h-1 flex-1 overflow-hidden rounded-full bg-ink/20">
<div
class="h-full rounded-full bg-ink transition-all"
style="width: {blockProgress(doc).toFixed(0)}%"
></div>
</div>
</div>
{:else}
<span class="mt-0.5 text-xs text-gray-400 italic"></span>
{/if}
</a>
</li>
{/each}
</ul>
<a
href="/enrich?filter=NEEDS_TRANSCRIPTION&next=1"
class="mt-auto block w-full rounded-sm bg-ink py-2 text-center text-xs font-semibold text-white transition-colors hover:bg-ink-2 focus-visible:ring-2 focus-visible:ring-ink focus-visible:ring-offset-1 focus-visible:outline-none"
>
{m.mission_control_transcription_cta()}
</a>
</div>
{/if}