Files
mindflux/src/main/resources/templates/admin/mindmatch.html
T
AliceDarkest 1bfbd53062 AP6 DSGVO: Footer-Rollout, Datenschutz/Impressum, Datenexport, NeuralTest-Entfernung
- Footer-Fragment (fragments/layout :: footer) ueberall ausgerollt: 24 duplizierte
  Inline-Footer ersetzt, 11 bisher footerlose Seiten (Fehler-/Auth-Seiten + 8
  Spielseiten) ergaenzt -> Rechtslinks von jeder Seite erreichbar. Support/Feedback
  von href="#" auf mailto-Platzhalter umgestellt.
- Datenschutzerklaerung vervollstaendigt: NeuralNet-Messaging als Verarbeitungs-
  taetigkeit (Inhalte, Sender/Empfaenger, Lesebestaetigung, Loeschung via Kaskade),
  E-Mail-Token (SHA-256, 24h) + SMTP ueber mail.sysnaptik.de, konkrete Speicher-
  fristen, korrekte Drittland-/CDN-Aussage.
- Impressum strukturiert: Pflichtfelder nach § 5 DDG (Name, Anschrift, Vertretung,
  Kontakt, MStV) als auffaellige Platzhalter (--warn).
- Datenexport (Art. 20): GET /profile/export -> ProfileExportService sammelt
  Stammdaten, Scores, Achievements und NeuralNet-Daten (ohne Passwort) als
  JSON-Download; drei Repo-Query-Methoden ergaenzt.
- V22-Migration: Demo-User NeuralTest entfernt (NeuralNet-Daten per Kaskade).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WFxcjtc9HNP4VECT6Ur1tE
2026-07-21 00:37:38 +02:00

