feat: responsives Frontend — Seitenleiste ab Desktop, Tabellen-Styling
Nav wird jetzt für alle Seiten aus einer einzigen Stelle (layout.html-Block) gerendert: auf dem Handy ein per Checkbox-Hack aufklappbares Menü (kein JavaScript), ab 960px Breite per CSS in eine permanente, dunkle Seitenleiste im enconf-Look verwandelt — dieselbe Markup-Struktur bedient beide Layouts, kein separates Desktop-Template. <details>/<summary> wurde bewusst NICHT verwendet: aktuelle Chromium-Versionen steuern dessen Auf-/Zuklapp-Zustand über eine CSS-resistente interne Animation (auch mit !important nicht überschreibbar), per Headless-Screenshot verifiziert. Zusätzlich: Tabellen (vorher komplett ungestylt, betraf v. a. das Register) haben jetzt echte Gestaltung inkl. horizontal scrollbarem Wrapper für schmale Bildschirme, Listenkarten ohne Link-Wrapper (Nutzer-/Abteilungsliste) bekommen dieselbe Kartenoptik wie verlinkte Einträge, und destruktive Aktionen (Löschen/Deaktivieren) sind jetzt visuell von primären Aktionen unterschieden. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
48
CLAUDE.md
48
CLAUDE.md
@@ -332,6 +332,49 @@ nicht anzulegen. Noch nicht gebaut (kein Abo-System).
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## Frontend
|
||||||
|
|
||||||
|
Anspruch (2026-08-29 explizit vom Nutzer bestätigt, da Deklarix ein
|
||||||
|
buchbarer Service werden soll): **für Browser UND Mobile optimiert,
|
||||||
|
und jede Entität im Datenmodell muss über das Frontend steuerbar sein**
|
||||||
|
— eine reine Anzeige-Seite ohne CRUD ist ein Defizit, kein v1-Kompromiss.
|
||||||
|
Stack bleibt `html/template` + htmx, kein React/Vue/SPA (siehe
|
||||||
|
Baureihenfolge/Architektur-Entscheidungen) — die responsive Optik wird
|
||||||
|
rein mit CSS erreicht, ohne das Template-Modell zu ändern.
|
||||||
|
|
||||||
|
**Navigation** (`internal/web/templates/layout.html`, `"nav"`-Block,
|
||||||
|
einmal definiert und von jeder Seite eingebunden — Änderungen hier
|
||||||
|
wirken auf das ganze Produkt): ein Checkbox-Hack (versteckte Checkbox +
|
||||||
|
`<label for=...>` als Klick-Ziel) klappt auf dem Handy ein Menü auf,
|
||||||
|
ganz ohne JavaScript. **Nicht** das naheliegendere `<details>`/`<summary>`
|
||||||
|
verwenden — aktuelle Chromium-Versionen steuern dessen Auf-/Zuklapp-
|
||||||
|
Zustand über eine interne, mit CSS (auch nicht mit `!important`)
|
||||||
|
nicht überschreibbare Animation; ein Versuch, `.app-nav { display:
|
||||||
|
flex !important }` bei geschlossenem `<details>` zu erzwingen, bleibt
|
||||||
|
wirkungslos (mit Chromium-Headless-Screenshot verifiziert). Ab
|
||||||
|
960px Breite (`@media (min-width: 960px)`, `app.css`) wird exakt
|
||||||
|
dieselbe Markup-Struktur per CSS zu einer permanenten, dunklen
|
||||||
|
Seitenleiste (Farb-Tokens aus `design/enterprise.css` übernommen) —
|
||||||
|
kein separates Desktop-Template.
|
||||||
|
|
||||||
|
**Tabellen** (`table`/`th`/`td` in `app.css`) sind seit dieser Änderung
|
||||||
|
gestylt (vorher komplett ungestylt, betraf v. a. `register_liste.html`);
|
||||||
|
breite Tabellen stehen in einem `.table-scroll`-Wrapper (horizontales
|
||||||
|
Scrollen auf dem Handy statt gequetschter Spalten).
|
||||||
|
|
||||||
|
**Verifikationsmethode für CSS-Änderungen:** Live-Cookie-Auth per
|
||||||
|
Chromium-Headless/CDP ist im Sandbox-Environment nicht möglich (kein
|
||||||
|
websocket-Python-Modul) — stattdessen: Seite per `curl -b cookies.txt`
|
||||||
|
authentifiziert abrufen, `/static/...`-Pfade im HTML auf eine absolute
|
||||||
|
`http://localhost:<port>/static/...`-URL umschreiben (Assets brauchen
|
||||||
|
kein Auth-Cookie), dann `chromium --headless --disable-gpu --no-sandbox
|
||||||
|
--window-size=<W>,<H> --screenshot=out.png file:///pfad/zur/seite.html`
|
||||||
|
bei mobiler (z. B. 390×844) und Desktop-Breite (z. B. 1440×900)
|
||||||
|
screenshotten. Für einen Menü-Aufklapp-Zustand: `checked`-Attribut
|
||||||
|
manuell ins gespeicherte HTML einfügen vor dem Screenshot.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## Projektstruktur
|
## Projektstruktur
|
||||||
|
|
||||||
```
|
```
|
||||||
@@ -346,7 +389,10 @@ nicht anzulegen. Noch nicht gebaut (kein Abo-System).
|
|||||||
│ └── web/ # Handler, Templates
|
│ └── web/ # Handler, Templates
|
||||||
├── rules/ # YAML-Regelwerk + OPEN.md (offene fachliche Fragen)
|
├── rules/ # YAML-Regelwerk + OPEN.md (offene fachliche Fragen)
|
||||||
├── design/
|
├── design/
|
||||||
│ └── enterprise.css # Design-System (enconf-Basis, ungenutzt seit Pivot)
|
│ └── enterprise.css # enconf Ant-Design-Theme — Referenz für Design-Tokens
|
||||||
|
│ (Farben/Radius/Schatten), nicht direkt eingebunden
|
||||||
|
│ (Ant-Design-Klassennamen passen nicht zu Deklarix'
|
||||||
|
│ reinem HTML/htmx-Stack, siehe internal/web/static/app.css)
|
||||||
├── packaging/
|
├── packaging/
|
||||||
│ └── DEBIAN/
|
│ └── DEBIAN/
|
||||||
│ └── control.tmpl # .deb Package-Control-Template
|
│ └── control.tmpl # .deb Package-Control-Template
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
/* Deklarix — eigenes, schlankes Stylesheet auf Basis der Design-Tokens
|
/* Deklarix — eigenes, schlankes Stylesheet auf Basis der Design-Tokens
|
||||||
aus dem enconf Enterprise Light Theme (design/enterprise.css): gleiche
|
aus dem enconf Enterprise Light Theme (design/enterprise.css): gleiche
|
||||||
Marke (Primärblau #1677ff, Inter, Radius-Skala), aber ohne dessen
|
Marke (Primärblau #1677ff, Inter, Radius-Skala). Mobile-first:
|
||||||
Ant-Design-/Desktop-Sidebar-Layout, das für Deklarix nicht passt.
|
Basis-Stile gelten fürs Telefon (Nav als aufklappbares <details>-Menü
|
||||||
Mobile-first: Basis-Stile gelten fürs Telefon, @media (min-width)
|
ohne JavaScript), @media (min-width: 960px) verwandelt dieselbe
|
||||||
erweitert für größere Bildschirme. */
|
Nav-Markup-Struktur per CSS in eine feste Seitenleiste (siehe
|
||||||
|
.topbar/.app-nav) — kein separates Desktop-Template nötig. */
|
||||||
|
|
||||||
@import url('/static/inter.css');
|
@import url('/static/inter.css');
|
||||||
|
|
||||||
@@ -14,6 +15,7 @@
|
|||||||
--radius-lg: 10px;
|
--radius-lg: 10px;
|
||||||
--shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05);
|
--shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05);
|
||||||
--shadow: 0 1px 3px rgba(0, 0, 0, 0.06), 0 1px 2px rgba(0, 0, 0, 0.04);
|
--shadow: 0 1px 3px rgba(0, 0, 0, 0.06), 0 1px 2px rgba(0, 0, 0, 0.04);
|
||||||
|
--shadow-md: 0 4px 12px rgba(0, 0, 0, 0.08);
|
||||||
|
|
||||||
--color-bg: #f8fafc;
|
--color-bg: #f8fafc;
|
||||||
--color-text: #334155;
|
--color-text: #334155;
|
||||||
@@ -27,6 +29,12 @@
|
|||||||
--color-mittel-bg: #fffbeb;
|
--color-mittel-bg: #fffbeb;
|
||||||
--color-niedrig: #166534;
|
--color-niedrig: #166534;
|
||||||
--color-niedrig-bg: #f0fdf4;
|
--color-niedrig-bg: #f0fdf4;
|
||||||
|
|
||||||
|
--sidebar-width: 220px;
|
||||||
|
--sidebar-bg: linear-gradient(180deg, #0b1426 0%, #101d33 50%, #0d1829 100%);
|
||||||
|
--sidebar-text: #b6c2d9;
|
||||||
|
--sidebar-text-hover: #ffffff;
|
||||||
|
--sidebar-hover-bg: rgba(255, 255, 255, 0.08);
|
||||||
}
|
}
|
||||||
|
|
||||||
* {
|
* {
|
||||||
@@ -74,23 +82,109 @@ a {
|
|||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
nav {
|
/* ── Navigation ──────────────────────────────────────────────────────
|
||||||
|
Mobil: .topbar ist eine schmale, fixierte Kopfleiste mit einem
|
||||||
|
aufklappbaren <details>-Menü (siehe layout.html) — kein JavaScript,
|
||||||
|
das <details>-Element liefert Auf-/Zuklappen nativ. Ab Desktop-Breite
|
||||||
|
(siehe Media Query unten) wird dieselbe Markup-Struktur per CSS in
|
||||||
|
eine permanent sichtbare, dunkle Seitenleiste verwandelt. */
|
||||||
|
.topbar {
|
||||||
|
position: sticky;
|
||||||
|
top: 0;
|
||||||
|
z-index: 10;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: flex-end;
|
justify-content: space-between;
|
||||||
gap: 16px;
|
|
||||||
padding: 12px 16px;
|
padding: 12px 16px;
|
||||||
|
background: #fff;
|
||||||
|
border-bottom: 1px solid var(--color-border);
|
||||||
}
|
}
|
||||||
|
|
||||||
nav a {
|
.brand {
|
||||||
color: var(--color-muted);
|
font-weight: 600;
|
||||||
|
color: var(--color-heading);
|
||||||
|
text-decoration: none;
|
||||||
|
letter-spacing: -0.01em;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Checkbox-Hack: eine unsichtbare Checkbox plus ein <label for=...>
|
||||||
|
als Klick-/Tap-Ziel steuern per CSS-Geschwister-Selektor, ob .app-nav
|
||||||
|
sichtbar ist — funktioniert ohne JavaScript und ohne die Falle von
|
||||||
|
<details> (siehe Kommentar in layout.html). */
|
||||||
|
.nav-toggle {
|
||||||
|
position: absolute;
|
||||||
|
width: 1px;
|
||||||
|
height: 1px;
|
||||||
|
overflow: hidden;
|
||||||
|
clip: rect(0, 0, 0, 0);
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-toggle-label {
|
||||||
|
cursor: pointer;
|
||||||
|
padding: 8px 14px;
|
||||||
|
border: 1px solid var(--color-border);
|
||||||
|
border-radius: var(--radius);
|
||||||
font-size: 0.875rem;
|
font-size: 0.875rem;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
|
color: var(--color-text);
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-toggle:focus-visible ~ .nav-toggle-label {
|
||||||
|
outline: 2px solid var(--branding-primary);
|
||||||
|
outline-offset: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-toggle:checked ~ .nav-toggle-label {
|
||||||
|
border-color: var(--branding-primary);
|
||||||
|
color: var(--branding-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-nav {
|
||||||
|
display: none;
|
||||||
|
position: absolute;
|
||||||
|
top: calc(100% + 6px);
|
||||||
|
right: 16px;
|
||||||
|
z-index: 20;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 2px;
|
||||||
|
min-width: 220px;
|
||||||
|
padding: 8px;
|
||||||
|
background: #fff;
|
||||||
|
border: 1px solid var(--color-border);
|
||||||
|
border-radius: var(--radius-md);
|
||||||
|
box-shadow: var(--shadow-md);
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-toggle:checked ~ .app-nav {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-nav a {
|
||||||
|
padding: 10px 12px;
|
||||||
|
border-radius: var(--radius);
|
||||||
|
color: var(--color-text);
|
||||||
|
font-size: 0.9375rem;
|
||||||
|
font-weight: 500;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
nav a:hover {
|
.app-nav a:hover {
|
||||||
color: var(--color-text);
|
background: var(--color-bg);
|
||||||
|
color: var(--branding-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-nav form {
|
||||||
|
margin: 4px 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-nav button {
|
||||||
|
width: 100%;
|
||||||
|
margin-top: 0;
|
||||||
|
background: transparent;
|
||||||
|
color: var(--color-hoch);
|
||||||
|
border: 1px solid var(--color-hoch-bg);
|
||||||
|
box-shadow: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Formulare: großzügige Touch-Ziele (min. 44px Höhe), volle Breite auf
|
/* Formulare: großzügige Touch-Ziele (min. 44px Höhe), volle Breite auf
|
||||||
@@ -275,7 +369,12 @@ nav button {
|
|||||||
gap: 8px;
|
gap: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.beitraege-liste li a {
|
.beitraege-liste li a,
|
||||||
|
/* Einträge ohne umschließenden Link (Zeilen mit Badge/Aktions-Buttons
|
||||||
|
statt Navigation, z. B. Nutzer-/Abteilungsliste) bekommen dieselbe
|
||||||
|
Karte direkt auf dem <li> — :has() unterscheidet beide Fälle, damit
|
||||||
|
ein verlinkter Eintrag nicht doppelt (li UND a) gerahmt wird. */
|
||||||
|
.beitraege-liste > li:not(:has(> a)) {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@@ -288,6 +387,15 @@ nav button {
|
|||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.beitraege-liste > li:not(:has(> a)) form {
|
||||||
|
margin: 0;
|
||||||
|
flex: 0 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.beitraege-liste > li:not(:has(> a)) button {
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
.beteiligte {
|
.beteiligte {
|
||||||
list-style: none;
|
list-style: none;
|
||||||
margin: 0 0 16px;
|
margin: 0 0 16px;
|
||||||
@@ -424,7 +532,45 @@ button.entfernen {
|
|||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Ab hier mehr Platz (Tablet/Desktop) — der Container bekommt spürbaren
|
/* Tabellen (z. B. Register-Export-Ansicht) — bewusst horizontal
|
||||||
|
scrollbar in einem eigenen Wrapper statt schrumpfender Spalten: bei
|
||||||
|
neun Spalten wie im Register würde Schrumpfen nur unlesbaren Text
|
||||||
|
erzeugen, siehe .table-scroll in register_liste.html. */
|
||||||
|
table {
|
||||||
|
width: 100%;
|
||||||
|
border-collapse: collapse;
|
||||||
|
background: #fff;
|
||||||
|
border-radius: var(--radius-md);
|
||||||
|
overflow: hidden;
|
||||||
|
font-size: 0.875rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
th, td {
|
||||||
|
padding: 10px 12px;
|
||||||
|
text-align: left;
|
||||||
|
border-bottom: 1px solid var(--color-border);
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
th {
|
||||||
|
background: var(--color-bg);
|
||||||
|
color: var(--color-heading);
|
||||||
|
font-weight: 600;
|
||||||
|
font-size: 0.8125rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
tbody tr:hover {
|
||||||
|
background: var(--color-bg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-scroll {
|
||||||
|
overflow-x: auto;
|
||||||
|
box-shadow: var(--shadow);
|
||||||
|
border-radius: var(--radius-md);
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ab hier mehr Platz (Tablet) — der Container bekommt spürbaren
|
||||||
Rand statt volle Breite, sonst bleibt alles identisch. */
|
Rand statt volle Breite, sonst bleibt alles identisch. */
|
||||||
@media (min-width: 640px) {
|
@media (min-width: 640px) {
|
||||||
.page {
|
.page {
|
||||||
@@ -435,3 +581,74 @@ button.entfernen {
|
|||||||
font-size: 1.75rem;
|
font-size: 1.75rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Ab Desktop-Breite: dieselbe .topbar/.app-nav-Markup wird zu einer
|
||||||
|
permanent sichtbaren, dunklen Seitenleiste — kein separates
|
||||||
|
Desktop-Template, nur CSS. Der `details`/`summary`-Aufklapp-
|
||||||
|
Mechanismus wird hier überschrieben (Inhalt immer sichtbar,
|
||||||
|
summary versteckt), das Handy-Verhalten bleibt darunter unverändert. */
|
||||||
|
@media (min-width: 960px) {
|
||||||
|
.topbar {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
bottom: 0;
|
||||||
|
width: var(--sidebar-width);
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: stretch;
|
||||||
|
justify-content: flex-start;
|
||||||
|
gap: 8px;
|
||||||
|
padding: 20px 16px;
|
||||||
|
background: var(--sidebar-bg);
|
||||||
|
border-bottom: none;
|
||||||
|
border-right: 1px solid rgba(255, 255, 255, 0.08);
|
||||||
|
z-index: 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
.brand {
|
||||||
|
color: #fff;
|
||||||
|
font-size: 1.125rem;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-toggle-label {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-nav {
|
||||||
|
display: flex;
|
||||||
|
position: static;
|
||||||
|
min-width: 0;
|
||||||
|
padding: 0;
|
||||||
|
background: transparent;
|
||||||
|
border: none;
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-nav a {
|
||||||
|
color: var(--sidebar-text);
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-nav a:hover {
|
||||||
|
background: var(--sidebar-hover-bg);
|
||||||
|
color: var(--sidebar-text-hover);
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-nav button {
|
||||||
|
color: var(--sidebar-text);
|
||||||
|
border-color: rgba(255, 255, 255, 0.15);
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-nav button:hover {
|
||||||
|
background: var(--sidebar-hover-bg);
|
||||||
|
color: var(--sidebar-text-hover);
|
||||||
|
filter: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page {
|
||||||
|
margin-left: var(--sidebar-width);
|
||||||
|
max-width: 1100px;
|
||||||
|
padding: 32px 40px;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
<li>
|
<li>
|
||||||
{{.Name}}
|
{{.Name}}
|
||||||
<form method="post" action="/verwaltung/abteilungen/{{.ID}}/loeschen" style="display:inline" onsubmit="return confirm('Abteilung wirklich löschen?')">
|
<form method="post" action="/verwaltung/abteilungen/{{.ID}}/loeschen" style="display:inline" onsubmit="return confirm('Abteilung wirklich löschen?')">
|
||||||
<button type="submit">Löschen</button>
|
<button type="submit" class="entfernen">Löschen</button>
|
||||||
</form>
|
</form>
|
||||||
</li>
|
</li>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|||||||
@@ -56,7 +56,7 @@
|
|||||||
</form>
|
</form>
|
||||||
{{if .ID}}
|
{{if .ID}}
|
||||||
<form method="post" action="/betreiber/werkzeuge/{{.ID}}/loeschen" onsubmit="return confirm('Werkzeug wirklich löschen?')">
|
<form method="post" action="/betreiber/werkzeuge/{{.ID}}/loeschen" onsubmit="return confirm('Werkzeug wirklich löschen?')">
|
||||||
<button type="submit">Werkzeug löschen</button>
|
<button type="submit" class="entfernen">Werkzeug löschen</button>
|
||||||
</form>
|
</form>
|
||||||
{{end}}
|
{{end}}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -6,21 +6,36 @@
|
|||||||
<script src="/static/htmx.min.js"></script>
|
<script src="/static/htmx.min.js"></script>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
|
{{/* Eine einzige Nav-Definition für alle Seiten (siehe navData in
|
||||||
|
middleware.go) — auf dem Handy ein aufklappbares Menü (Checkbox-
|
||||||
|
Hack, kein JavaScript: das <details>-Element scheitert daran, dass
|
||||||
|
aktuelle Chromium-Versionen dessen Auf-/Zuklapp-Zustand über eine
|
||||||
|
interne, nicht per CSS überschreibbare Animation steuern), ab
|
||||||
|
Desktop-Breite per CSS in eine permanent sichtbare Seitenleiste
|
||||||
|
verwandelt. Dieselbe Markup-Struktur bedient beide Layouts, siehe
|
||||||
|
app.css .app-nav. Die Checkbox ist bei jedem Seitenaufruf frisch
|
||||||
|
unchecked (serverseitig gerendert, kein Zustand über Navigation
|
||||||
|
hinweg nötig). */}}
|
||||||
{{define "nav"}}
|
{{define "nav"}}
|
||||||
<nav>
|
<header class="topbar">
|
||||||
<a href="/">Start</a>
|
<a class="brand" href="/">Deklarix</a>
|
||||||
{{if not .IsBetreiber}}<a href="/antraege">Meine Anträge</a>{{end}}
|
<input type="checkbox" id="nav-toggle" class="nav-toggle">
|
||||||
{{if .IsFachebene}}<a href="/faelle">Posteingang</a>{{end}}
|
<label for="nav-toggle" class="nav-toggle-label" aria-label="Menü öffnen">Menü</label>
|
||||||
{{if .IsFachebene}}<a href="/registereintraege">Register</a>{{end}}
|
<nav class="app-nav">
|
||||||
{{if .IsFachebene}}<a href="/wiedervorlage">Wiedervorlage</a>{{end}}
|
<a href="/">Start</a>
|
||||||
{{if .IsAdmin}}<a href="/verwaltung/nutzer">Nutzerverwaltung</a>{{end}}
|
{{if not .IsBetreiber}}<a href="/antraege">Meine Anträge</a>{{end}}
|
||||||
{{if .IsAdmin}}<a href="/verwaltung/abteilungen">Abteilungen</a>{{end}}
|
{{if .IsFachebene}}<a href="/faelle">Posteingang</a>{{end}}
|
||||||
{{if .IsAdmin}}<a href="/verwaltung/werkzeuge">Werkzeugkatalog</a>{{end}}
|
{{if .IsFachebene}}<a href="/registereintraege">Register</a>{{end}}
|
||||||
{{if .IsBetreiber}}<a href="/betreiber">Plattform</a>{{end}}
|
{{if .IsFachebene}}<a href="/wiedervorlage">Wiedervorlage</a>{{end}}
|
||||||
<form method="post" action="/logout" style="display:inline">
|
{{if .IsAdmin}}<a href="/verwaltung/nutzer">Nutzerverwaltung</a>{{end}}
|
||||||
<button type="submit">Abmelden</button>
|
{{if .IsAdmin}}<a href="/verwaltung/abteilungen">Abteilungen</a>{{end}}
|
||||||
</form>
|
{{if .IsAdmin}}<a href="/verwaltung/werkzeuge">Werkzeugkatalog</a>{{end}}
|
||||||
</nav>
|
{{if .IsBetreiber}}<a href="/betreiber">Plattform</a>{{end}}
|
||||||
|
<form method="post" action="/logout">
|
||||||
|
<button type="submit">Abmelden</button>
|
||||||
|
</form>
|
||||||
|
</nav>
|
||||||
|
</header>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
{{/* bewertung-block rendert eine Bewertung (Datenklasse, KI-VO-
|
{{/* bewertung-block rendert eine Bewertung (Datenklasse, KI-VO-
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
<span class="status status-published">aktiv</span>
|
<span class="status status-published">aktiv</span>
|
||||||
{{if not .IstSelbst}}
|
{{if not .IstSelbst}}
|
||||||
<form method="post" action="/verwaltung/nutzer/{{.ID}}/deaktivieren" style="display:inline">
|
<form method="post" action="/verwaltung/nutzer/{{.ID}}/deaktivieren" style="display:inline">
|
||||||
<button type="submit">Deaktivieren</button>
|
<button type="submit" class="entfernen">Deaktivieren</button>
|
||||||
</form>
|
</form>
|
||||||
{{end}}
|
{{end}}
|
||||||
{{else}}
|
{{else}}
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
{{if not .Eintraege}}
|
{{if not .Eintraege}}
|
||||||
<p class="hinweis">Noch keine Genehmigungen.</p>
|
<p class="hinweis">Noch keine Genehmigungen.</p>
|
||||||
{{else}}
|
{{else}}
|
||||||
|
<div class="table-scroll">
|
||||||
<table>
|
<table>
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
@@ -31,6 +32,7 @@
|
|||||||
{{end}}
|
{{end}}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
Reference in New Issue
Block a user