From 7a1fd81d2383ed72b7fb1ceb579abe447fb558c2 Mon Sep 17 00:00:00 2001 From: mAi Date: Wed, 20 May 2026 15:22:52 +0200 Subject: [PATCH] =?UTF-8?q?feat(checklists):=20t-paliad-225=20Slice=20A=20?= =?UTF-8?q?frontend=20=E2=80=94=20Meine=20Vorlagen=20+=20authoring=20wizar?= =?UTF-8?q?d?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit m/paliad#61 Slice A frontend pass. Pages: - /checklists gets a third tab "Meine Vorlagen" between Vorlagen and Vorhandene Instanzen — lists owned authored templates with regime badge, visibility chip, Bearbeiten / Löschen actions, "Neue Vorlage" CTA. Tab state round-trips via ?tab=mine. - /checklists/new and /checklists/{slug}/edit serve a shared bundle (checklists-author.html). Client reads location.pathname to decide create vs edit mode; edit mode prefills from /api/checklists/templates/mine. Wizard: - Metadata form (title, description, regime UPC/DE/EPA/OTHER, court, reference, deadline, language de/en, visibility private/firm). - Repeating section + item editor — add/remove sections, add/remove items per section, label + optional note + optional rule per item. - Single-language authoring (lang column on paliad.checklists). The catalog read layer mirrors the title/description onto both DE and EN sides so the existing bilingual frontend renders without a special case for authored entries. - Save POSTs (create) or PATCHes (edit) the template; visibility flip on edit goes through its own endpoint so the audit row captures the transition. Merged catalog: - /api/checklists now returns the merged list (static + DB visible); the Summary shape gained origin / visibility / owner_email / owner_display_name fields. i18n: 55 new keys per language (110 total) under checklisten.tab.mine.*, checklisten.mine.*, checklisten.author.*, checklisten.detail.* (Bearbeiten/Löschen labels for Slice B). i18n codegen total: 2621 keys. Build hygiene: bun run build clean, go build clean, go vet clean, go test ./internal/... + ./cmd/server/ all green. --- frontend/build.ts | 3 + frontend/src/checklists-author.tsx | 120 ++++++++ frontend/src/checklists.tsx | 13 + frontend/src/client/checklists-author.ts | 365 +++++++++++++++++++++++ frontend/src/client/checklists.ts | 99 +++++- frontend/src/client/i18n.ts | 104 +++++++ frontend/src/i18n-keys.ts | 52 ++++ 7 files changed, 753 insertions(+), 3 deletions(-) create mode 100644 frontend/src/checklists-author.tsx create mode 100644 frontend/src/client/checklists-author.ts diff --git a/frontend/build.ts b/frontend/build.ts index 5886621..2a10ec3 100644 --- a/frontend/build.ts +++ b/frontend/build.ts @@ -10,6 +10,7 @@ import { renderLinks } from "./src/links"; import { renderGlossary } from "./src/glossary"; import { renderGebuehrentabellen } from "./src/gebuehrentabellen"; import { renderChecklists } from "./src/checklists"; +import { renderChecklistsAuthor } from "./src/checklists-author"; import { renderChecklistsDetail } from "./src/checklists-detail"; import { renderChecklistsInstance } from "./src/checklists-instance"; import { renderCourts } from "./src/courts"; @@ -243,6 +244,7 @@ async function build() { join(import.meta.dir, "src/client/glossary.ts"), join(import.meta.dir, "src/client/gebuehrentabellen.ts"), join(import.meta.dir, "src/client/checklists.ts"), + join(import.meta.dir, "src/client/checklists-author.ts"), join(import.meta.dir, "src/client/checklists-detail.ts"), join(import.meta.dir, "src/client/checklists-instance.ts"), join(import.meta.dir, "src/client/courts.ts"), @@ -366,6 +368,7 @@ async function build() { await Bun.write(join(DIST, "glossary.html"), renderGlossary()); await Bun.write(join(DIST, "gebuehrentabellen.html"), renderGebuehrentabellen()); await Bun.write(join(DIST, "checklists.html"), renderChecklists()); + await Bun.write(join(DIST, "checklists-author.html"), renderChecklistsAuthor()); await Bun.write(join(DIST, "checklists-detail.html"), renderChecklistsDetail()); await Bun.write(join(DIST, "checklists-instance.html"), renderChecklistsInstance()); await Bun.write(join(DIST, "courts.html"), renderCourts()); diff --git a/frontend/src/checklists-author.tsx b/frontend/src/checklists-author.tsx new file mode 100644 index 0000000..64de67e --- /dev/null +++ b/frontend/src/checklists-author.tsx @@ -0,0 +1,120 @@ +import { h } from "./jsx"; +import { Sidebar } from "./components/Sidebar"; +import { PaliadinWidget } from "./components/PaliadinWidget"; +import { BottomNav } from "./components/BottomNav"; +import { Footer } from "./components/Footer"; +import { PWAHead } from "./components/PWAHead"; + +// Authoring wizard for paliad.checklists. Both /checklists/new and +// /checklists/{slug}/edit serve this same bundle; the client reads +// window.location.pathname to decide create vs edit mode. +export function renderChecklistsAuthor(): string { + return "" + ( + + + + + + + + + Vorlage erstellen — Paliad + + + + + + +
+
+
+
+

Neue Checklisten-Vorlage

+

+ Erstellen Sie eine eigene Checkliste mit Sektionen und Punkten. +

+
+ +
+
+ + +

z.B. „UPC SoC — interne Checkliste“.

+
+ +
+ +