Christian Mueller 5267baf0b4 feat: rewrite busylight as FastAPI web application with SQLite
Replace the standalone Python script + config.cfg with a full web
application featuring:
- FastAPI backend with REST API
- SQLite database (config, state, activity log separated)
- Bootstrap 5 web interface for configuration
- Pages: Dashboard, Users, Devices, Assignments, Color Rules, Settings, Log
- APScheduler background polling for Teams presence + AIDA status
- systemd service file for Linux deployment
- Migration script to import existing config.cfg data

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-23 20:46:33 +02:00

95 lines
4.2 KiB
HTML

{% extends "base.html" %}
{% block title %}Benutzer - Busylight{% endblock %}
{% block content %}
<div class="d-flex justify-content-between align-items-center mb-4">
<h4 class="mb-0">Benutzer</h4>
<form method="post" action="/api/users/sync">
<button type="submit" class="btn btn-primary">
<i class="bi bi-cloud-download"></i> Aus Azure synchronisieren
</button>
</form>
</div>
{% if request.query_params.get('synced') %}
<div class="alert alert-success alert-dismissible fade show">
<i class="bi bi-check-circle"></i> {{ request.query_params.get('synced') }} neue Benutzer synchronisiert.
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
</div>
{% endif %}
{% if request.query_params.get('error') == 'not_authenticated' %}
<div class="alert alert-danger alert-dismissible fade show">
<i class="bi bi-x-circle"></i> Azure nicht verbunden. Bitte zuerst authentifizieren.
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
</div>
{% endif %}
<div class="card">
<div class="card-body p-0">
<div class="table-responsive">
<table class="table table-hover mb-0">
<thead>
<tr>
<th>Status</th>
<th>Name</th>
<th>E-Mail</th>
<th>Personal-Nr (AIDA)</th>
<th>Zuordnung</th>
<th>Aktionen</th>
</tr>
</thead>
<tbody>
{% for user in users %}
<tr class="{% if not user.active %}table-light text-muted{% endif %}">
<td>
{% if user.active %}
<span class="badge bg-success">Aktiv</span>
{% else %}
<span class="badge bg-secondary">Inaktiv</span>
{% endif %}
</td>
<td>{{ user.display_name }}</td>
<td><small>{{ user.email or '-' }}</small></td>
<td>
<form method="post" action="/api/users/{{ user.azure_id }}/update" class="d-flex gap-1">
<input type="text" name="personal_nr" value="{{ user.personal_nr or '' }}"
class="form-control form-control-sm" style="width: 120px;"
placeholder="~~00000~~">
<input type="hidden" name="active" value="{{ '1' if user.active else '0' }}">
<button type="submit" class="btn btn-sm btn-outline-secondary">
<i class="bi bi-check"></i>
</button>
</form>
</td>
<td>
{% if user.assignment_id %}
<span class="badge bg-info"><i class="bi bi-link-45deg"></i> Zugeordnet</span>
{% else %}
<span class="text-muted">-</span>
{% endif %}
</td>
<td>
<form method="post" action="/api/users/{{ user.azure_id }}/toggle" class="d-inline">
<button type="submit" class="btn btn-sm {% if user.active %}btn-outline-warning{% else %}btn-outline-success{% endif %}">
{% if user.active %}
<i class="bi bi-pause-circle"></i>
{% else %}
<i class="bi bi-play-circle"></i>
{% endif %}
</button>
</form>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
<div class="mt-3 text-muted">
<small>{{ users|length }} Benutzer insgesamt</small>
</div>
{% endblock %}