diff --git a/frontend/messages/de.json b/frontend/messages/de.json index 928460c3..99c9c1b7 100644 --- a/frontend/messages/de.json +++ b/frontend/messages/de.json @@ -1159,5 +1159,20 @@ "themen_alle": "Alle Themen", "themen_leer": "Noch keine Themen vergeben.", "themen_weitere": "+ {count} weitere", - "themen_dokumente": "{count} Dokumente" + "themen_dokumente": "{count} Dokumente", + "journey_badge_list": "REISE", + "journey_badge_detail": "LESEREISE", + "journey_selector_question": "Was möchtest du erstellen?", + "journey_selector_story_title": "Geschichte", + "journey_selector_story_desc": "Eine erzählte Geschichte mit Bildern und Text.", + "journey_selector_journey_title": "Lesereise", + "journey_selector_journey_desc": "Eine kuratierte Auswahl von Briefen mit Notizen.", + "journey_selector_next_btn": "Weiter", + "journey_placeholder_back": "andere Auswahl", + "journey_placeholder_heading": "Lesereise-Editor folgt in #753", + "journey_item_open_aria": "Brief vom {date} öffnen", + "journey_item_open_aria_undated": "Brief öffnen", + "journey_empty_state": "Diese Lesereise ist noch leer.", + "journey_interlude_aria_label": "Kuratorennotiz", + "journey_selector_aria_live_hint": "Bitte wähle einen Typ aus, um fortzufahren." } diff --git a/frontend/messages/en.json b/frontend/messages/en.json index e10ef624..0c4686a4 100644 --- a/frontend/messages/en.json +++ b/frontend/messages/en.json @@ -1159,5 +1159,20 @@ "themen_alle": "All Topics", "themen_leer": "No topics assigned yet.", "themen_weitere": "+ {count} more", - "themen_dokumente": "{count} documents" + "themen_dokumente": "{count} documents", + "journey_badge_list": "JOURNEY", + "journey_badge_detail": "READING JOURNEY", + "journey_selector_question": "What would you like to create?", + "journey_selector_story_title": "Story", + "journey_selector_story_desc": "A narrative story with images and text.", + "journey_selector_journey_title": "Reading Journey", + "journey_selector_journey_desc": "A curated selection of letters with notes.", + "journey_selector_next_btn": "Continue", + "journey_placeholder_back": "different selection", + "journey_placeholder_heading": "Reading Journey editor coming in #753", + "journey_item_open_aria": "Open letter from {date}", + "journey_item_open_aria_undated": "Open letter", + "journey_empty_state": "This reading journey is still empty.", + "journey_interlude_aria_label": "Curator's note", + "journey_selector_aria_live_hint": "Please select a type to continue." } diff --git a/frontend/messages/es.json b/frontend/messages/es.json index 6a8d9eb3..3c8a361e 100644 --- a/frontend/messages/es.json +++ b/frontend/messages/es.json @@ -1159,5 +1159,20 @@ "themen_alle": "Todos los temas", "themen_leer": "Aún no hay temas.", "themen_weitere": "+ {count} más", - "themen_dokumente": "{count} documentos" + "themen_dokumente": "{count} documentos", + "journey_badge_list": "VIAJE", + "journey_badge_detail": "VIAJE DE LECTURA", + "journey_selector_question": "¿Qué deseas crear?", + "journey_selector_story_title": "Historia", + "journey_selector_story_desc": "Una historia narrada con imágenes y texto.", + "journey_selector_journey_title": "Viaje de lectura", + "journey_selector_journey_desc": "Una selección curada de cartas con notas.", + "journey_selector_next_btn": "Continuar", + "journey_placeholder_back": "otra selección", + "journey_placeholder_heading": "Editor de viaje de lectura próximamente en #753", + "journey_item_open_aria": "Abrir carta del {date}", + "journey_item_open_aria_undated": "Abrir carta", + "journey_empty_state": "Este viaje de lectura está vacío.", + "journey_interlude_aria_label": "Nota del curador", + "journey_selector_aria_live_hint": "Por favor, selecciona un tipo para continuar." } diff --git a/frontend/src/lib/geschichte/GeschichteListRow.svelte b/frontend/src/lib/geschichte/GeschichteListRow.svelte new file mode 100644 index 00000000..af2ac038 --- /dev/null +++ b/frontend/src/lib/geschichte/GeschichteListRow.svelte @@ -0,0 +1,49 @@ + + + +
+

