feat(geschichten): make Geschichte panel rows fully clickable
Some checks failed
CI / Unit & Component Tests (push) Failing after 4m20s
CI / OCR Service Tests (push) Successful in 49s
CI / Backend Unit Tests (push) Failing after 3m16s
CI / Unit & Component Tests (pull_request) Failing after 3m52s
CI / Backend Unit Tests (pull_request) Failing after 3m11s
CI / OCR Service Tests (pull_request) Successful in 48s

The story rows on the person detail page now match the
PersonDocumentList pattern: the entire row is a single anchor with a
hover background, and the title gets group-hover:underline. Author,
date, and body excerpt are all part of the same clickable area, so
the touch target matches the visual rhythm of the document panels
above.
This commit is contained in:
Marcel
2026-05-03 08:45:04 +02:00
parent 34ab8a0a2c
commit 4f3020ffab
2 changed files with 36 additions and 14 deletions

View File

@@ -53,22 +53,24 @@ function authorName(g: Geschichte): string {
{/if}
</header>
<ul class="flex flex-col gap-4">
<ul class="-mx-2">
{#each visible as g (g.id)}
<li class="flex flex-col gap-1 border-b border-line pb-3 last:border-0 last:pb-0">
<li>
<a
href="/geschichten/{g.id}"
class="font-serif text-base font-bold text-ink hover:underline"
class="group flex flex-col gap-1 border-b border-line px-2 py-3 transition-colors last:border-b-0 hover:bg-muted"
>
{g.title}
<span class="font-serif text-base font-bold text-ink group-hover:underline">
{g.title}
</span>
<span class="font-sans text-xs text-ink-3">
{authorName(g)}
{#if formatPublishedDate(g)}· {formatPublishedDate(g)}{/if}
</span>
{#if g.body}
<span class="font-serif text-sm text-ink-2">{plainExcerpt(g.body, 80)}</span>
{/if}
</a>
<p class="font-sans text-xs text-ink-3">
{authorName(g)}
{#if formatPublishedDate(g)}· {formatPublishedDate(g)}{/if}
</p>
{#if g.body}
<p class="font-serif text-sm text-ink-2">{plainExcerpt(g.body, 80)}</p>
{/if}
</li>
{/each}
</ul>

View File

@@ -51,9 +51,29 @@ describe('GeschichtenCard', () => {
canWrite: false
});
await expect.element(page.getByText('Geschichten')).toBeInTheDocument();
await expect
.element(page.getByRole('link', { name: 'Erinnerung an Franz' }))
.toBeInTheDocument();
// The whole row is one link to the story; matching on the title text via
// a partial regex tolerates trailing author/date metadata in the
// accessible name.
const link = await page
.getByRole('link', { name: /Erinnerung an Franz/ })
.first()
.element();
expect(link.getAttribute('href')).toBe('/geschichten/g1');
});
it('makes the entire story row a single clickable link', async () => {
render(GeschichtenCard, {
geschichten: [makeStory('g1', 'A title', '<p>Some body excerpt text</p>')],
personId: 'p1',
personName: 'Franz',
canWrite: false
});
// The body-excerpt text is inside the same <a> as the title.
const links = await page.getByRole('link', { name: /A title/ }).all();
expect(links.length).toBeGreaterThan(0);
const linkEl = await links[0].element();
expect(linkEl.tagName).toBe('A');
expect(linkEl.textContent).toContain('Some body excerpt text');
});
it('hides the "+ Geschichte schreiben" link when canWrite is false', async () => {