frontend-ui.md 6.5 KB

Frontend UI: App Shell & Routing Scaffold (RHL-019)

This document describes the frontend routing scaffold and the application shell layout for the RHL Lieferscheine app.

Scope (RHL-019):

  • Public /login route.
  • Protected application shell for all other routes.
  • Placeholder pages for branch/year/month/day routes and branch search.
  • Minimal session-awareness placeholders (no real auth guard yet).
  • Minimal tests to validate scaffold stability.

Non-goals (out of scope for RHL-019):

  • Real login form, auth guard, and session-based redirects.
  • Explorer navigation UI (years/months/days list).
  • Search UI and filters.
  • PDF viewer / file open.

1. Route Groups & URL Structure

The app uses Next.js App Router Route Groups to separate public and protected UI.

1.1 Route groups

  • Public: app/(public)

    • Routes that do not show the authenticated app shell.
    • Current route: /login
  • Protected: app/(protected)

    • Routes that render inside the AppShell.
    • RHL-019 intentionally does not enforce authentication yet.

1.2 URL map (scaffold)

URL Purpose Notes
/login Login placeholder Public layout (no AppShell)
/ Protected entry placeholder Later redirects based on session
/:branch Branch placeholder Example: /NL01
/:branch/:year Year placeholder Example: /NL01/2025
/:branch/:year/:month Month placeholder Example: /NL01/2025/12
/:branch/:year/:month/:day Day placeholder Example: /NL01/2025/12/31
/:branch/search Search placeholder Explicit segment so search is not treated as :year

Important:

  • There is no standalone /search route. Visiting /search matches /:branch with branch = "search".

2. Layouts

2.1 Root layout

File: app/layout.jsx

Responsibilities:

  • Global CSS imports (app/globals.css).
  • Theme provider setup (shadcn/ui + next-themes wrapper).
  • Base HTML/body structure.

2.2 Public layout

File: app/(public)/layout.jsx

Responsibilities:

  • Minimal centered layout for public routes.
  • Intended for /login (and potential future public routes).

2.3 Protected layout

File: app/(protected)/layout.jsx

Responsibilities:

  • Wraps all protected pages with the AppShell.
  • Intentionally contains no auth guard in RHL-019.

3. AppShell

The AppShell is the stable frame for authenticated UI.

Folder: components/app-shell/*

  • AppShell.jsx

    • Overall layout container: TopNav + content area.
    • Uses min-h-screen flex flex-col so the content area can fill remaining height.
  • TopNav.jsx

    • Branding.
    • User status placeholder.
    • Placeholder buttons for theme and logout (not wired yet).
  • SidebarPlaceholder.jsx

    • Reserved space for future navigation/filter UI.
    • Later additions:

    • Admin/dev branch selector

    • Explorer navigation (year/month/day)

    • Search filters and shortcuts

  • UserStatus.jsx

    • Placeholder only.
    • Later reads session state (via apiClient.getMe()).

3.1 Responsive behavior

  • Sidebar is hidden on small viewports (md:block).
  • Main content remains usable on mobile sizes.

4. Placeholder Pages

Placeholder pages validate:

  • URL structure
  • Layout composition
  • Dynamic route parameter handling

They render via:

  • components/placeholders/PlaceholderPage.jsx

4.1 Dynamic route params (Next.js App Router)

In this project setup, dynamic route params can behave like an async value.

Rule of thumb:

  • In dynamic routes ([branch], [year], [month], [day]), unwrap params before using properties.

5. File Naming Convention (.js vs .jsx)

To keep the project consistent and avoid test/tooling issues:

  • Use .jsx for files that contain JSX:

    • app/**/page.jsx, app/**/layout.jsx
    • React components in components/**
  • Use .js for non-JSX files:

    • lib/** utilities and helpers
    • app/api/**/route.js
    • models/**
    • tests that do not contain JSX

6. Frontend Route Helpers

File: lib/frontend/routes.js

Purpose:

  • Centralize URL building so UI code does not scatter hardcoded strings.
  • Encode dynamic segments defensively.
  • Keep navigation consistent across components.

Provided helpers:

  • homePath()/
  • loginPath()/login
  • branchPath(branch)/:branch
  • yearPath(branch, year)/:branch/:year
  • monthPath(branch, year, month)/:branch/:year/:month
  • dayPath(branch, year, month, day)/:branch/:year/:month/:day
  • searchPath(branch)/:branch/search

7. Tests

7.1 Unit tests

  • lib/frontend/routes.test.js

    • Validates URL builder behavior.
  • components/app-shell/AppShell.test.js

    • Smoke test: server-renders AppShell and asserts key text is present.
    • next/link is mocked to avoid Next runtime dependency.

7.2 Running tests

From the repo root:

npx vitest run

Optional (recommended) build check:

npm run build

8. Manual Verification Checklist

8.1 Local (Docker)

Follow Docs/runbook.md.

Typical command:

docker compose -f docker-compose.yml -f docker-compose.local.yml up -d --build

Verify routes:

  • /login (public layout)
  • / (protected app shell)
  • /:branch (e.g. /NL01)
  • /:branch/:year/:month/:day (placeholder)
  • /:branch/search

8.2 Server

Follow Docs/runbook.md.

Verify:

  • curl -s http://127.0.0.1:3000/api/health
  • Browser:

    • http(s)://<server>:3000/login
    • http(s)://<server>:3000/NL01/... (or a real branch)

9. Planned Follow-ups

  • Add real auth guard and session-based redirects (//login or /:branch).
  • Replace placeholders with Explorer pages (years/months/days + files).
  • Add Search UI and filters.
  • Add PDF open/view experience.