67 lines
1.8 KiB
Svelte
67 lines
1.8 KiB
Svelte
<script lang="ts">
|
|
import * as m from '$lib/paraglide/messages.js';
|
|
import { getLocale } from '$lib/paraglide/runtime.js';
|
|
import type { components } from '$lib/generated/api';
|
|
|
|
type Document = {
|
|
id: string;
|
|
title: string;
|
|
updatedAt?: string;
|
|
sender?: { id: string; firstName: string; lastName: string };
|
|
};
|
|
|
|
type StatsDTO = components['schemas']['StatsDTO'];
|
|
|
|
interface Props {
|
|
recentDocs: Document[];
|
|
stats?: StatsDTO | null;
|
|
}
|
|
|
|
let { recentDocs, stats = null }: Props = $props();
|
|
|
|
function formatDate(dateStr: string): string {
|
|
// updatedAt is a full ISO datetime — no T12:00:00 noon-anchor needed here
|
|
return new Intl.DateTimeFormat(getLocale(), {
|
|
day: 'numeric',
|
|
month: 'long',
|
|
year: 'numeric'
|
|
}).format(new Date(dateStr));
|
|
}
|
|
</script>
|
|
|
|
{#if recentDocs.length > 0}
|
|
<div data-testid="dashboard-recent-docs" class="rounded-sm border border-line bg-surface p-6">
|
|
<h2 class="mb-4 font-sans text-xs font-bold tracking-widest text-gray-400 uppercase">
|
|
{m.dashboard_recent_heading()}
|
|
</h2>
|
|
{#each recentDocs as doc (doc.id)}
|
|
<div
|
|
data-testid="doc-row-{doc.id}"
|
|
class="flex min-h-[44px] items-center justify-between border-b border-line py-2 last:border-0"
|
|
>
|
|
<a
|
|
href="/documents/{doc.id}"
|
|
class="font-serif text-lg text-ink hover:text-ink-2 hover:underline"
|
|
>
|
|
{doc.title}
|
|
</a>
|
|
{#if doc.updatedAt}
|
|
<span
|
|
data-testid="doc-date-{doc.id}"
|
|
class="ml-2 shrink-0 font-sans text-xs text-gray-400"
|
|
>
|
|
{formatDate(doc.updatedAt)}
|
|
</span>
|
|
{/if}
|
|
</div>
|
|
{/each}
|
|
{#if stats?.totalDocuments != null}
|
|
<p data-testid="dashboard-stats-footnote" class="mt-4 font-sans text-sm text-ink-3">
|
|
{stats.totalDocuments}
|
|
{m.dashboard_stats_documents()} · {stats.totalPersons}
|
|
{m.dashboard_stats_persons()}
|
|
</p>
|
|
{/if}
|
|
</div>
|
|
{/if}
|