+
+
+
+ {m.dashboard_reader_drafts_heading()}
+
+
+
{#if drafts.length === 0}
-
{m.dashboard_reader_drafts_empty()}
+
{m.dashboard_reader_drafts_empty()}
{:else}
-
+
{#each drafts as draft (draft.id)}
-
- {draft.title}
-
- {relativeTimeDe(new Date(draft.updatedAt))}
+
+ {draft.title}
+
+ {m.dashboard_reader_draft_meta({ relative: relativeTimeDe(new Date(draft.updatedAt)) })}
+
+
{/each}
diff --git a/frontend/src/lib/shared/dashboard/ReaderDraftsModule.svelte.spec.ts b/frontend/src/lib/shared/dashboard/ReaderDraftsModule.svelte.spec.ts
index 9d4beab8..44a8e43a 100644
--- a/frontend/src/lib/shared/dashboard/ReaderDraftsModule.svelte.spec.ts
+++ b/frontend/src/lib/shared/dashboard/ReaderDraftsModule.svelte.spec.ts
@@ -36,10 +36,12 @@ describe('ReaderDraftsModule', () => {
await expect.element(link2).toHaveAttribute('href', '/geschichten/g2/edit');
});
- it('shows heading "Meine Entwürfe"', async () => {
+ it('shows heading as h3 (not h2)', async () => {
render(ReaderDraftsModule, { drafts: [draft1] });
- const heading = page.getByRole('heading', { name: /Meine Entwürfe/i });
- await expect.element(heading).toBeInTheDocument();
+ const h3 = page.getByRole('heading', { level: 3 });
+ await expect.element(h3).toBeInTheDocument();
+ const h2 = page.getByRole('heading', { level: 2 });
+ await expect.element(h2).not.toBeInTheDocument();
});
it('shows empty state when drafts is empty', async () => {
@@ -53,4 +55,45 @@ describe('ReaderDraftsModule', () => {
const emptyText = page.getByText(/Keine Entwürfe/i);
await expect.element(emptyText).not.toBeInTheDocument();
});
+
+ it('card wrapper has mint left-border classes', async () => {
+ render(ReaderDraftsModule, { drafts: [draft1] });
+ const h3 = page.getByRole('heading', { level: 3 });
+ const card = ((await h3.element()) as HTMLElement).closest('div[class]');
+ const rootCard = card?.parentElement;
+ const cls = rootCard?.className ?? '';
+ expect(cls).toMatch(/border-l-\[3px\]/);
+ expect(cls).toMatch(/border-l-brand-mint/);
+ });
+
+ it('draft-row link has min-h-[44px] touch target', async () => {
+ render(ReaderDraftsModule, { drafts: [draft1] });
+ const link = page.getByRole('link', { name: /Mein erster Entwurf/ });
+ const cls = ((await link.element()) as HTMLElement).className;
+ expect(cls).toMatch(/min-h-\[44px\]/);
+ });
+
+ it('draft title has text-brand-navy class', async () => {
+ render(ReaderDraftsModule, { drafts: [draft1] });
+ const link = page.getByRole('link', { name: /Mein erster Entwurf/ });
+ const el = (await link.element()) as HTMLElement;
+ const titleEl = el.querySelector('[class*="text-brand-navy"]');
+ expect(titleEl).not.toBeNull();
+ expect(titleEl?.textContent?.trim()).toBe('Mein erster Entwurf');
+ });
+
+ it('draft meta contains "Entwurf" text', async () => {
+ render(ReaderDraftsModule, { drafts: [draft1] });
+ const link = page.getByRole('link', { name: /Mein erster Entwurf/ });
+ const el = (await link.element()) as HTMLElement;
+ expect(el.textContent).toMatch(/Entwurf/);
+ });
+
+ it('chevron SVG is present in each draft row', async () => {
+ render(ReaderDraftsModule, { drafts: [draft1] });
+ const link = page.getByRole('link', { name: /Mein erster Entwurf/ });
+ const el = (await link.element()) as HTMLElement;
+ const svg = el.querySelector('svg');
+ expect(svg).not.toBeNull();
+ });
});