129 lines
5.7 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="de" data-theme="dark"
xmlns:th="http://www.thymeleaf.org"
xmlns:sec="https://www.thymeleaf.org/thymeleaf-extras-springsecurity6">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>MindMatch-Verwaltung – Admin</title>
<link rel="stylesheet" href="/css/theme.css?v=4">
<script src="/js/theme.js?v=5"></script>
<style>
.mmadmin { max-width: 1000px; margin: 0 auto; padding: 0 1rem; width: 100%; }
.mmadmin .deck {
background: var(--surface);
border: 1px solid var(--border);
border-left: 4px solid var(--accent);
border-radius: 14px;
padding: 1.2rem 1.4rem;
margin-bottom: 1.4rem;
box-shadow: var(--g-soft);
}
.mmadmin .deck.inactive { border-left-color: var(--danger); opacity: 0.75; }
.mmadmin .deck-head {
display: flex; align-items: center; flex-wrap: wrap; gap: 0.6rem;
justify-content: space-between; margin-bottom: 0.8rem;
}
.mmadmin .deck-head h2 { color: var(--heading); margin: 0; font-size: 1.25rem; }
.mmadmin .slug { color: var(--accent); font-size: 0.8rem; font-family: monospace; }
.mmadmin .badge {
font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.06em;
padding: 0.18rem 0.5rem; border-radius: 7px; border: 1px solid var(--border-accent);
}
.mmadmin .badge.on { background: var(--glow-w); color: var(--accent); }
.mmadmin .badge.off { background: rgba(255,95,107,.12); color: var(--danger); border-color: var(--danger); }
.mmadmin .pairs { list-style: none; padding: 0; margin: 0 0 0.8rem; }
.mmadmin .pairs li {
display: flex; align-items: center; gap: 0.6rem; flex-wrap: wrap;
padding: 0.4rem 0; border-bottom: 1px solid var(--border);
}
.mmadmin .pairs .term { color: var(--accent); font-weight: 700; min-width: 130px; }
.mmadmin .pairs .arrow { color: var(--muted); }
.mmadmin .pairs .def { flex: 1; min-width: 160px; color: var(--text); }
.mmadmin form.inline { display: flex; gap: 0.5rem; flex-wrap: wrap; align-items: center; }
.mmadmin .add-pair { margin-top: 0.6rem; }
.mmadmin .new-deck { margin-bottom: 1.6rem; }
.mmadmin .count { color: var(--muted); font-size: 0.85rem; }
.mmadmin .empty { color: var(--muted); }
.mmadmin .empty.warn { color: var(--danger); }
</style>
</head>
<body>
<div class="mf-theme-float"><button class="mf-theme"></button></div>
<div class="mf-container" style="max-width:1040px">
<div class="mf-page-head">
<a th:href="@{/admin}" class="mf-back">⟵ Zurück zum Admin-Dashboard</a>
</div>
<header style="margin-bottom:1.4rem">
<div class="mf-eyebrow">MindMatch</div>
<h1 style="color:var(--heading); font-size:1.75rem; font-weight:800; margin-top:.35rem">🧩 MindMatch-Verwaltung</h1>
</header>
<main class="mmadmin">
<!-- Neues Deck -->
<div class="mf-panel accent new-deck">
<h4>Neue Kategorie (Deck) anlegen</h4>
<form class="inline" th:action="@{/admin/mindmatch/decks}" method="post">
<input class="mf-input" style="width:auto; min-width:240px" type="text" name="title" placeholder="z. B. SQL-Befehle" required>
<button type="submit" class="mf-btn">➕ Deck anlegen</button>
</form>
</div>
<!-- Decks -->
<div class="deck" th:each="deck : ${decks}" th:classappend="${deck.active} ? '' : 'inactive'">
<div class="deck-head">
<div>
<h2 th:text="${deck.title}">Deck</h2>
<span class="slug" th:text="'/' + ${deck.slug}">/slug</span>
<span class="badge on" th:if="${deck.active}">aktiv</span>
<span class="badge off" th:unless="${deck.active}">inaktiv</span>
<span class="count" th:text="'· ' + ${deck.pairs.size()} + ' Paare'">· 0 Paare</span>
</div>
<div style="display:flex; gap:0.5rem;">
<form th:action="@{'/admin/mindmatch/decks/' + ${deck.id} + '/toggle'}" method="post">
<button type="submit" class="mf-btn outline" th:text="${deck.active} ? 'Deaktivieren' : 'Aktivieren'">Toggle</button>
</form>
<form th:action="@{'/admin/mindmatch/decks/' + ${deck.id} + '/delete'}" method="post"
onsubmit="return confirm('Deck inkl. aller Paare löschen?');">
<button type="submit" class="mf-btn danger">Deck löschen</button>
</form>
</div>
</div>
<ul class="pairs">
<li th:each="pair : ${deck.pairs}">
<span class="term" th:text="${pair.term}">Begriff</span>
<span class="arrow">↔</span>
<span class="def" th:text="${pair.matchText}">Bedeutung</span>
<form th:action="@{'/admin/mindmatch/pairs/' + ${pair.id} + '/delete'}" method="post">
<button type="submit" class="mf-btn danger" style="padding:.35rem .7rem">✕</button>
</form>
</li>
<li th:if="${deck.pairs.isEmpty()}" class="empty warn">Noch keine Paare – unten hinzufügen.</li>
</ul>
<!-- Paar hinzufügen -->
<form class="inline add-pair" th:action="@{'/admin/mindmatch/decks/' + ${deck.id} + '/pairs'}" method="post">
<input class="mf-input" style="width:auto; min-width:200px" type="text" name="term" placeholder="Begriff (z. B. SELECT)" required>
<span class="arrow">↔</span>
<input class="mf-input" style="width:auto; min-width:200px" type="text" name="match" placeholder="Bedeutung (z. B. Daten abfragen)" required>
<button type="submit" class="mf-btn outline">➕ Paar hinzufügen</button>
</form>
</div>
<p th:if="${decks.isEmpty()}" class="empty">Noch keine Decks vorhanden. Lege oben das erste an.</p>
</main>
</div>
<footer th:replace="~{fragments/layout :: footer}"></footer>
</body>
</html>