Dashboard: - Much smaller cards (col-xl-2), compact badges - Short labels (Buero, HO, DND, OoO, etc.) - Optimized for small screens Login: - Password-protected admin pages (all except dashboard) - Dashboard remains public (read-only status view) - Login page with redirect back to requested page - Session cookie (24h, regenerated on restart) - Password set via Settings page (SHA256 hashed) - Sidebar shows only Dashboard when not logged in - Login/Logout link in sidebar footer Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
137 lines
6.5 KiB
HTML
137 lines
6.5 KiB
HTML
{% extends "base.html" %}
|
|
{% block title %}Einstellungen - Busylight{% endblock %}
|
|
|
|
{% block content %}
|
|
<h4 class="mb-4">Einstellungen</h4>
|
|
|
|
{% if request.query_params.get('saved') %}
|
|
<div class="alert alert-success alert-dismissible fade show">
|
|
<i class="bi bi-check-circle"></i> Einstellungen gespeichert.
|
|
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
|
|
</div>
|
|
{% endif %}
|
|
|
|
<form method="post" action="/api/settings">
|
|
<div class="row g-4">
|
|
<!-- Azure AD -->
|
|
<div class="col-lg-6">
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<h6 class="mb-0"><i class="bi bi-microsoft"></i> Azure AD / Microsoft Graph</h6>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="mb-3">
|
|
<label class="form-label">Client ID</label>
|
|
<input type="text" name="azure_client_id" class="form-control font-monospace"
|
|
value="{{ settings.azure_client_id }}">
|
|
</div>
|
|
<div class="mb-3">
|
|
<label class="form-label">Client Secret</label>
|
|
<input type="password" name="azure_client_secret" class="form-control font-monospace"
|
|
value="{{ settings.azure_client_secret }}">
|
|
</div>
|
|
<div class="mb-3">
|
|
<label class="form-label">Tenant ID</label>
|
|
<input type="text" name="azure_tenant_id" class="form-control font-monospace"
|
|
value="{{ settings.azure_tenant_id }}">
|
|
</div>
|
|
<div class="mb-3">
|
|
<label class="form-label">Auth Tenant</label>
|
|
<input type="text" name="azure_auth_tenant" class="form-control"
|
|
value="{{ settings.azure_auth_tenant }}">
|
|
</div>
|
|
<div class="mb-3">
|
|
<label class="form-label">Graph Scopes</label>
|
|
<input type="text" name="azure_scopes" class="form-control"
|
|
value="{{ settings.azure_scopes }}">
|
|
</div>
|
|
<div class="border rounded p-3 bg-light">
|
|
{% if authenticated %}
|
|
<i class="bi bi-check-circle text-success"></i>
|
|
<strong class="text-success">Authentifiziert</strong>
|
|
{% else %}
|
|
<i class="bi bi-x-circle text-danger"></i>
|
|
<strong class="text-danger">Nicht authentifiziert</strong>
|
|
<p class="small text-muted mt-2 mb-0">
|
|
Fuehre auf dem Server aus:<br>
|
|
<code>python app.py --auth</code>
|
|
</p>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Polling & AIDA -->
|
|
<div class="col-lg-6">
|
|
<div class="card mb-4">
|
|
<div class="card-header">
|
|
<h6 class="mb-0"><i class="bi bi-clock"></i> Polling</h6>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="mb-3">
|
|
<label class="form-label">Abfrage-Intervall (Sekunden)</label>
|
|
<input type="number" name="poll_interval" class="form-control"
|
|
value="{{ settings.poll_interval }}" min="5" max="300">
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="card mb-4">
|
|
<div class="card-header">
|
|
<h6 class="mb-0"><i class="bi bi-shield-lock"></i> Zugangsschutz</h6>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="mb-3">
|
|
<label class="form-label">Admin-Passwort</label>
|
|
<input type="password" name="admin_password" class="form-control"
|
|
placeholder="Neues Passwort eingeben (leer = nicht aendern)">
|
|
{% if settings.admin_password %}
|
|
<small class="text-success"><i class="bi bi-check-circle"></i> Passwort ist gesetzt</small>
|
|
{% else %}
|
|
<small class="text-warning"><i class="bi bi-exclamation-triangle"></i> Kein Passwort gesetzt - alle Seiten sind frei zugaenglich</small>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<h6 class="mb-0"><i class="bi bi-file-earmark-spreadsheet"></i> AIDA Zeiterfassung</h6>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="mb-3">
|
|
<label class="form-label">CSV-Pfad</label>
|
|
<input type="text" name="aida_csv_path" class="form-control font-monospace"
|
|
value="{{ settings.aida_csv_path }}"
|
|
placeholder="/mnt/zeiterfassung/Status.csv">
|
|
<small class="text-muted">Auf Linux z.B. via SMB-Mount</small>
|
|
</div>
|
|
<div class="mb-3">
|
|
<label class="form-label">Status: Anwesend</label>
|
|
<input type="text" name="aida_status_anwesend" class="form-control"
|
|
value="{{ settings.aida_status_anwesend }}">
|
|
</div>
|
|
<div class="mb-3">
|
|
<label class="form-label">Status: Abwesend</label>
|
|
<input type="text" name="aida_status_abwesend" class="form-control"
|
|
value="{{ settings.aida_status_abwesend }}">
|
|
</div>
|
|
<div class="mb-3">
|
|
<label class="form-label">Status: Homeoffice</label>
|
|
<input type="text" name="aida_status_homeoffice" class="form-control"
|
|
value="{{ settings.aida_status_homeoffice }}">
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="mt-4">
|
|
<button type="submit" class="btn btn-primary">
|
|
<i class="bi bi-check-lg"></i> Einstellungen speichern
|
|
</button>
|
|
</div>
|
|
</form>
|
|
{% endblock %}
|