{geschichte.title}

+ {#if isJourney} + + {m.journey_badge_list()} + + {/if} +
+

+ {authorName} + {#if publishedAt}· {m.geschichten_published_on({ date: publishedAt })}{/if} +

+ {#if geschichte.body} + +

{plainExcerpt(geschichte.body, 150)}

+ {/if} +
diff --git a/frontend/src/lib/geschichte/GeschichteListRow.svelte.spec.ts b/frontend/src/lib/geschichte/GeschichteListRow.svelte.spec.ts new file mode 100644 index 00000000..97e39175 --- /dev/null +++ b/frontend/src/lib/geschichte/GeschichteListRow.svelte.spec.ts @@ -0,0 +1,63 @@ +import { describe, it, expect, afterEach } from 'vitest'; +import { cleanup, render } from 'vitest-browser-svelte'; +import { page } from 'vitest/browser'; + +const { default: GeschichteListRow } = await import('./GeschichteListRow.svelte'); + +afterEach(cleanup); + +const baseRow = (overrides = {}) => ({ + id: 'g1', + title: 'Die Reise nach Berlin', + body: '

Im Jahr 1923...

', + type: 'STORY' as 'STORY' | 'JOURNEY', + status: 'PUBLISHED' as 'PUBLISHED' | 'DRAFT', + author: { firstName: 'Anna', lastName: 'Schmidt', email: 'a@x' }, + publishedAt: '2026-04-15T10:00:00Z', + ...overrides +}); + +describe('GeschichteListRow', () => { + it('renders the title', async () => { + render(GeschichteListRow, { props: { geschichte: baseRow() } }); + await expect + .element(page.getByRole('heading', { level: 2 })) + .toHaveTextContent('Die Reise nach Berlin'); + }); + + it('shows no badge for STORY type', async () => { + render(GeschichteListRow, { props: { geschichte: baseRow({ type: 'STORY' }) } }); + expect(document.querySelector('[data-testid="journey-badge"]')).toBeNull(); + }); + + it('shows no badge when type is undefined', async () => { + render(GeschichteListRow, { + props: { geschichte: baseRow({ type: undefined as unknown as 'STORY' | 'JOURNEY' }) } + }); + expect(document.querySelector('[data-testid="journey-badge"]')).toBeNull(); + }); + + it('shows REISE badge for JOURNEY type', async () => { + render(GeschichteListRow, { props: { geschichte: baseRow({ type: 'JOURNEY' }) } }); + const badge = document.querySelector('[data-testid="journey-badge"]'); + expect(badge).not.toBeNull(); + expect(badge?.textContent?.trim()).toBe('REISE'); + }); + + it('badge is a plain , not a nested interactive element', async () => { + render(GeschichteListRow, { props: { geschichte: baseRow({ type: 'JOURNEY' }) } }); + const badge = document.querySelector('[data-testid="journey-badge"]'); + expect(badge?.tagName.toLowerCase()).toBe('span'); + }); + + it('badge has text-xs class for WCAG readability', async () => { + render(GeschichteListRow, { props: { geschichte: baseRow({ type: 'JOURNEY' }) } }); + const badge = document.querySelector('[data-testid="journey-badge"]'); + expect(badge?.className).toContain('text-xs'); + }); + + it('renders author name in meta line', async () => { + render(GeschichteListRow, { props: { geschichte: baseRow() } }); + expect(document.body.textContent).toContain('Anna Schmidt'); + }); +});