fix: Restore all files lost during destructive rebase

A previous `git pull --rebase origin main` dropped 177 local commits,
losing 3400+ files across admin-v2, backend, studio-v2, website,
klausur-service, and many other services. The partial restore attempt
(660295e2) only recovered some files.

This commit restores all missing files from pre-rebase ref 98933f5e
while preserving post-rebase additions (night-scheduler, night-mode UI,
NightModeWidget dashboard integration).

Restored features include:
- AI Module Sidebar (FAB), OCR Labeling, OCR Compare
- GPU Dashboard, RAG Pipeline, Magic Help
- Klausur-Korrektur (8 files), Abitur-Archiv (5+ files)
- Companion, Zeugnisse-Crawler, Screen Flow
- Full backend, studio-v2, website, klausur-service
- All compliance SDKs, agent-core, voice-service
- CI/CD configs, documentation, scripts

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Benjamin Admin
2026-02-09 09:51:32 +01:00
parent f7487ee240
commit bfdaf63ba9
2009 changed files with 749983 additions and 1731 deletions

View File

@@ -0,0 +1,109 @@
"""
School Management Module - Page Templates.
Enthält Template-Funktionen für Schulverwaltungsseiten.
"""
from .school_styles import get_school_base_styles
SCHOOL_NAV_ITEMS = [
{"id": "dashboard", "label": "Dashboard", "href": "/school"},
{"id": "attendance", "label": "Anwesenheit", "href": "/school/attendance"},
{"id": "grades", "label": "Noten", "href": "/school/grades"},
{"id": "timetable", "label": "Stundenplan", "href": "/school/timetable"},
{"id": "onboarding", "label": "Eltern", "href": "/school/onboarding"},
]
SCHOOL_ICONS = {
"home": '<svg class="nav-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6 0h6"></path></svg>',
"users": '<svg class="nav-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4.354a4 4 0 110 5.292M15 21H3v-1a6 6 0 0112 0v1zm0 0h6v-1a6 6 0 00-9-5.197M13 7a4 4 0 11-8 0 4 4 0 018 0z"></path></svg>',
"calendar": '<svg class="nav-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z"></path></svg>',
"chart": '<svg class="nav-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z"></path></svg>',
"clock": '<svg class="nav-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg>',
"external": '<svg class="nav-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14"></path></svg>',
}
def render_school_sidebar(active_page: str = "dashboard") -> str:
"""Render the school sidebar navigation."""
icon_map = {
"dashboard": "home",
"attendance": "users",
"grades": "chart",
"timetable": "clock",
"onboarding": "calendar",
}
nav_html = ""
for item in SCHOOL_NAV_ITEMS:
active_class = "active" if item["id"] == active_page else ""
icon = SCHOOL_ICONS.get(icon_map.get(item["id"], "home"), "")
nav_html += f'''
<a href="{item['href']}" class="nav-item {active_class}">
{icon}
<span>{item['label']}</span>
</a>
'''
return f'''
<aside class="sidebar">
<div class="logo">
<div class="logo-icon">BP</div>
<span class="logo-text">Schulverwaltung</span>
</div>
<nav class="nav-section">
<div class="nav-section-title">Navigation</div>
{nav_html}
</nav>
<nav class="nav-section" style="margin-top: auto;">
<div class="nav-section-title">Links</div>
<a href="/studio" class="nav-item">
{SCHOOL_ICONS['external']}
<span>Zurück zum Studio</span>
</a>
<a href="/meetings" class="nav-item">
{SCHOOL_ICONS['users']}
<span>Meetings</span>
</a>
</nav>
</aside>
'''
def render_school_base_page(
title: str,
content: str,
active_page: str = "dashboard",
extra_styles: str = "",
extra_scripts: str = ""
) -> str:
"""Render the base page template for school pages."""
return f'''
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<title>BreakPilot {title}</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="https://fonts.googleapis.com/css2?family=Manrope:wght@400;500;600;700&display=swap" rel="stylesheet">
<style>
{get_school_base_styles()}
{extra_styles}
</style>
</head>
<body>
<div class="app-container">
{render_school_sidebar(active_page)}
<main class="main-content">
{content}
</main>
</div>
<script>
{extra_scripts}
</script>
</body>
</html>
'''