From bf6c5d079a7f5d2466c42c386ef8c01d5bcb023c Mon Sep 17 00:00:00 2001 From: Marco Date: Fri, 31 Jul 2026 22:29:36 +0000 Subject: [PATCH] Fix order-filter dropdowns, restructure Konto identity line, drop blog reset link MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - CustomSelect.tsx: mousedown on an option blurred the trigger button before the click landed, unmounting the list before anything could be selected — add preventDefault on the list's mousedown to stop that. - KontoShell no longer renders "Eingeloggt als ..." above each page's content; each page renders its own title then AccountIdentity right below it, and ProfileForm's now-duplicate email/Kundennummer line is removed. - Blog category filter: drop the separate "Zurücksetzen" link — clicking an active category badge again already deactivates it. - Werkzeuge cards: more vertical gap between stacked cards below sm:. - Legal pages' "Stand: ..." line is now derived from the LegalPages doc's own updatedAt instead of a hand-typed string. Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_018unaXmuzVA8ct1b6WoyP1U --- README.md | 23 +++++++++++++++----- app/agb/page.tsx | 3 ++- app/blog/page.tsx | 8 ------- app/components/CustomSelect.tsx | 5 +++++ app/components/Tools.tsx | 2 +- app/datenschutz/page.tsx | 3 ++- app/konto/bestellungen/page.tsx | 12 +++++++---- app/konto/components/AccountIdentity.tsx | 7 ++++++ app/konto/components/KontoShell.tsx | 24 ++++++--------------- app/konto/merkliste/page.tsx | 12 +++++++---- app/konto/profil/components/ProfileForm.tsx | 7 ------ app/konto/profil/page.tsx | 9 +++++++- app/lib/format.ts | 9 ++++++++ app/lib/payload.ts | 3 +++ app/widerruf/page.tsx | 3 ++- 15 files changed, 80 insertions(+), 50 deletions(-) create mode 100644 app/konto/components/AccountIdentity.tsx 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 `
`/`