feat(procedures): U0 skeleton — /tools/procedures page shell (m/paliad#151)
First slice of the unified procedural-events tool train. Ships only the page chrome — route, sidebar/header, filter strip with search box, four entry-mode tabs (Verfahren wählen / Direkt suchen / Geführt / Aus Akte), and the host containers later slices mount their UI into. No data wiring. Per m's decisions (design §11.5): URL is English (/tools/procedures, not /tools/verfahren); all four tabs visible from boot (not a single-default landing); search box lives in the top filter strip and will compose with chip filters once U1+ wire them. U1 fills #procedures-panel-search (Mode A), U2 fills -wizard (Mode B), U3 fills -proceeding + #procedures-output-tree (Verfahrensablauf), U4 hard-cuts /tools/fristenrechner and /tools/verfahrensablauf to 301 redirects and drops the legacy pages.
This commit is contained in:
@@ -5,6 +5,7 @@ import { renderLogin } from "./src/login";
|
|||||||
import { renderKostenrechner } from "./src/kostenrechner";
|
import { renderKostenrechner } from "./src/kostenrechner";
|
||||||
import { renderFristenrechner } from "./src/fristenrechner";
|
import { renderFristenrechner } from "./src/fristenrechner";
|
||||||
import { renderVerfahrensablauf } from "./src/verfahrensablauf";
|
import { renderVerfahrensablauf } from "./src/verfahrensablauf";
|
||||||
|
import { renderProcedures } from "./src/procedures";
|
||||||
import { renderDownloads } from "./src/downloads";
|
import { renderDownloads } from "./src/downloads";
|
||||||
import { renderLinks } from "./src/links";
|
import { renderLinks } from "./src/links";
|
||||||
import { renderGlossary } from "./src/glossary";
|
import { renderGlossary } from "./src/glossary";
|
||||||
@@ -243,6 +244,7 @@ async function build() {
|
|||||||
join(import.meta.dir, "src/client/kostenrechner.ts"),
|
join(import.meta.dir, "src/client/kostenrechner.ts"),
|
||||||
join(import.meta.dir, "src/client/fristenrechner.ts"),
|
join(import.meta.dir, "src/client/fristenrechner.ts"),
|
||||||
join(import.meta.dir, "src/client/verfahrensablauf.ts"),
|
join(import.meta.dir, "src/client/verfahrensablauf.ts"),
|
||||||
|
join(import.meta.dir, "src/client/procedures.ts"),
|
||||||
join(import.meta.dir, "src/client/downloads.ts"),
|
join(import.meta.dir, "src/client/downloads.ts"),
|
||||||
join(import.meta.dir, "src/client/links.ts"),
|
join(import.meta.dir, "src/client/links.ts"),
|
||||||
join(import.meta.dir, "src/client/glossary.ts"),
|
join(import.meta.dir, "src/client/glossary.ts"),
|
||||||
@@ -371,6 +373,7 @@ async function build() {
|
|||||||
await Bun.write(join(DIST, "kostenrechner.html"), renderKostenrechner());
|
await Bun.write(join(DIST, "kostenrechner.html"), renderKostenrechner());
|
||||||
await Bun.write(join(DIST, "fristenrechner.html"), renderFristenrechner());
|
await Bun.write(join(DIST, "fristenrechner.html"), renderFristenrechner());
|
||||||
await Bun.write(join(DIST, "verfahrensablauf.html"), renderVerfahrensablauf());
|
await Bun.write(join(DIST, "verfahrensablauf.html"), renderVerfahrensablauf());
|
||||||
|
await Bun.write(join(DIST, "procedures.html"), renderProcedures());
|
||||||
await Bun.write(join(DIST, "downloads.html"), renderDownloads());
|
await Bun.write(join(DIST, "downloads.html"), renderDownloads());
|
||||||
await Bun.write(join(DIST, "links.html"), renderLinks());
|
await Bun.write(join(DIST, "links.html"), renderLinks());
|
||||||
await Bun.write(join(DIST, "glossary.html"), renderGlossary());
|
await Bun.write(join(DIST, "glossary.html"), renderGlossary());
|
||||||
|
|||||||
@@ -205,6 +205,25 @@ const translations: Record<Lang, Record<string, string>> = {
|
|||||||
"tools.verfahrensablauf.heading": "Verfahrensablauf",
|
"tools.verfahrensablauf.heading": "Verfahrensablauf",
|
||||||
"tools.verfahrensablauf.subtitle": "Typischen Verfahrensablauf einsehen \u2014 Verfahrensart w\u00e4hlen, Datum optional setzen.",
|
"tools.verfahrensablauf.subtitle": "Typischen Verfahrensablauf einsehen \u2014 Verfahrensart w\u00e4hlen, Datum optional setzen.",
|
||||||
|
|
||||||
|
// Unified procedural-events tool (m/paliad#151, U0 skeleton)
|
||||||
|
"procedures.title": "Verfahren & Fristen \u2014 Paliad",
|
||||||
|
"procedures.heading": "Verfahren & Fristen",
|
||||||
|
"procedures.subtitle": "Verfahrensablauf, Fristenrechner und gef\u00fchrte Suche in einem Tool.",
|
||||||
|
"procedures.filter.search.placeholder": "Klageerhebung, Hinweisbeschluss, oral hearing\u2026",
|
||||||
|
"procedures.filter.axis.forum": "Forum:",
|
||||||
|
"procedures.filter.axis.proc": "Verfahren:",
|
||||||
|
"procedures.filter.axis.kind": "Ereignisart:",
|
||||||
|
"procedures.filter.axis.party": "Partei:",
|
||||||
|
"procedures.tab.proceeding": "Verfahren w\u00e4hlen",
|
||||||
|
"procedures.tab.search": "Direkt suchen",
|
||||||
|
"procedures.tab.wizard": "Gef\u00fchrt",
|
||||||
|
"procedures.tab.akte": "Aus Akte",
|
||||||
|
"procedures.panel.proceeding.placeholder": "Verfahrenswahl folgt in U3 \u2014 das \u00dcbersichts-Baumdiagramm wird hier eingebettet.",
|
||||||
|
"procedures.panel.search.placeholder": "Direktsuche folgt in U1.",
|
||||||
|
"procedures.panel.wizard.placeholder": "Gef\u00fchrter Einstieg folgt in U2.",
|
||||||
|
"procedures.panel.akte.placeholder": "Akten-Einstieg folgt in einem sp\u00e4teren Slice.",
|
||||||
|
"nav.procedures": "Verfahren & Fristen",
|
||||||
|
|
||||||
"deadlines.step1": "Verfahrensart w\u00e4hlen",
|
"deadlines.step1": "Verfahrensart w\u00e4hlen",
|
||||||
"deadlines.step2": "Ausgangsdatum eingeben",
|
"deadlines.step2": "Ausgangsdatum eingeben",
|
||||||
"deadlines.step2.perspective": "Perspektive und Datum",
|
"deadlines.step2.perspective": "Perspektive und Datum",
|
||||||
@@ -3399,6 +3418,25 @@ const translations: Record<Lang, Record<string, string>> = {
|
|||||||
"tools.verfahrensablauf.heading": "Procedure Roadmap",
|
"tools.verfahrensablauf.heading": "Procedure Roadmap",
|
||||||
"tools.verfahrensablauf.subtitle": "Browse the typical proceeding shape \u2014 pick a proceeding type, optionally set a trigger date.",
|
"tools.verfahrensablauf.subtitle": "Browse the typical proceeding shape \u2014 pick a proceeding type, optionally set a trigger date.",
|
||||||
|
|
||||||
|
// Unified procedural-events tool (m/paliad#151, U0 skeleton)
|
||||||
|
"procedures.title": "Procedures & Deadlines \u2014 Paliad",
|
||||||
|
"procedures.heading": "Procedures & Deadlines",
|
||||||
|
"procedures.subtitle": "Procedure roadmap, deadline calculator, and guided search in one tool.",
|
||||||
|
"procedures.filter.search.placeholder": "Statement of claim, hearing notice, m\u00fcndliche Verhandlung\u2026",
|
||||||
|
"procedures.filter.axis.forum": "Forum:",
|
||||||
|
"procedures.filter.axis.proc": "Proceeding:",
|
||||||
|
"procedures.filter.axis.kind": "Event kind:",
|
||||||
|
"procedures.filter.axis.party": "Party:",
|
||||||
|
"procedures.tab.proceeding": "Pick proceeding",
|
||||||
|
"procedures.tab.search": "Direct search",
|
||||||
|
"procedures.tab.wizard": "Guided",
|
||||||
|
"procedures.tab.akte": "From matter",
|
||||||
|
"procedures.panel.proceeding.placeholder": "Pick-proceeding view ships in U3 \u2014 the overview tree mounts here.",
|
||||||
|
"procedures.panel.search.placeholder": "Direct search ships in U1.",
|
||||||
|
"procedures.panel.wizard.placeholder": "Guided entry ships in U2.",
|
||||||
|
"procedures.panel.akte.placeholder": "Matter entry ships in a later slice.",
|
||||||
|
"nav.procedures": "Procedures & Deadlines",
|
||||||
|
|
||||||
"deadlines.step1": "Select Proceeding Type",
|
"deadlines.step1": "Select Proceeding Type",
|
||||||
"deadlines.step2": "Enter Trigger Date",
|
"deadlines.step2": "Enter Trigger Date",
|
||||||
"deadlines.step2.perspective": "Perspective and Date",
|
"deadlines.step2.perspective": "Perspective and Date",
|
||||||
|
|||||||
72
frontend/src/client/procedures.ts
Normal file
72
frontend/src/client/procedures.ts
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
// /tools/procedures client — U0 skeleton boot
|
||||||
|
// (m/paliad#151, docs/design-unified-procedural-events-tool-2026-05-27.md).
|
||||||
|
//
|
||||||
|
// U0 owns:
|
||||||
|
// - Tab switching across the four entry modes (proceeding / search /
|
||||||
|
// wizard / akte). URL-driven via ?mode=<name>; cold open lands on
|
||||||
|
// "proceeding" per design §11.5.Q3.
|
||||||
|
// - Showing exactly one panel at a time.
|
||||||
|
//
|
||||||
|
// Later slices wire data:
|
||||||
|
// U1 mounts Mode A into #procedures-panel-search.
|
||||||
|
// U2 mounts Mode B into #procedures-panel-wizard.
|
||||||
|
// U3 mounts Verfahrensablauf into #procedures-panel-proceeding +
|
||||||
|
// #procedures-output-tree.
|
||||||
|
// The search box in the top filter strip and the chip filters in
|
||||||
|
// #procedures-filter-chips-* are also wired in U1+ as each slice
|
||||||
|
// adds its dimension-aware behaviour.
|
||||||
|
|
||||||
|
import { initI18n } from "./i18n";
|
||||||
|
import { initSidebar } from "./sidebar";
|
||||||
|
|
||||||
|
type ProceduresTab = "proceeding" | "search" | "wizard" | "akte";
|
||||||
|
|
||||||
|
const TABS: ProceduresTab[] = ["proceeding", "search", "wizard", "akte"];
|
||||||
|
|
||||||
|
function readTabFromUrl(): ProceduresTab {
|
||||||
|
const params = new URLSearchParams(window.location.search);
|
||||||
|
const raw = params.get("mode");
|
||||||
|
if (raw && (TABS as string[]).includes(raw)) return raw as ProceduresTab;
|
||||||
|
return "proceeding";
|
||||||
|
}
|
||||||
|
|
||||||
|
function writeTabToUrl(tab: ProceduresTab): void {
|
||||||
|
const url = new URL(window.location.href);
|
||||||
|
if (tab === "proceeding") {
|
||||||
|
url.searchParams.delete("mode");
|
||||||
|
} else {
|
||||||
|
url.searchParams.set("mode", tab);
|
||||||
|
}
|
||||||
|
history.replaceState(null, "", url.pathname + url.search + url.hash);
|
||||||
|
}
|
||||||
|
|
||||||
|
function showTab(tab: ProceduresTab): void {
|
||||||
|
for (const t of TABS) {
|
||||||
|
const btn = document.getElementById(`procedures-tab-${t}`);
|
||||||
|
const panel = document.getElementById(`procedures-panel-${t}`);
|
||||||
|
const active = t === tab;
|
||||||
|
if (btn) {
|
||||||
|
btn.classList.toggle("is-active", active);
|
||||||
|
btn.setAttribute("aria-selected", active ? "true" : "false");
|
||||||
|
}
|
||||||
|
if (panel) panel.hidden = !active;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function wireTabs(): void {
|
||||||
|
for (const t of TABS) {
|
||||||
|
const btn = document.getElementById(`procedures-tab-${t}`);
|
||||||
|
if (!btn) continue;
|
||||||
|
btn.addEventListener("click", () => {
|
||||||
|
showTab(t);
|
||||||
|
writeTabToUrl(t);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
document.addEventListener("DOMContentLoaded", () => {
|
||||||
|
initI18n();
|
||||||
|
initSidebar();
|
||||||
|
showTab(readTabFromUrl());
|
||||||
|
wireTabs();
|
||||||
|
});
|
||||||
@@ -2088,6 +2088,7 @@ export type I18nKey =
|
|||||||
| "nav.logout"
|
| "nav.logout"
|
||||||
| "nav.neuigkeiten"
|
| "nav.neuigkeiten"
|
||||||
| "nav.paliadin"
|
| "nav.paliadin"
|
||||||
|
| "nav.procedures"
|
||||||
| "nav.projekte"
|
| "nav.projekte"
|
||||||
| "nav.soon.tooltip"
|
| "nav.soon.tooltip"
|
||||||
| "nav.submissions"
|
| "nav.submissions"
|
||||||
@@ -2204,6 +2205,22 @@ export type I18nKey =
|
|||||||
| "partner_unit.members_label"
|
| "partner_unit.members_label"
|
||||||
| "partner_unit.none"
|
| "partner_unit.none"
|
||||||
| "partner_unit.subtitle"
|
| "partner_unit.subtitle"
|
||||||
|
| "procedures.filter.axis.forum"
|
||||||
|
| "procedures.filter.axis.kind"
|
||||||
|
| "procedures.filter.axis.party"
|
||||||
|
| "procedures.filter.axis.proc"
|
||||||
|
| "procedures.filter.search.placeholder"
|
||||||
|
| "procedures.heading"
|
||||||
|
| "procedures.panel.akte.placeholder"
|
||||||
|
| "procedures.panel.proceeding.placeholder"
|
||||||
|
| "procedures.panel.search.placeholder"
|
||||||
|
| "procedures.panel.wizard.placeholder"
|
||||||
|
| "procedures.subtitle"
|
||||||
|
| "procedures.tab.akte"
|
||||||
|
| "procedures.tab.proceeding"
|
||||||
|
| "procedures.tab.search"
|
||||||
|
| "procedures.tab.wizard"
|
||||||
|
| "procedures.title"
|
||||||
| "project.instance_level.appeal"
|
| "project.instance_level.appeal"
|
||||||
| "project.instance_level.cassation"
|
| "project.instance_level.cassation"
|
||||||
| "project.instance_level.first"
|
| "project.instance_level.first"
|
||||||
|
|||||||
193
frontend/src/procedures.tsx
Normal file
193
frontend/src/procedures.tsx
Normal file
@@ -0,0 +1,193 @@
|
|||||||
|
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";
|
||||||
|
|
||||||
|
// U0 — Skeleton for the unified procedural-events tool
|
||||||
|
// (m/paliad#151, design docs/design-unified-procedural-events-tool-2026-05-27.md).
|
||||||
|
//
|
||||||
|
// Folds /tools/fristenrechner (Mode A + Mode B + result) and
|
||||||
|
// /tools/verfahrensablauf into a single page at /tools/procedures. Each
|
||||||
|
// later slice fills one of the four entry tabs:
|
||||||
|
//
|
||||||
|
// U1 — Direkt suchen (Mode A search)
|
||||||
|
// U2 — Geführt (Mode B wizard)
|
||||||
|
// U3 — Verfahren (Verfahrensablauf tree + 3-way detail filter)
|
||||||
|
// U4 — Hard-cut 301 (drop legacy pages, redirect URLs)
|
||||||
|
//
|
||||||
|
// This file ships only the page chrome — sidebar, header, filter strip
|
||||||
|
// with search box, four entry-mode tabs, and the host containers the
|
||||||
|
// later slices mount their UI into. No data wiring.
|
||||||
|
|
||||||
|
export function renderProcedures(): 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="procedures.title">Verfahren & Fristen — Paliad</title>
|
||||||
|
<link rel="stylesheet" href="/assets/global.css" />
|
||||||
|
</head>
|
||||||
|
<body className="has-sidebar page-procedures">
|
||||||
|
<Sidebar currentPath="/tools/procedures" />
|
||||||
|
<BottomNav currentPath="/tools/procedures" />
|
||||||
|
|
||||||
|
<main>
|
||||||
|
<section className="tool-page">
|
||||||
|
<div className="container">
|
||||||
|
<div className="tool-header">
|
||||||
|
<h1 data-i18n="procedures.heading">Verfahren & Fristen</h1>
|
||||||
|
<p className="tool-subtitle" data-i18n="procedures.subtitle">
|
||||||
|
Verfahrensablauf, Fristenrechner und gerührte Suche in einem Tool.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Shared filter strip — search box + four chip groups
|
||||||
|
(forum / proceeding / event_kind / party). Lives at the
|
||||||
|
top of the page so every entry tab and output mode reads
|
||||||
|
the same active filter set (design §4 + m's Q3
|
||||||
|
divergence: search composes with chip filters). U0
|
||||||
|
ships the markup only; chip hydration + search wiring
|
||||||
|
arrive with U1-U3. */}
|
||||||
|
<section className="procedures-filter-strip" aria-label="Filter">
|
||||||
|
<div className="procedures-filter-search">
|
||||||
|
<svg className="procedures-filter-search-icon" width="18" height="18" viewBox="0 0 24 24"
|
||||||
|
fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"
|
||||||
|
stroke-linejoin="round" aria-hidden="true">
|
||||||
|
<circle cx="11" cy="11" r="7"></circle>
|
||||||
|
<line x1="21" y1="21" x2="16.65" y2="16.65"></line>
|
||||||
|
</svg>
|
||||||
|
<input
|
||||||
|
type="search"
|
||||||
|
id="procedures-search-input"
|
||||||
|
className="procedures-filter-search-input"
|
||||||
|
autocomplete="off"
|
||||||
|
spellcheck="false"
|
||||||
|
data-i18n-placeholder="procedures.filter.search.placeholder"
|
||||||
|
placeholder="Klageerhebung, Hinweisbeschluss, oral hearing…"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="procedures-filter-chips" id="procedures-filter-chips">
|
||||||
|
<div className="procedures-filter-chip-row" data-axis="forum">
|
||||||
|
<span className="procedures-filter-axis-label" data-i18n="procedures.filter.axis.forum">Forum:</span>
|
||||||
|
<div className="procedures-filter-chip-host" id="procedures-filter-chips-forum"></div>
|
||||||
|
</div>
|
||||||
|
<div className="procedures-filter-chip-row" data-axis="proc">
|
||||||
|
<span className="procedures-filter-axis-label" data-i18n="procedures.filter.axis.proc">Verfahren:</span>
|
||||||
|
<div className="procedures-filter-chip-host" id="procedures-filter-chips-proc"></div>
|
||||||
|
</div>
|
||||||
|
<div className="procedures-filter-chip-row" data-axis="kind">
|
||||||
|
<span className="procedures-filter-axis-label" data-i18n="procedures.filter.axis.kind">Ereignisart:</span>
|
||||||
|
<div className="procedures-filter-chip-host" id="procedures-filter-chips-kind"></div>
|
||||||
|
</div>
|
||||||
|
<div className="procedures-filter-chip-row" data-axis="party">
|
||||||
|
<span className="procedures-filter-axis-label" data-i18n="procedures.filter.axis.party">Partei:</span>
|
||||||
|
<div className="procedures-filter-chip-host" id="procedures-filter-chips-party"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* Entry-mode tab strip — all four tabs visible from boot
|
||||||
|
(m's Q3 divergence). The active tab is URL-driven
|
||||||
|
(?mode=proceeding|search|wizard|akte); cold open lands
|
||||||
|
on "proceeding" per design §11.5.Q3. */}
|
||||||
|
<nav className="procedures-tabs" role="tablist" aria-label="Einstieg">
|
||||||
|
<button type="button"
|
||||||
|
className="procedures-tab is-active"
|
||||||
|
role="tab"
|
||||||
|
aria-selected="true"
|
||||||
|
data-tab="proceeding"
|
||||||
|
id="procedures-tab-proceeding">
|
||||||
|
<span className="procedures-tab-icon" aria-hidden="true">📚</span>
|
||||||
|
<span className="procedures-tab-label" data-i18n="procedures.tab.proceeding">Verfahren wählen</span>
|
||||||
|
</button>
|
||||||
|
<button type="button"
|
||||||
|
className="procedures-tab"
|
||||||
|
role="tab"
|
||||||
|
aria-selected="false"
|
||||||
|
data-tab="search"
|
||||||
|
id="procedures-tab-search">
|
||||||
|
<span className="procedures-tab-icon" aria-hidden="true">⚡</span>
|
||||||
|
<span className="procedures-tab-label" data-i18n="procedures.tab.search">Direkt suchen</span>
|
||||||
|
</button>
|
||||||
|
<button type="button"
|
||||||
|
className="procedures-tab"
|
||||||
|
role="tab"
|
||||||
|
aria-selected="false"
|
||||||
|
data-tab="wizard"
|
||||||
|
id="procedures-tab-wizard">
|
||||||
|
<span className="procedures-tab-icon" aria-hidden="true">🧭</span>
|
||||||
|
<span className="procedures-tab-label" data-i18n="procedures.tab.wizard">Geführt</span>
|
||||||
|
</button>
|
||||||
|
<button type="button"
|
||||||
|
className="procedures-tab"
|
||||||
|
role="tab"
|
||||||
|
aria-selected="false"
|
||||||
|
data-tab="akte"
|
||||||
|
id="procedures-tab-akte">
|
||||||
|
<span className="procedures-tab-icon" aria-hidden="true">📁</span>
|
||||||
|
<span className="procedures-tab-label" data-i18n="procedures.tab.akte">Aus Akte</span>
|
||||||
|
</button>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
{/* Per-tab content hosts. Only one is visible at a time —
|
||||||
|
procedures.ts toggles `hidden` on the inactive ones.
|
||||||
|
Each later slice fills the corresponding host. */}
|
||||||
|
<section className="procedures-panel" id="procedures-panel-proceeding" role="tabpanel"
|
||||||
|
aria-labelledby="procedures-tab-proceeding">
|
||||||
|
<div className="procedures-panel-placeholder" data-i18n="procedures.panel.proceeding.placeholder">
|
||||||
|
Verfahrenswahl folgt in U3 — das Übersichts-Baumdiagramm wird hier eingebettet.
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section className="procedures-panel" id="procedures-panel-search" role="tabpanel"
|
||||||
|
aria-labelledby="procedures-tab-search" hidden>
|
||||||
|
<div className="procedures-panel-placeholder" data-i18n="procedures.panel.search.placeholder">
|
||||||
|
Direktsuche folgt in U1.
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section className="procedures-panel" id="procedures-panel-wizard" role="tabpanel"
|
||||||
|
aria-labelledby="procedures-tab-wizard" hidden>
|
||||||
|
<div className="procedures-panel-placeholder" data-i18n="procedures.panel.wizard.placeholder">
|
||||||
|
Geführter Einstieg folgt in U2.
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section className="procedures-panel" id="procedures-panel-akte" role="tabpanel"
|
||||||
|
aria-labelledby="procedures-tab-akte" hidden>
|
||||||
|
<div className="procedures-panel-placeholder" data-i18n="procedures.panel.akte.placeholder">
|
||||||
|
Akten-Einstieg folgt in einem späteren Slice.
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* Tree output host. Slice U3 mounts the Verfahrensablauf
|
||||||
|
tree here; U0 leaves it empty + hidden so the
|
||||||
|
tab placeholders are the only thing visible. */}
|
||||||
|
<section className="procedures-output procedures-output-tree" id="procedures-output-tree"
|
||||||
|
aria-label="Tree output" hidden></section>
|
||||||
|
|
||||||
|
{/* Linear-drawer host. Inline drawer expanding beneath a
|
||||||
|
tree card (design §8 — desktop) AND the standalone
|
||||||
|
linear follow-up view that Mode A / Mode B land on
|
||||||
|
after locking a trigger event (design §3.2). U1
|
||||||
|
switches it on. */}
|
||||||
|
<section className="procedures-output procedures-output-linear" id="procedures-output-linear"
|
||||||
|
aria-label="Linear output" hidden></section>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<Footer />
|
||||||
|
<PaliadinWidget />
|
||||||
|
<script src="/assets/procedures.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -36,6 +36,17 @@ func handleVerfahrensablaufPage(w http.ResponseWriter, r *http.Request) {
|
|||||||
http.ServeFile(w, r, "dist/verfahrensablauf.html")
|
http.ServeFile(w, r, "dist/verfahrensablauf.html")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Unified procedural-events tool page (m/paliad#151, design
|
||||||
|
// docs/design-unified-procedural-events-tool-2026-05-27.md). Consolidates
|
||||||
|
// Fristenrechner Mode A + Mode B + result + Verfahrensablauf into a
|
||||||
|
// single surface at /tools/procedures. No DB dependency — the page
|
||||||
|
// itself is static HTML; per-tab data flows over the existing
|
||||||
|
// /api/tools/fristenrechner/* endpoints. Slice U4 turns the legacy
|
||||||
|
// /tools/fristenrechner + /tools/verfahrensablauf into 301 redirects.
|
||||||
|
func handleProceduresPage(w http.ResponseWriter, r *http.Request) {
|
||||||
|
http.ServeFile(w, r, "dist/procedures.html")
|
||||||
|
}
|
||||||
|
|
||||||
// POST /api/tools/fristenrechner — calculate the UI timeline for a proceeding.
|
// POST /api/tools/fristenrechner — calculate the UI timeline for a proceeding.
|
||||||
//
|
//
|
||||||
// Phase C: routes through FristenrechnerService which pulls rules from
|
// Phase C: routes through FristenrechnerService which pulls rules from
|
||||||
|
|||||||
@@ -305,6 +305,7 @@ func Register(mux *http.ServeMux, client *auth.Client, giteaAPIToken string, svc
|
|||||||
protected.HandleFunc("POST /api/tools/kostenrechner", handleKostenrechnerAPI)
|
protected.HandleFunc("POST /api/tools/kostenrechner", handleKostenrechnerAPI)
|
||||||
protected.HandleFunc("GET /tools/fristenrechner", handleFristenrechnerPage)
|
protected.HandleFunc("GET /tools/fristenrechner", handleFristenrechnerPage)
|
||||||
protected.HandleFunc("GET /tools/verfahrensablauf", handleVerfahrensablaufPage)
|
protected.HandleFunc("GET /tools/verfahrensablauf", handleVerfahrensablaufPage)
|
||||||
|
protected.HandleFunc("GET /tools/procedures", handleProceduresPage)
|
||||||
protected.HandleFunc("POST /api/tools/fristenrechner", handleFristenrechnerAPI)
|
protected.HandleFunc("POST /api/tools/fristenrechner", handleFristenrechnerAPI)
|
||||||
protected.HandleFunc("POST /api/tools/fristenrechner/calculate-rule", handleFristenrechnerCalculateRule)
|
protected.HandleFunc("POST /api/tools/fristenrechner/calculate-rule", handleFristenrechnerCalculateRule)
|
||||||
protected.HandleFunc("GET /api/tools/proceeding-types", handleProceedingTypes)
|
protected.HandleFunc("GET /api/tools/proceeding-types", handleProceedingTypes)
|
||||||
|
|||||||
Reference in New Issue
Block a user