|
|
@@ -1,4 +1,4 @@
|
|
|
-# Frontend UI: App Shell, Routing, Auth/RBAC, Explorer, Search, Date Range Filter, Recent Search History, Navigation Polish, Profile Password Change, User Management, Role Refinement, Must-Change-Password Gate, and User Management UX Hardening (RHL-019 / RHL-020 / RHL-021 / RHL-022 / RHL-023 / RHL-024 / RHL-025 / RHL-037 / RHL-032 / RHL-009 / RHL-012 / RHL-041 / RHL-044 / RHL-042 / RHL-043)
|
|
|
+# Frontend UI: App Shell, Routing, Auth/RBAC, Overview Launcher, Explorer, Search, Date Range Filter, Recent Search History, Navigation Polish, Profile Password Change, User Management, Role Refinement, Must-Change-Password Gate, and User Management UX Hardening (RHL-019 / RHL-020 / RHL-021 / RHL-022 / RHL-023 / RHL-024 / RHL-025 / RHL-037 / RHL-032 / RHL-009 / RHL-012 / RHL-041 / RHL-044 / RHL-042 / RHL-043 / RHL-046)
|
|
|
|
|
|
This document describes the **frontend routing scaffold**, the **application shell layout**, and the core UI modules for the RHL Lieferscheine app.
|
|
|
|
|
|
@@ -25,6 +25,7 @@ Timeline:
|
|
|
- temporary-password controls (reset/show/copy + tooltips) in table and edit dialog,
|
|
|
- sticky icon-only action column polish,
|
|
|
- AppShell cleanup (remove sidebar placeholder, desktop width to `75%`).
|
|
|
+- **RHL-046**: Overview home cards (`/`) + role-based launcher card + shared profile support card + image loading performance update (`/overview-cards/v2` WebP, eager loading for above-the-fold cards, long-lived immutable cache headers).
|
|
|
|
|
|
> **Language policy**
|
|
|
>
|
|
|
@@ -36,7 +37,7 @@ Timeline:
|
|
|
|
|
|
## 1. Scope
|
|
|
|
|
|
-### 1.1 Implemented (as of RHL-012 + RHL-041 + RHL-037 + RHL-025 + RHL-042 + RHL-032 + RHL-009 + RHL-044 + RHL-043)
|
|
|
+### 1.1 Implemented (as of RHL-012 + RHL-041 + RHL-037 + RHL-025 + RHL-042 + RHL-032 + RHL-009 + RHL-044 + RHL-043 + RHL-046)
|
|
|
|
|
|
- **Public** `/login` route with a functional login form (shadcn/ui primitives).
|
|
|
|
|
|
@@ -50,6 +51,23 @@ Timeline:
|
|
|
- mobile/tablet: full width
|
|
|
- desktop (`lg+`): centered `w-3/4` content for a wider but bounded workspace
|
|
|
|
|
|
+- **Protected overview launcher page** (`/`, RHL-046):
|
|
|
+ - Replaces the old placeholder entry page.
|
|
|
+ - Keeps the page header `Übersicht`.
|
|
|
+ - Renders launcher cards:
|
|
|
+ - always: `Explorer`, `Suche`, `Profil`
|
|
|
+ - only for `canManageUsers(role)`: `Benutzerverwaltung`
|
|
|
+ - Card targets:
|
|
|
+ - Explorer -> `/:branch`
|
|
|
+ - Suche -> `/:branch/search`
|
|
|
+ - Profil -> `/profile`
|
|
|
+ - Benutzerverwaltung -> `/admin/users`
|
|
|
+ - Branch target resolution uses the dedicated overview logic:
|
|
|
+ - branch role: own `user.branchId`
|
|
|
+ - admin-like: route context / last branch (`rhl_last_branch`) / fallback chain
|
|
|
+ - Fail-safe behavior:
|
|
|
+ - if no valid branch target can be determined, branch-dependent cards are shown disabled with a German hint.
|
|
|
+
|
|
|
- **Session guard** for protected routes:
|
|
|
- Session identity is checked via `GET /api/auth/me`.
|
|
|
- When unauthenticated: redirect to `/login?reason=expired&next=<original-url>`.
|
|
|
@@ -70,6 +88,7 @@ Timeline:
|
|
|
- Password change form calls `apiClient.changePassword({ currentPassword, newPassword })`.
|
|
|
- Uses inline validation for actionable form errors.
|
|
|
- Uses toast notifications (Sonner) for success/error feedback.
|
|
|
+ - Profile includes an additional support card with a direct `mailto:` support action (RHL-046 follow-up).
|
|
|
|
|
|
- **Must-change-password enforcement (RHL-044)**:
|
|
|
- Session identity (`GET /api/auth/me`) includes `mustChangePassword`.
|
|
|
@@ -193,6 +212,16 @@ Timeline:
|
|
|
|
|
|
- The “Benutzerverwaltung” entry is only shown when the user has the user-management capability.
|
|
|
|
|
|
+- **Overview image performance update (RHL-046 follow-up)**:
|
|
|
+ - Overview card assets are served from versioned static files:
|
|
|
+ - `/overview-cards/v2/explorer.webp`
|
|
|
+ - `/overview-cards/v2/search.webp`
|
|
|
+ - `/overview-cards/v2/profile.webp`
|
|
|
+ - `/overview-cards/v2/users.webp`
|
|
|
+ - Above-the-fold overview cards use eager image loading.
|
|
|
+ - Static asset caching for `/overview-cards/v2/*` is explicitly configured as:
|
|
|
+ - `Cache-Control: public, max-age=31536000, immutable`
|
|
|
+
|
|
|
---
|
|
|
|
|
|
### 1.2 Still out of scope / planned
|
|
|
@@ -238,8 +267,8 @@ The app uses Next.js App Router **Route Groups** to separate public and protecte
|
|
|
| URL | Purpose | Notes |
|
|
|
| ---------------------------- | --------------------------- | ---------------------------------------------------------- |
|
|
|
| `/login` | Login page | Supports `reason` and `next` query params |
|
|
|
-| `/` | Protected entry placeholder | Rendered only when authenticated |
|
|
|
-| `/profile` | Profile | Password change is implemented here (RHL-009) |
|
|
|
+| `/` | Overview launcher | Protected landing page with role-based cards (RHL-046) |
|
|
|
+| `/profile` | Profile | Password change + support card (RHL-009 / RHL-046) |
|
|
|
| `/admin/users` | Benutzerverwaltung | Only `superadmin`/`dev` (RHL-012) |
|
|
|
| `/:branch` | Explorer: years | Example: `/NL01` |
|
|
|
| `/:branch/:year` | Explorer: months | Example: `/NL01/2025` |
|
|
|
@@ -252,6 +281,24 @@ Important:
|
|
|
|
|
|
- There is **no** standalone `/search` route. Visiting `/search` matches `/:branch` with `branch = "search"`.
|
|
|
|
|
|
+### 2.3 Protected entry page (`/`) overview implementation (RHL-046)
|
|
|
+
|
|
|
+Primary files:
|
|
|
+
|
|
|
+- `app/(protected)/page.jsx`
|
|
|
+- `components/overview/OverviewHomePage.jsx`
|
|
|
+- `components/overview/OverviewCard.jsx`
|
|
|
+- `components/overview/layoutClasses.js`
|
|
|
+- `lib/frontend/overview/useOverviewBranchTarget.js`
|
|
|
+- `lib/frontend/overview/homeBranchTarget.js`
|
|
|
+- `lib/frontend/overview/cardsConfig.js`
|
|
|
+
|
|
|
+Behavior summary:
|
|
|
+
|
|
|
+- `OverviewHomePage` builds card data and renders card UI with role-based visibility.
|
|
|
+- Branch target resolution for Explorer/Search is encapsulated in the overview branch hook/helper flow.
|
|
|
+- Card content (title/description/image/target) is built through `buildOverviewCards(...)`.
|
|
|
+
|
|
|
---
|
|
|
|
|
|
## 3. Layouts
|
|
|
@@ -377,6 +424,10 @@ Policy:
|
|
|
|
|
|
File: `components/app-shell/UserStatus.jsx`
|
|
|
|
|
|
+Shared support mailto builder:
|
|
|
+
|
|
|
+- `lib/frontend/support/supportMailto.js`
|
|
|
+
|
|
|
Menu items (German):
|
|
|
|
|
|
- **Profil** → `/profile` (account info + password change)
|
|
|
@@ -833,12 +884,17 @@ The UI uses the API client wrappers from `lib/frontend/apiClient.js`:
|
|
|
- Shows read-only account/session info (role, branch, email).
|
|
|
- Shows required-action alert when `mustChangePassword=true`.
|
|
|
- Shows success alert after a successful forced password change.
|
|
|
+ - Includes a support card with `Support kontaktieren` action (RHL-046 follow-up).
|
|
|
|
|
|
- `components/profile/ChangePasswordCard.jsx`
|
|
|
- Calls `apiClient.changePassword({ currentPassword, newPassword })`.
|
|
|
- Maps password policy errors into user-friendly German hints.
|
|
|
- Triggers auth revalidation after success (`retry()` from AuthContext).
|
|
|
|
|
|
+- `lib/frontend/support/supportMailto.js`
|
|
|
+ - Centralized builder for support `mailto:` links.
|
|
|
+ - Shared by TopNav user menu and profile support card to keep subject/body/context consistent.
|
|
|
+
|
|
|
---
|
|
|
|
|
|
## 13. UI primitives (shadcn/ui)
|
|
|
@@ -864,6 +920,12 @@ Role helper tests (RHL-041):
|
|
|
|
|
|
- `lib/frontend/auth/roles.test.js`
|
|
|
|
|
|
+Overview + support utility tests (RHL-046):
|
|
|
+
|
|
|
+- `lib/frontend/overview/homeBranchTarget.test.js`
|
|
|
+- `lib/frontend/overview/cardsConfig.test.js`
|
|
|
+- `lib/frontend/support/supportMailto.test.js`
|
|
|
+
|
|
|
Existing tests remain as documented in the project.
|
|
|
|
|
|
### 15.2 Running tests
|
|
|
@@ -887,6 +949,10 @@ npm run build
|
|
|
### 16.1 Local (Docker)
|
|
|
|
|
|
- Login and verify TopNav role label per account.
|
|
|
+- Verify overview launcher (`/`):
|
|
|
+ - branch/admin users see 3 cards (`Explorer`, `Suche`, `Profil`)
|
|
|
+ - `dev/superadmin` see the additional `Benutzerverwaltung` card
|
|
|
+ - Explorer/Search routes resolve to the expected branch target
|
|
|
- Branch switching for admin-like users.
|
|
|
- Explorer drill-down.
|
|
|
- Search scopes (admin-like) + Search restrictions (branch).
|
|
|
@@ -896,6 +962,12 @@ npm run build
|
|
|
- restore recent entries across same and different branches
|
|
|
- clear history via `Verlauf löschen`
|
|
|
- Open PDFs.
|
|
|
+- Verify profile support card:
|
|
|
+ - support card is visible below password section
|
|
|
+ - `Support kontaktieren` opens a prefilled support `mailto:` link
|
|
|
+- Verify overview image performance:
|
|
|
+ - assets are loaded from `/overview-cards/v2/*.webp`
|
|
|
+ - response headers include `Cache-Control: public, max-age=31536000, immutable`
|
|
|
- User management UI (superadmin/dev):
|
|
|
- list/create/update/delete
|
|
|
- delete typed confirmation
|
|
|
@@ -907,6 +979,7 @@ npm run build
|
|
|
### 16.2 Server
|
|
|
|
|
|
- Repeat the local checks on the real server.
|
|
|
+- Specifically verify overview card image caching and second-load cache hits in browser DevTools.
|
|
|
- Validate RBAC behavior:
|
|
|
- branch user → forbidden on foreign branches
|
|
|
- admin-like → notfound on non-existent branches
|
|
|
@@ -923,3 +996,5 @@ npm run build
|
|
|
- Optional user-management polish:
|
|
|
- additional branch-list filtering in the create/edit branch picker UX
|
|
|
- optional one-click username copy helper
|
|
|
+- Optional overview perceived-performance polish:
|
|
|
+ - add a lightweight image-area skeleton only if real-world perception still feels delayed after asset/caching optimization.
|