WEB-0b: CMS-Verwaltung der öffentlichen Webseite (Hand-Editier-UI)

Neuer Bereich /webseite im Manager (Nav: "Mehr"-Blatt) zur Pflege der 6
Webseiten-Seiten gegen Pams WEB-0-Backend (LAN-only, keine Auth):

- Übersicht: alle Seiten mit Status (Entwurf/Veröffentlicht).
- Seiten-Editor: Titel + SEO-Beschreibung + Status speichern.
- Geordneter Block-Editor: Blöcke hinzufügen (Überschrift, Textabschnitt/
  Markdown, Bild, Galerie, Kontaktangaben), bearbeiten, nach oben/unten
  verschieben (PUT .../blocks/order), löschen. Die dynamische AbgabetiereList
  ist nicht manuell anlegbar; nur ihr Einleitungstext ist editierbar.

Vertraege: GET /pages, GET /pages/{slug}, PUT /pages/{id},
POST /pages/{pageId}/blocks, PUT /blocks/{id}, DELETE /blocks/{id},
PUT /pages/{pageId}/blocks/order. Enums als Strings (Draft/Published, Heading...).

Deutsch via de.ts (LF beibehalten), mobile-first. e2e-Mock um die CMS-Routen
erweitert (zustandsbehaftet) + Smoke (Block anlegen/bearbeiten/verschieben,
bleibt erhalten). Gate gruen: build, eslint, vitest 69, e2e 68.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-06 11:22:32 +02:00
parent 36454f3747
commit c20e6b5426
11 changed files with 1056 additions and 1 deletions

View File

@@ -25,6 +25,24 @@ export interface WeightRecordRow {
notes: string | null
}
/** WEB-0b: CMS-Block (data ist das typ-spezifische JSON-Objekt). */
export interface MockBlock {
id: string
order: number
type: string
data: Record<string, unknown>
}
/** WEB-0b: CMS-Seite der öffentlichen Webseite. */
export interface MockPage {
id: string
slug: string
title: string
seoDescription: string | null
status: 'Draft' | 'Published'
blocks: MockBlock[]
}
export interface MockDb {
gerbils: Gerbil[]
litters: Litter[]
@@ -33,6 +51,7 @@ export interface MockDb {
colorVarieties: { id: string; name: string; canonicalGenotype: string | null; sortOrder: number }[]
healthRecords: HealthRecordRow[]
weightRecords: WeightRecordRow[]
pages: MockPage[]
}
function gerbil(
@@ -142,5 +161,34 @@ export function seedDb(): MockDb {
{ id: 'wr-2', gerbilId: 'kruemel', date: '2026-05-20', weightGrams: 82, notes: null },
]
return { gerbils, litters, enclosures, contacts, colorVarieties, healthRecords, weightRecords }
// WEB-0b: die 6 Webseiten-Seiten (wie vom Backend geseedet), mit ein paar Blöcken.
const pages: MockPage[] = [
{
id: 'page-start',
slug: 'start',
title: 'Startseite',
seoDescription: 'Willkommen bei unserer Rennmauszucht.',
status: 'Published',
blocks: [
{ id: 'blk-start-1', order: 0, type: 'Heading', data: { text: 'Willkommen', level: 2 } },
{ id: 'blk-start-2', order: 1, type: 'RichText', data: { markdown: 'Schön, dass du da bist.' } },
],
},
{ id: 'page-zucht', slug: 'ueber-die-zucht', title: 'Über die Zucht', seoDescription: null, status: 'Draft', blocks: [] },
{
id: 'page-abgabe',
slug: 'abgabetiere',
title: 'Abgabetiere',
seoDescription: null,
status: 'Published',
blocks: [
{ id: 'blk-abgabe-1', order: 0, type: 'AbgabetiereList', data: { mode: 'auto', intro: 'Diese Tiere suchen ein Zuhause.' } },
],
},
{ id: 'page-bedingungen', slug: 'abgabebedingungen', title: 'Abgabebedingungen', seoDescription: null, status: 'Draft', blocks: [] },
{ id: 'page-farben', slug: 'farben-genetik', title: 'Farben & Genetik', seoDescription: null, status: 'Draft', blocks: [] },
{ id: 'page-kontakt', slug: 'kontakt', title: 'Kontakt', seoDescription: null, status: 'Draft', blocks: [] },
]
return { gerbils, litters, enclosures, contacts, colorVarieties, healthRecords, weightRecords, pages }
}