diff --git a/README.md b/README.md
index 2ad8da8..6bb7233 100644
--- a/README.md
+++ b/README.md
@@ -165,7 +165,7 @@ explains what does have access instead.
| `discount-codes` | Cart discount input (`/cart`, display-only on `/checkout`) | `code`, `type` (`percent`/`fixed`), `value`, `validFrom`/`validUntil`, `minOrderValue`, `maxRedemptions`, `redemptionCount` (server-incremented only), `active`. **Not public-read** — see Discount codes section below |
| `posts` | `/blog`, `/blog/[slug]` | `title`, `slug`, `categories` (`hasMany` relation to `categories` — a post can have several, joined with `", "` wherever rendered), `excerpt`, `thumbnail`, `content` (richText, supports custom Lexical blocks — Bild/Bildergalerie/Video/Zitat — rendered via `app/components/RichText.tsx`'s `@payloadcms/richtext-lexical/react` renderer with custom `JSXConverters`), `readTime` (auto-calculated on save from word count), `featured` (shown as the `/blog` hero post; most-recently-published wins if several are marked), `publishedAt`, `quoteLabel` (label + icon + underline shown next to every blockquote in `content`, default `"Merke dir:"` — leave empty to hide that framing, the blockquote text itself still renders), `relatedProduct` (optional relation to `products`, powers the "Passend dazu" card at the end of the post — leave empty to hide that card, or empty if the linked product has no `detailHref`), `seoTitle`/`seoDescription`/`seoImage` (each falls back to `title`/`excerpt`/`thumbnail` when empty, consumed by `/blog/[slug]`'s `generateMetadata()`) |
| `categories` | Blog post categorization | `name`, `slug` (unique per tenant, not globally) |
-| `legal-pages` | `/impressum`, `/datenschutz`, `/agb`, `/widerruf` | `type` (`impressum`/`datenschutz`/`agb`/`widerruf`, one doc per type per tenant), `title`, `content` (richText), `attachment` (optional file, e.g. the Muster-Widerrufsformular PDF) |
+| `legal-pages` | `/impressum`, `/datenschutz`, `/agb`, `/widerruf` | `type` (`impressum`/`datenschutz`/`agb`/`widerruf`, one doc per type per tenant), `title`, `content` (richText), `attachment` (optional file, e.g. the Muster-Widerrufsformular PDF). Each page's "Stand: …" line is derived from this doc's own `updatedAt` (`formatMonthYear()` in `app/lib/format.ts`), not a hand-typed string — it updates automatically the moment an admin edits the content, no separate field to remember |
| `trust-badges` | Horizontal "Schneller Versand / Versandkostenfrei / Mit Liebe verpackt" row — shown on `/shop`, `/cart`, `/checkout`, `/widerruf`, `/agb`, 404 | `title`, `description` (supports `{{lieferzeit}}`/`{{kostenfreiab}}` placeholders, resolved by the frontend from `shipping-settings`/`shipping-methods` at render time — not by Payload itself), `icon`, `sortOrder` |
| `cart-trust-badges` | Sidebar bullets on `/cart` (title only) and `/checkout` (title + description) — deliberately a separate collection from `trust-badges` so the two pages can't drift into showing different claims | `title`, `description`, `icon`, `sortOrder` |
| `shipping-methods` | `/checkout` shipping selection | `title` (no day-range in the title text — that lives in `shipping-settings` now, keeping both in one title used to drift), `description`, `price`, `freeShippingThreshold` (per-method, optional — leave empty for a method that should never be free, e.g. Express), `active` (inactive methods are hidden, not shown disabled), `sortOrder` |
@@ -1269,16 +1269,29 @@ whatever page sent the visitor to log in instead of always
`orders/[orderNumber]` (PATCH — cancel/return-request, see "Order
cancellation & returns" below), and `orders/[orderNumber]/invoice`
(GET — invoice PDF download, see "Invoice PDFs" below).
+- **`app/konto/components/KontoShell.tsx`** is the shared shell for every
+ logged-in `/konto/*` page (bestellungen, merkliste, profil) —
+ `AccountNav.tsx` (persistent sidebar on `sm:`+, a horizontal tab bar
+ below it) plus the `
Stand: Juli 2026
+ {page &&Stand: {formatMonthYear(page.updatedAt)}
} {/* MobileSectionTOC — below lg: only, see SectionTOC.tsx's own diff --git a/app/blog/page.tsx b/app/blog/page.tsx index 1475650..d090b06 100644 --- a/app/blog/page.tsx +++ b/app/blog/page.tsx @@ -96,14 +96,6 @@ export default async function BlogOverviewPage({ ); })} - {activeCategories.length > 0 && ( - - Zurücksetzen - - )} )} diff --git a/app/components/CustomSelect.tsx b/app/components/CustomSelect.tsx index 482d67c..0c64da0 100644 --- a/app/components/CustomSelect.tsx +++ b/app/components/CustomSelect.tsx @@ -131,6 +131,11 @@ export function CustomSelect({ ref={listRef} role="listbox" aria-label={label} + // Without this, a mousedown on anStand: Juli 2026
+ {page &&Stand: {formatMonthYear(page.updatedAt)}
} {/* MobileSectionTOC — below lg: only, see SectionTOC.tsx's own diff --git a/app/konto/bestellungen/page.tsx b/app/konto/bestellungen/page.tsx index 45f1ce1..e0a3a7b 100644 --- a/app/konto/bestellungen/page.tsx +++ b/app/konto/bestellungen/page.tsx @@ -14,6 +14,7 @@ import { getOrderFilterEnabled } from "../../lib/payload"; import { OrderStatusBadge } from "../components/OrderStatusBadge"; import { PaymentStatusBadge } from "../components/PaymentStatusBadge"; import { KontoShell } from "../components/KontoShell"; +import { AccountIdentity } from "../components/AccountIdentity"; import { OrderFilters } from "./components/OrderFilters"; // robots: noindex — account area, same reasoning as /checkout. @@ -59,11 +60,14 @@ export default async function KontoBestellungenPage({ ]); return ( -- Meine Bestellungen -
++ Meine Bestellungen +
++ Eingeloggt als {email} (Kundennummer {customerNumber}) +
+ ); +} diff --git a/app/konto/components/KontoShell.tsx b/app/konto/components/KontoShell.tsx index 093163f..63785ea 100644 --- a/app/konto/components/KontoShell.tsx +++ b/app/konto/components/KontoShell.tsx @@ -12,28 +12,18 @@ import { AccountNav } from "./AccountNav"; // page-specific logic each page still needs (e.g. merkliste's return-URL // login redirect, profil's second profile-fetch redirect). // -// `customer` is rendered here, once, so "Eingeloggt als …" looks and -// appears identically on every /konto/* page — it used to be hand-copied -// onto individual pages (bestellungen had it, merkliste/profil didn't), -// which read as inconsistent rather than a deliberate per-page choice. -export async function KontoShell({ - children, - customer, -}: { - children: ReactNode; - customer: { email: string; customerNumber: string }; -}) { +// "Eingeloggt als …" is NOT rendered here (even though `customer` used to +// be the only prop this shell needed) — it belongs directly under each +// page's own title so it reads as "page title, then who's logged in", not +// above the title before the page has even introduced itself. See +// AccountIdentity.tsx, rendered by each page right after its own heading. +export async function KontoShell({ children }: { children: ReactNode }) { return ( <>- Eingeloggt als {customer.email} (Kundennummer {customer.customerNumber}) -
- {children} -- Meine Merkliste -
++ Meine Merkliste +
+- Mein Profil -
-- {profile.email} · Kundennummer {profile.customerNumber} -
-