Go ServeMux refused to register patterns 'GET /checklists/{slug}/edit' (from
dirac's Slice A merge b418705) and 'GET /checklists/instances/{id}' (existing)
because both match '/checklists/instances/edit'. Container crash-looped on
boot since 13:32 UTC; paliad.de returned 404 from Traefik because no app was
listening.
Renaming the new template-edit route to /checklists/templates/{slug}/edit
disambiguates — '/templates/...' is a literal segment so the {slug} is now
strictly under a fixed prefix that can't collide with 'instances'.
Touches:
- internal/handlers/handlers.go:257 — route pattern
- frontend/src/client/checklists.ts:290 — Bearbeiten link
- frontend/src/client/checklists-author.ts:52 — URL parser regex
- frontend/src/checklists-author.tsx — doc comment
go build + bun run build clean.
121 lines
6.5 KiB
TypeScript
121 lines
6.5 KiB
TypeScript
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/templates/{slug}/edit serve this same bundle; the client reads
|
|
// window.location.pathname to decide create vs edit mode.
|
|
export function renderChecklistsAuthor(): string {
|
|
return "<!DOCTYPE html>" + (
|
|
<html lang="de">
|
|
<head>
|
|
<meta charset="UTF-8" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
|
|
<meta name="theme-color" content="#BFF355" />
|
|
<meta name="apple-mobile-web-app-capable" content="yes" />
|
|
<meta name="apple-mobile-web-app-status-bar-style" content="default" />
|
|
<PWAHead />
|
|
<title data-i18n="checklisten.author.title">Vorlage erstellen — Paliad</title>
|
|
<link rel="stylesheet" href="/assets/global.css" />
|
|
</head>
|
|
<body className="has-sidebar">
|
|
<Sidebar currentPath="/checklists" />
|
|
<BottomNav currentPath="/checklists" />
|
|
|
|
<main>
|
|
<section className="tool-page">
|
|
<div className="container">
|
|
<div className="tool-header">
|
|
<h1 id="author-heading" data-i18n="checklisten.author.heading.new">Neue Checklisten-Vorlage</h1>
|
|
<p className="tool-subtitle" data-i18n="checklisten.author.subtitle">
|
|
Erstellen Sie eine eigene Checkliste mit Sektionen und Punkten.
|
|
</p>
|
|
</div>
|
|
|
|
<form id="author-form" className="form-stack" autoComplete="off">
|
|
<div className="form-row">
|
|
<label className="form-label" htmlFor="title" data-i18n="checklisten.author.field.title">Titel</label>
|
|
<input className="form-input" id="title" name="title" type="text" required maxLength="200" />
|
|
<p className="form-hint" data-i18n="checklisten.author.field.title.hint">z.B. „UPC SoC — interne Checkliste“.</p>
|
|
</div>
|
|
|
|
<div className="form-row">
|
|
<label className="form-label" htmlFor="description" data-i18n="checklisten.author.field.description">Kurzbeschreibung</label>
|
|
<textarea className="form-input" id="description" name="description" rows="3" maxLength="2000" />
|
|
</div>
|
|
|
|
<div className="form-grid form-grid-2">
|
|
<div className="form-row">
|
|
<label className="form-label" htmlFor="regime" data-i18n="checklisten.author.field.regime">Regime</label>
|
|
<select className="form-input" id="regime" name="regime">
|
|
<option value="UPC">UPC</option>
|
|
<option value="DE">DE</option>
|
|
<option value="EPA">EPA</option>
|
|
<option value="OTHER" selected>OTHER</option>
|
|
</select>
|
|
</div>
|
|
<div className="form-row">
|
|
<label className="form-label" htmlFor="lang" data-i18n="checklisten.author.field.lang">Sprache</label>
|
|
<select className="form-input" id="lang" name="lang">
|
|
<option value="de" selected>Deutsch</option>
|
|
<option value="en">English</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="form-grid form-grid-2">
|
|
<div className="form-row">
|
|
<label className="form-label" htmlFor="court" data-i18n="checklisten.author.field.court">Gericht / Behörde</label>
|
|
<input className="form-input" id="court" name="court" type="text" maxLength="200" />
|
|
</div>
|
|
<div className="form-row">
|
|
<label className="form-label" htmlFor="reference" data-i18n="checklisten.author.field.reference">Rechtsgrundlage</label>
|
|
<input className="form-input" id="reference" name="reference" type="text" maxLength="200" />
|
|
</div>
|
|
</div>
|
|
|
|
<div className="form-row">
|
|
<label className="form-label" htmlFor="deadline" data-i18n="checklisten.author.field.deadline">Deadline (optional)</label>
|
|
<input className="form-input" id="deadline" name="deadline" type="text" maxLength="200" />
|
|
</div>
|
|
|
|
<fieldset className="form-fieldset">
|
|
<legend data-i18n="checklisten.author.field.visibility">Sichtbarkeit</legend>
|
|
<label className="form-radio">
|
|
<input type="radio" name="visibility" value="private" checked />
|
|
<span><strong data-i18n="checklisten.mine.visibility.private">Privat</strong> — <span data-i18n="checklisten.author.visibility.private.hint">Nur für Sie sichtbar.</span></span>
|
|
</label>
|
|
<label className="form-radio">
|
|
<input type="radio" name="visibility" value="firm" />
|
|
<span><strong data-i18n="checklisten.mine.visibility.firm">Firmenweit</strong> — <span data-i18n="checklisten.author.visibility.firm.hint">Für alle angemeldeten Kolleginnen und Kollegen sichtbar.</span></span>
|
|
</label>
|
|
</fieldset>
|
|
|
|
<fieldset className="form-fieldset">
|
|
<legend data-i18n="checklisten.author.groups.heading">Sektionen und Punkte</legend>
|
|
<div id="groups-container" />
|
|
<button type="button" className="btn btn-secondary" id="add-group" data-i18n="checklisten.author.groups.add">+ Sektion hinzufügen</button>
|
|
</fieldset>
|
|
|
|
<p id="author-error" className="form-error" style="display:none" role="alert" />
|
|
|
|
<div className="form-actions">
|
|
<button type="submit" className="btn btn-primary" id="author-save" data-i18n="checklisten.author.save">Speichern</button>
|
|
<a className="btn btn-secondary" href="/checklists?tab=mine" data-i18n="checklisten.author.cancel">Abbrechen</a>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</section>
|
|
</main>
|
|
|
|
<Footer />
|
|
<PaliadinWidget />
|
|
<script src="/assets/checklists-author.js"></script>
|
|
</body>
|
|
</html>
|
|
);
|
|
}
|