feat(onboarding): A2 — Household setup page #34
42
frontend/src/routes/household/setup/+page.svelte
Normal file
42
frontend/src/routes/household/setup/+page.svelte
Normal file
@@ -0,0 +1,42 @@
|
||||
<script lang="ts">
|
||||
import ProgressSidebar from '$lib/components/ProgressSidebar.svelte';
|
||||
import HouseholdSetupForm from '$lib/onboarding/HouseholdSetupForm.svelte';
|
||||
|
||||
type FormResult = {
|
||||
errors?: Record<string, string>;
|
||||
name?: string;
|
||||
} | null;
|
||||
|
||||
let { form = null }: { form?: FormResult } = $props();
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>Haushalt einrichten — Mealplan</title>
|
||||
</svelte:head>
|
||||
|
||||
<div class="flex min-h-screen bg-[var(--color-page)]">
|
||||
<!-- Desktop progress sidebar — hidden on mobile -->
|
||||
<aside
|
||||
class="hidden md:flex w-[300px] flex-shrink-0 flex-col bg-[var(--color-surface)] border-r border-[var(--color-border)] p-[40px_28px]"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<ProgressSidebar currentStep={1} />
|
||||
</aside>
|
||||
|
||||
<!-- Form area -->
|
||||
<main class="flex flex-1 flex-col justify-center">
|
||||
<!-- Mobile: step indicator (visible only on mobile) -->
|
||||
<div class="md:hidden px-[20px] pt-[24px] pb-[0]">
|
||||
<p class="text-[10px] font-medium tracking-[.08em] uppercase text-[var(--color-text-muted)]">
|
||||
Schritt 1 von 3
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- Form -->
|
||||
<div class="px-[20px] py-[24px] md:px-[56px] md:py-[48px]">
|
||||
<div class="max-w-[420px]">
|
||||
<HouseholdSetupForm {form} />
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
53
frontend/src/routes/household/setup/page.test.ts
Normal file
53
frontend/src/routes/household/setup/page.test.ts
Normal file
@@ -0,0 +1,53 @@
|
||||
import { describe, it, expect, vi } from 'vitest';
|
||||
import { render, screen } from '@testing-library/svelte';
|
||||
import Page from './+page.svelte';
|
||||
|
||||
vi.mock('$app/forms', () => ({
|
||||
enhance: () => ({ destroy: () => {} })
|
||||
}));
|
||||
|
||||
describe('household setup page', () => {
|
||||
it('renders the form heading', () => {
|
||||
render(Page);
|
||||
expect(screen.getByText('Haushalt benennen')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('renders the household name input', () => {
|
||||
render(Page);
|
||||
expect(screen.getByLabelText('Haushaltsname')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('renders the continue button', () => {
|
||||
render(Page);
|
||||
expect(screen.getByRole('button', { name: /weiter/i })).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('renders the ProgressSidebar with step 1 active', () => {
|
||||
render(Page);
|
||||
const step1 = screen.getByTestId('step-1');
|
||||
expect(step1).toHaveAttribute('aria-current', 'step');
|
||||
});
|
||||
|
||||
it('renders steps 2 and 3 as future steps', () => {
|
||||
render(Page);
|
||||
expect(screen.getByTestId('step-2')).not.toHaveAttribute('aria-current');
|
||||
expect(screen.getByTestId('step-3')).not.toHaveAttribute('aria-current');
|
||||
});
|
||||
|
||||
it('does not render app navigation chrome', () => {
|
||||
render(Page);
|
||||
// No nav links like Planer or Rezepte (those are app shell nav items)
|
||||
expect(screen.queryByText('Planer')).not.toBeInTheDocument();
|
||||
expect(screen.queryByText('Rezepte')).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('sets the page title', () => {
|
||||
render(Page);
|
||||
expect(document.title).toBe('Haushalt einrichten — Mealplan');
|
||||
});
|
||||
|
||||
it('renders the mobile step indicator text', () => {
|
||||
render(Page);
|
||||
expect(screen.getByText(/schritt 1 von 3/i)).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
7
frontend/src/routes/household/staples/+page.svelte
Normal file
7
frontend/src/routes/household/staples/+page.svelte
Normal file
@@ -0,0 +1,7 @@
|
||||
<svelte:head>
|
||||
<title>Vorräte einrichten — Mealplan</title>
|
||||
</svelte:head>
|
||||
|
||||
<div class="flex min-h-screen items-center justify-center bg-[var(--color-page)]">
|
||||
<p class="text-[var(--color-text-muted)]">A3 — Vorräte einrichten (coming soon)</p>
|
||||
</div>
|
||||
7
frontend/src/test-setup.ts
Normal file
7
frontend/src/test-setup.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
import '@testing-library/jest-dom/vitest';
|
||||
import { configure } from '@testing-library/dom';
|
||||
|
||||
// Exclude elements inside aria-hidden containers from text queries,
|
||||
// so that visually-hidden sidebars (e.g. ProgressSidebar in onboarding pages)
|
||||
// don't create duplicate text matches when the same text appears in the main content.
|
||||
configure({ defaultIgnore: 'script, style, [aria-hidden="true"] *' });
|
||||
Reference in New Issue
Block a user