feat: redesign CMS and unify German admin UI

This commit is contained in:
2026-09-17 16:51:24 +02:00
parent a2b3e99174
commit 7ec0c51ff5
129 changed files with 952 additions and 550 deletions
+6 -6
View File
@@ -8,7 +8,7 @@ import { sendEmail } from "@/lib/email/sendBookingEmails";
// Routes through the shared isAdmin check (role === "admin", not just
// collection === "users") so this stays correct if a non-admin role is ever
// added to Users — see the comment on isAdmin in access/index.ts.
// added to Users - see the comment on isAdmin in access/index.ts.
const isSelfOrAdmin: typeof isAdmin = (args) => {
const user = args.req.user;
if (!user) return false;
@@ -21,12 +21,12 @@ const isSelfOrAdmin: typeof isAdmin = (args) => {
// customer changes their email address: issues a random, single-use,
// time-limited email-verification token and resets emailVerified to false.
// Only the token's hash is ever persisted (see emailVerificationTokenHash
// below) — the plaintext exists only in req.context for the afterChange
// below) - the plaintext exists only in req.context for the afterChange
// hook below to email out, and is never written to the database or logged.
//
// The email-change case matters because `update` access on this collection
// is isSelfOrAdmin and the auto-added `email` field carries no field-level
// access of its own — without this, a customer could verify a throwaway
// access of its own - without this, a customer could verify a throwaway
// address once and then repoint `email` at an address they don't own while
// keeping emailVerified: true (which gates booking-confirmation emails).
const issueVerificationToken: CollectionBeforeChangeHook = ({ data, originalDoc, operation, req }) => {
@@ -110,7 +110,7 @@ export const Customers: CollectionConfig = {
label: "Telefonnummer",
required: false,
admin: {
description: "Optional — für eine spätere Nutzung vorbereitet, aktuell nicht verpflichtend.",
description: "Optional - für eine spätere Nutzung vorbereitet, aktuell nicht verpflichtend.",
},
},
{
@@ -118,7 +118,7 @@ export const Customers: CollectionConfig = {
type: "checkbox",
label: "E-Mail bestätigt",
defaultValue: false,
// "create" AND "update" must both be locked down — otherwise a
// "create" AND "update" must both be locked down - otherwise a
// customer could simply include emailVerified: true in their own
// registration or profile request and skip verification entirely.
access: { create: isAdminFieldLevel, update: isAdminFieldLevel },
@@ -130,7 +130,7 @@ export const Customers: CollectionConfig = {
{
name: "emailVerificationTokenHash",
type: "text",
// Never exposed or settable via any API — only the two hooks above
// Never exposed or settable via any API - only the two hooks above
// (running through the trusted Local API) ever touch this field.
access: { create: () => false, read: () => false, update: () => false },
admin: { hidden: true },