Files
mindflux/src/main/resources/templates/admin/dashboard.html
T
AliceDarkest b88962da6f Dev Lab: server-autoritatives Entwicklerlabor mit 6 Mechaniken + 189 Aufgaben
Dev Lab bündelt mehrere Disziplinen (SQL, Java/Debugging, Git, HTML, CSS, Regex,
PHP, REST) in 11 Spielen mit zusammen 189 Aufgaben. Im Gegensatz zur ersten,
rein clientseitigen Skizze jetzt server-autoritativ, DB-gestützt und im Admin
pflegbar – mit echter Mechanik-Vielfalt statt überall Lückentext:
cloze (Lücke tippen), choice (Multiple Choice), order (Bausteine zusammensetzen),
spot (Bug anklicken), match (Paare zuordnen), regex (Muster schreiben mit
Live-Treffer-Vorschau).

Prüfung und Score ausschließlich serverseitig – die Lösungen verlassen nie das
Backend; Eingabe-Platzhalter sind neutrale Labels (Lösungs-Leak behoben).
Fehler-Mechanik mit Versuchen + Hinweis + Auflösung, kein Game-Over; Score über
die generische game_scores-Tabelle (Kennung devlab, deck=Spiel-Slug).

- Entities DevLabGame/DevLabTask (JSON-payload) + Flyway V8__devlab.sql
- DevLabService mit sechs Mechanik-Checkern; API /api/devlab/** (CSRF-ausgenommen,
  devlab in KNOWN_GAMES)
- Admin /admin/devlab (Spiele + Aufgaben pflegen); polymorphe Frontend-Engine
  devlabgame.js + DB-getriebener Hub devlab.js
- Inhalte aus devlab/content.json (idempotenter Seeder); ersetzt die erste
  clientseitige Dev-Lab-Skizze (devlab.js/devlabgame.js/-game.html/-game.css neu)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-30 16:32:03 +02:00

86 lines
3.2 KiB
HTML

<!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>Mindflux Admin Dashboard</title>
<link rel="stylesheet" href="/css/theme.css">
<script src="/js/theme.js"></script>
<style>
.admin-actions { display:grid; grid-template-columns:repeat(auto-fit,minmax(240px,1fr)); gap:1rem; margin-top:1.1rem; }
.admin-card {
display:flex; align-items:center; gap:.6rem;
background:var(--surface-2); border:1px solid var(--border-accent); border-radius:13px;
padding:1.1rem 1.2rem; color:var(--heading); text-decoration:none; font-weight:700;
box-shadow:var(--g-soft); transition:transform .16s ease, box-shadow .25s ease, background-color .2s;
}
.admin-card:hover { transform:translateY(-3px); background:var(--surface); box-shadow:0 0 18px var(--glow-s); }
.admin-footer { margin-top:2rem; text-align:center; color:var(--muted); font-size:.85rem; }
.admin-footer a { color:var(--accent); text-decoration:none; }
.admin-footer a:hover { text-decoration:underline; }
</style>
</head>
<body>
<div class="mf-theme-float"><button class="mf-theme"></button></div>
<div class="mf-container">
<div class="mf-page-head">
<a th:href="@{/dashboard}" class="mf-back">⟵ Zurück zum Benutzer-Dashboard</a>
</div>
<header style="margin-bottom:1.4rem">
<div class="mf-eyebrow">Control Center</div>
<h1 style="color:var(--heading); font-size:1.85rem; font-weight:800; margin-top:.35rem">✨ Admin-Dashboard ✨</h1>
<p style="color:var(--muted); margin-top:.4rem">Hier steuerst du das System wie Doc den DeLorean!</p>
</header>
<main>
<div class="mf-panel accent">
<h4>Admin Aktionen</h4>
<div class="admin-actions">
<a th:href="@{/admin/users}" class="admin-card">👤 Benutzer verwalten</a>
<a th:href="@{/admin/mindmatch}" class="admin-card">🧩 MindMatch-Decks verwalten</a>
<a th:href="@{/admin/techtacular}" class="admin-card">🎯 TechTacular-Fragen verwalten</a>
<a th:href="@{/admin/syntaxsaga}" class="admin-card">📜 Syntax-Saga-Missionen verwalten</a>
<a th:href="@{/admin/devlab}" class="admin-card">⚗️ Dev-Lab-Aufgaben verwalten</a>
</div>
<p style="margin-top:1.1rem; color:var(--muted);">
Hier entsteht noch Großes... ✨ Bleib dran!
</p>
</div>
</main>
<footer class="mf-footer">
<a href="#">Support</a>
<a href="#">Feedback</a>
<a href="/nutzungsbedingungen">Nutzungsbedingungen</a>
<a href="/richtlinien">Richtlinien</a>
<a href="/datenschutz">Datenschutz</a>
<a href="/impressum">Impressum</a>
</footer>
</div>
<script>
window.addEventListener('DOMContentLoaded', () => {
const successMessage = document.getElementById('successMessage');
if (successMessage) {
setTimeout(() => {
successMessage.style.opacity = '0';
setTimeout(() => {
successMessage.style.display = 'none';
}, 1500);
}, 3000);
}
});
</script>
</body>
</html>