refactor(dashboard): align ReaderPersonChips cards with /persons overview style
Some checks failed
CI / OCR Service Tests (push) Has been cancelled
CI / Backend Unit Tests (push) Has been cancelled
CI / Unit & Component Tests (push) Has started running
CI / Unit & Component Tests (pull_request) Failing after 4m10s
CI / OCR Service Tests (pull_request) Successful in 35s
CI / Backend Unit Tests (pull_request) Failing after 3m33s

- rounded, px-4 py-6, shadow-sm, gap-4 — matches overview card sizing
- hover: left accent border + shadow-md (matches overview hover)
- avatar: h-12 w-12, font-bold (djb2 palette colors kept)
- name: font-bold, group-hover:underline
- doc count: neutral bg-muted chip instead of mint pill

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Marcel
2026-05-08 18:21:24 +02:00
parent cc20583ae6
commit 2283f733cc
2 changed files with 21 additions and 15 deletions

View File

@@ -31,24 +31,28 @@ const { persons }: Props = $props();
{#if persons.length === 0}
<p class="font-sans text-sm text-ink-3">{m.dashboard_reader_no_persons()}</p>
{/if}
<div class="grid grid-cols-2 gap-1.5 sm:grid-cols-4">
<div class="grid grid-cols-2 gap-4 sm:grid-cols-4">
{#each persons as p (p.id)}
<a
href="/persons/{p.id}"
class="flex min-h-[44px] flex-col items-center gap-1.5 rounded-sm border border-line bg-surface p-2.5 text-center no-underline transition-colors hover:border-brand-mint focus-visible:ring-2 focus-visible:ring-brand-navy focus-visible:outline-none"
class="group flex min-h-[44px] flex-col items-center gap-2 rounded border border-line bg-surface px-4 py-6 text-center no-underline shadow-sm transition-all duration-200 hover:border-l-4 hover:border-accent hover:shadow-md focus-visible:ring-2 focus-visible:ring-brand-navy focus-visible:outline-none"
>
<span
class="flex h-[22px] w-[22px] shrink-0 items-center justify-center rounded-full text-[11px] font-black text-white shadow-sm sm:h-9 sm:w-9 dark:shadow-none dark:ring-1 dark:ring-white/10"
class="flex h-12 w-12 shrink-0 items-center justify-center rounded-full text-base font-bold text-white shadow-sm dark:shadow-none dark:ring-1 dark:ring-white/10"
style="background-color: {personAvatarColor(p.id ?? '')}"
>
{getInitials(p.displayName ?? p.lastName ?? '')}
</span>
<span class="truncate font-serif text-sm text-ink">{p.displayName ?? p.lastName}</span>
<span
class="rounded-full bg-mint-soft px-1.5 py-px text-[11px] font-bold text-ink dark:bg-mint-soft"
<span class="truncate font-serif text-sm font-bold text-ink group-hover:underline"
>{p.displayName ?? p.lastName}</span
>
{p.documentCount ?? 0}
</span>
{#if (p.documentCount ?? 0) > 0}
<span
class="mt-1 inline-flex items-center rounded-full border border-line bg-muted px-2.5 py-0.5 font-sans text-[11px] font-semibold text-ink-2"
>
{p.documentCount}
</span>
{/if}
</a>
{/each}
</div>

View File

@@ -51,21 +51,23 @@ describe('ReaderPersonChips', () => {
expect(cls).toMatch(/min-h-\[44px\]/);
});
it('doc count renders as mint pill with bg-mint-soft', async () => {
it('doc count renders as neutral chip with bg-muted', async () => {
render(ReaderPersonChips, { persons: [person1] });
const link = page.getByRole('link', { name: /Anna Müller/ });
const el = (await link.element()) as HTMLElement;
const pill = el.querySelector('[class*="bg-mint-soft"]');
expect(pill).not.toBeNull();
expect(pill!.textContent).toContain('23');
const chip = el.querySelector('[class*="bg-muted"]');
expect(chip).not.toBeNull();
expect(chip!.textContent).toContain('23');
});
it('doc count pill has rounded-full class', async () => {
it('doc count chip has rounded-full and border-line classes', async () => {
render(ReaderPersonChips, { persons: [person1] });
const link = page.getByRole('link', { name: /Anna Müller/ });
const el = (await link.element()) as HTMLElement;
const pill = el.querySelector('[class*="rounded-full"]');
expect(pill).not.toBeNull();
const chip = el.querySelector('[class*="bg-muted"]');
expect(chip).not.toBeNull();
expect(chip!.className).toMatch(/rounded-full/);
expect(chip!.className).toMatch(/border-line/);
});
it('person grid uses grid layout', async () => {