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>
184 lines
5.7 KiB
Python
184 lines
5.7 KiB
Python
"""
|
|
School Module - Dashboard Page
|
|
Main school dashboard with stats and quick actions
|
|
"""
|
|
|
|
from ..styles import SCHOOL_BASE_STYLES, DASHBOARD_STYLES
|
|
from ..templates import ICONS, render_base_page, COMMON_SCRIPTS
|
|
|
|
|
|
def school_dashboard() -> str:
|
|
"""Main school dashboard"""
|
|
styles = SCHOOL_BASE_STYLES + DASHBOARD_STYLES
|
|
|
|
content = f'''
|
|
<main class="main-content">
|
|
<div class="page-header">
|
|
<div>
|
|
<h1 class="page-title">Dashboard</h1>
|
|
<p class="page-subtitle">Willkommen zurück! Hier ist die Übersicht für heute.</p>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Stats Grid -->
|
|
<div class="dashboard-grid">
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<span class="card-title">Anwesend heute</span>
|
|
<div class="card-icon accent">
|
|
{ICONS['check_circle']}
|
|
</div>
|
|
</div>
|
|
<div class="stat-value">24/26</div>
|
|
<div class="stat-label">92% Anwesenheitsrate</div>
|
|
</div>
|
|
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<span class="card-title">Offene Entschuldigungen</span>
|
|
<div class="card-icon warning">
|
|
{ICONS['warning']}
|
|
</div>
|
|
</div>
|
|
<div class="stat-value">3</div>
|
|
<div class="stat-label">Warten auf Bestätigung</div>
|
|
</div>
|
|
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<span class="card-title">Ungelesene Nachrichten</span>
|
|
<div class="card-icon info">
|
|
{ICONS['mail']}
|
|
</div>
|
|
</div>
|
|
<div class="stat-value">5</div>
|
|
<div class="stat-label">Neue Elternnachrichten</div>
|
|
</div>
|
|
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<span class="card-title">Nächster Elternsprechtag</span>
|
|
<div class="card-icon primary">
|
|
{ICONS['calendar']}
|
|
</div>
|
|
</div>
|
|
<div class="stat-value">15.01.</div>
|
|
<div class="stat-label">8 Termine gebucht</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Quick Actions -->
|
|
<h3 style="margin-bottom: 1rem; font-weight: 600;">Schnellzugriff</h3>
|
|
<div class="quick-actions">
|
|
<a href="#" class="quick-action" onclick="recordAttendance()">
|
|
<div class="quick-action-icon">
|
|
{ICONS['attendance']}
|
|
</div>
|
|
<span class="quick-action-text">Anwesenheit erfassen</span>
|
|
</a>
|
|
|
|
<a href="#" class="quick-action" onclick="addGrade()">
|
|
<div class="quick-action-icon">
|
|
{ICONS['edit']}
|
|
</div>
|
|
<span class="quick-action-text">Note eintragen</span>
|
|
</a>
|
|
|
|
<a href="#" class="quick-action" onclick="sendMessage()">
|
|
<div class="quick-action-icon">
|
|
{ICONS['messages']}
|
|
</div>
|
|
<span class="quick-action-text">Nachricht senden</span>
|
|
</a>
|
|
|
|
<a href="#" class="quick-action" onclick="generateQRCode()">
|
|
<div class="quick-action-icon">
|
|
{ICONS['qr']}
|
|
</div>
|
|
<span class="quick-action-text">Eltern-QR erstellen</span>
|
|
</a>
|
|
</div>
|
|
|
|
<!-- Recent Activity Table -->
|
|
<div class="table-container">
|
|
<div class="table-header">
|
|
<span class="table-title">Heutige Abwesenheiten</span>
|
|
<button class="btn btn-secondary" onclick="viewAllAbsences()">Alle anzeigen</button>
|
|
</div>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Schüler</th>
|
|
<th>Klasse</th>
|
|
<th>Stunden</th>
|
|
<th>Status</th>
|
|
<th>Aktion</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td>Anna Schmidt</td>
|
|
<td>5a</td>
|
|
<td>1.-4. Stunde</td>
|
|
<td><span class="badge absent">⚠ Unentschuldigt</span></td>
|
|
<td><button class="btn btn-primary" onclick="confirmAbsence('1')">Bestätigen</button></td>
|
|
</tr>
|
|
<tr>
|
|
<td>Ben Müller</td>
|
|
<td>5a</td>
|
|
<td>Ganztägig</td>
|
|
<td><span class="badge pending">⏳ Gemeldet</span></td>
|
|
<td><button class="btn btn-secondary" onclick="confirmAbsence('2')">Prüfen</button></td>
|
|
</tr>
|
|
<tr>
|
|
<td>Clara Weber</td>
|
|
<td>5a</td>
|
|
<td>3. Stunde</td>
|
|
<td><span class="badge late">⏰ Verspätet</span></td>
|
|
<td><button class="btn btn-secondary" onclick="viewDetails('3')">Details</button></td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</main>'''
|
|
|
|
scripts = COMMON_SCRIPTS + '''
|
|
<script>
|
|
function recordAttendance() {
|
|
window.location.href = '/school/attendance';
|
|
}
|
|
|
|
function addGrade() {
|
|
window.location.href = '/school/grades';
|
|
}
|
|
|
|
function sendMessage() {
|
|
alert('Nachrichtenkomponist wird geöffnet...');
|
|
}
|
|
|
|
function generateQRCode() {
|
|
alert('QR-Code Generator wird geöffnet...');
|
|
}
|
|
|
|
function confirmAbsence(id) {
|
|
alert('Abwesenheit ' + id + ' wird bestätigt...');
|
|
}
|
|
|
|
function viewDetails(id) {
|
|
alert('Details für ' + id + ' werden angezeigt...');
|
|
}
|
|
|
|
function viewAllAbsences() {
|
|
window.location.href = '/school/attendance';
|
|
}
|
|
|
|
document.addEventListener('DOMContentLoaded', async () => {
|
|
if (!getAuthToken()) {
|
|
// Redirect to login if not authenticated
|
|
// window.location.href = '/app/login';
|
|
}
|
|
});
|
|
</script>'''
|
|
|
|
return render_base_page("Schulverwaltung", styles, content, scripts, "dashboard")
|