modified: web/blueprints/auth.py

modified:   web/blueprints/group_admin.py
	modified:   web/blueprints/panel.py
	modified:   web/blueprints/site_admin.py
	modified:   web/templates/admin/base.html
	modified:   web/templates/admin/dashboard.html
	modified:   web/templates/admin/group_edit.html
	modified:   web/templates/admin/group_members.html
	modified:   web/templates/admin/groups.html
	modified:   web/templates/admin/user_edit.html
	modified:   web/templates/admin/users.html
	modified:   web/templates/auth/admin_login.html
	modified:   web/templates/auth/login.html
	modified:   web/templates/base.html
	modified:   web/templates/group_admin/base.html
	modified:   web/templates/group_admin/dashboard.html
	modified:   web/templates/group_admin/database.html
	modified:   web/templates/group_admin/member_edit.html
	modified:   web/templates/group_admin/members.html
	modified:   web/templates/panel/no_db.html
This commit is contained in:
SimolZimol
2026-04-01 02:55:32 +02:00
parent 93999d1c0d
commit c9c684f97a
21 changed files with 4633 additions and 184 deletions

View File

@@ -1,9 +1,9 @@
<!DOCTYPE html>
<html lang="de" data-bs-theme="dark">
<html lang="en" data-bs-theme="dark">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{% block title %}Gruppen Admin{% endblock %} — {{ session.get('group_name','') }}</title>
<title>{% block title %}Group Admin{% endblock %} — {{ session.get('group_name','') }}</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css">
<link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}">
@@ -16,8 +16,8 @@
</a>
<div class="d-flex align-items-center gap-3">
<a href="{{ url_for('group_admin.dashboard') }}" class="nav-link text-dark {{ 'fw-bold' if request.endpoint == 'group_admin.dashboard' }}">Dashboard</a>
<a href="{{ url_for('group_admin.members') }}" class="nav-link text-dark {{ 'fw-bold' if request.endpoint == 'group_admin.members' }}">Mitglieder</a>
<a href="{{ url_for('group_admin.database') }}" class="nav-link text-dark {{ 'fw-bold' if request.endpoint == 'group_admin.database' }}">Datenbank</a>
<a href="{{ url_for('group_admin.members') }}" class="nav-link text-dark {{ 'fw-bold' if request.endpoint == 'group_admin.members' }}">Members</a>
<a href="{{ url_for('group_admin.database') }}" class="nav-link text-dark {{ 'fw-bold' if request.endpoint == 'group_admin.database' }}">Database</a>
<a href="{{ url_for('panel.dashboard') }}" class="btn btn-outline-dark btn-sm">
<i class="bi bi-grid me-1"></i>Panel
</a>

View File

@@ -1,14 +1,14 @@
{% extends "group_admin/base.html" %}
{% block title %}Dashboard{% endblock %}
{% block content %}
<h2 class="mb-4"><i class="bi bi-gear-fill text-warning me-2"></i>Gruppenadmin: {{ session.get('group_name') }}</h2>
<h2 class="mb-4"><i class="bi bi-gear-fill text-warning me-2"></i>Group Admin: {{ session.get('group_name') }}</h2>
<div class="row g-3 mb-4">
<div class="col-md-3">
<div class="card border-0 bg-secondary bg-opacity-25">
<div class="card-body text-center">
<div class="fs-2 fw-bold text-warning">{{ stats.member_count }}</div>
<div class="text-muted">Mitglieder</div>
<div class="text-muted">Members</div>
</div>
</div>
</div>
@@ -16,9 +16,9 @@
<div class="card border-0 bg-secondary bg-opacity-25">
<div class="card-body text-center">
<div class="fs-2 fw-bold {{ 'text-success' if stats.db_configured else 'text-danger' }}">
{{ 'Ja' if stats.db_configured else 'Nein' }}
{{ 'Yes' if stats.db_configured else 'No' }}
</div>
<div class="text-muted">DB konfiguriert</div>
<div class="text-muted">DB configured</div>
</div>
</div>
</div>
@@ -40,13 +40,13 @@
</div>
<div class="card-body d-flex flex-column gap-2">
<a href="{{ url_for('group_admin.members') }}" class="btn btn-outline-warning">
<i class="bi bi-people-fill me-2"></i>Mitglieder verwalten
<i class="bi bi-people-fill me-2"></i>Manage Members
</a>
<a href="{{ url_for('group_admin.database') }}" class="btn btn-outline-info">
<i class="bi bi-database-fill-gear me-2"></i>Datenbank konfigurieren
<i class="bi bi-database-fill-gear me-2"></i>Configure Database
</a>
<a href="{{ url_for('panel.dashboard') }}" class="btn btn-outline-success">
<i class="bi bi-speedometer2 me-2"></i>Panel öffnen
<i class="bi bi-speedometer2 me-2"></i>Open Panel
</a>
</div>
</div>
@@ -54,19 +54,19 @@
<div class="col-md-6">
<div class="card border-secondary h-100">
<div class="card-header"><i class="bi bi-info-circle me-2"></i>Gruppeninfo</div>
<div class="card-header"><i class="bi bi-info-circle me-2"></i>Group Info</div>
<div class="card-body">
<dl class="row mb-0">
<dt class="col-sm-5">Name</dt>
<dd class="col-sm-7">{{ session.get('group_name') }}</dd>
<dt class="col-sm-5">Deine Rolle</dt>
<dt class="col-sm-5">Your Role</dt>
<dd class="col-sm-7"><span class="badge bg-warning text-dark">Admin</span></dd>
<dt class="col-sm-5">Datenbank</dt>
<dt class="col-sm-5">Database</dt>
<dd class="col-sm-7">
{% if stats.db_configured %}
<span class="text-success"><i class="bi bi-check-circle-fill me-1"></i>Verbunden</span>
<span class="text-success"><i class="bi bi-check-circle-fill me-1"></i>Connected</span>
{% else %}
<span class="text-danger"><i class="bi bi-x-circle-fill me-1"></i>Nicht konfiguriert</span>
<span class="text-danger"><i class="bi bi-x-circle-fill me-1"></i>Not configured</span>
{% endif %}
</dd>
</dl>

View File

@@ -1,19 +1,19 @@
{% extends "group_admin/base.html" %}
{% block title %}Datenbank{% endblock %}
{% block title %}Database{% endblock %}
{% block content %}
<h2 class="mb-4"><i class="bi bi-database-fill-gear me-2"></i>MC Datenbank konfigurieren</h2>
<h2 class="mb-4"><i class="bi bi-database-fill-gear me-2"></i>Configure MC Database</h2>
<div class="row g-3">
<div class="col-md-7">
<div class="card border-secondary">
<div class="card-header">Verbindungsdaten</div>
<div class="card-header">Connection Details</div>
<div class="card-body">
{% if test_result is defined %}
<div class="alert {{ 'alert-success' if test_result else 'alert-danger' }}">
{% if test_result %}
<i class="bi bi-check-circle-fill me-2"></i>Verbindung erfolgreich! Daten wurden gespeichert.
<i class="bi bi-check-circle-fill me-2"></i>Connection successful! Settings saved.
{% else %}
<i class="bi bi-x-circle-fill me-2"></i>Verbindung fehlgeschlagen: {{ test_error }}
<i class="bi bi-x-circle-fill me-2"></i>Connection failed: {{ test_error }}
{% endif %}
</div>
{% endif %}
@@ -32,34 +32,34 @@
value="{{ creds.port if creds else request.form.get('port', '3306') }}">
</div>
<div class="col-12">
<label class="form-label">Datenbank *</label>
<label class="form-label">Database *</label>
<input type="text" name="database" class="form-control" required
placeholder="mclogger"
value="{{ creds.database if creds else request.form.get('database', '') }}">
</div>
<div class="col-md-6">
<label class="form-label">Benutzer *</label>
<label class="form-label">User *</label>
<input type="text" name="user" class="form-control" required
value="{{ creds.user if creds else request.form.get('user', '') }}">
</div>
<div class="col-md-6">
<label class="form-label">Passwort</label>
<label class="form-label">Password</label>
<input type="password" name="password" class="form-control"
placeholder="{{ '(unverändert)' if creds else '' }}">
placeholder="{{ '(unchanged)' if creds else '' }}">
{% if creds %}
<div class="form-text">Leer lassen um das bestehende Passwort beizubehalten.</div>
<div class="form-text">Leave blank to keep the existing password.</div>
{% endif %}
</div>
</div>
<div class="d-flex gap-2 mt-4">
<button type="submit" name="action" value="test_save" class="btn btn-success">
<i class="bi bi-plug-fill me-1"></i>Testen & Speichern
<i class="bi bi-plug-fill me-1"></i>Test & Save
</button>
{% if creds %}
<button type="submit" name="action" value="delete" class="btn btn-outline-danger"
onclick="return confirm('DB-Konfiguration löschen?')">
<i class="bi bi-trash3 me-1"></i>Entfernen
onclick="return confirm('Delete DB configuration?')">
<i class="bi bi-trash3 me-1"></i>Remove
</button>
{% endif %}
</div>
@@ -73,14 +73,14 @@
<div class="card-header"><i class="bi bi-info-circle me-2"></i>Info</div>
<div class="card-body">
<p class="small text-muted">
Gib hier die Verbindungsdaten zu deiner <strong>MCLogger MySQL-Datenbank</strong> ein.
Das Panel liest nur Daten (SELECT) — schreibender Zugriff ist nicht nötig.
Enter the connection details for your <strong>MCLogger MySQL database</strong>.
The panel only reads data (SELECT) — write access is not required.
</p>
<p class="small text-muted">
Die Zugangsdaten werden <strong>verschlüsselt</strong> gespeichert und sind nur für deine Gruppe sichtbar.
Credentials are stored <strong>encrypted</strong> and are only visible to your group.
</p>
<hr>
<p class="small text-muted mb-1"><strong>Benötigte Tabellen:</strong></p>
<p class="small text-muted mb-1"><strong>Required tables:</strong></p>
<ul class="small text-muted">
<li>player_sessions</li>
<li>chat_messages</li>

View File

@@ -1,11 +1,11 @@
{% extends "group_admin/base.html" %}
{% block title %}Berechtigungen {{ member.username }}{% endblock %}
{% block title %}Permissions {{ member.username }}{% endblock %}
{% block content %}
<div class="d-flex align-items-center gap-2 mb-4">
<a href="{{ url_for('group_admin.members') }}" class="btn btn-sm btn-outline-secondary">
<i class="bi bi-arrow-left"></i>
</a>
<h2 class="mb-0">Berechtigungen: <span class="text-warning">{{ member.username }}</span></h2>
<h2 class="mb-0">Permissions: <span class="text-warning">{{ member.username }}</span></h2>
</div>
<div class="row">
@@ -17,16 +17,16 @@
<div class="card-body">
<form method="post">
<div class="mb-3">
<label class="form-label">Rolle</label>
<label class="form-label">Role</label>
<select name="role" class="form-select">
<option value="member" {{ 'selected' if member.role == 'member' }}>Member</option>
<option value="admin" {{ 'selected' if member.role == 'admin' }}>Admin</option>
</select>
<div class="form-text">Admins können Mitglieder und die DB-Verbindung verwalten.</div>
<div class="form-text">Admins can manage members and the DB connection.</div>
</div>
<hr>
<p class="form-label mb-2">Panel-Zugriff</p>
<p class="form-label mb-2">Panel Access</p>
<div class="row g-2">
{% for key, label in all_permissions %}
<div class="col-md-6">
@@ -42,9 +42,9 @@
<div class="d-flex gap-2 mt-4">
<button type="submit" class="btn btn-warning">
<i class="bi bi-check-lg me-1"></i>Speichern
<i class="bi bi-check-lg me-1"></i>Save
</button>
<a href="{{ url_for('group_admin.members') }}" class="btn btn-outline-secondary">Abbrechen</a>
<a href="{{ url_for('group_admin.members') }}" class="btn btn-outline-secondary">Cancel</a>
</div>
</form>
</div>

View File

@@ -1,16 +1,16 @@
{% extends "group_admin/base.html" %}
{% block title %}Mitglieder{% endblock %}
{% block title %}Members{% endblock %}
{% block content %}
<h2 class="mb-4"><i class="bi bi-people-fill me-2"></i>Mitglieder</h2>
<h2 class="mb-4"><i class="bi bi-people-fill me-2"></i>Members</h2>
<div class="row g-3">
<!-- Mitgliederliste -->
<div class="col-md-8">
<div class="card border-secondary">
<div class="card-header">Aktuelle Mitglieder ({{ members|length }})</div>
<div class="card-header">Current Members ({{ members|length }})</div>
<div class="card-body p-0">
<table class="table table-hover mb-0">
<thead><tr><th>Benutzer</th><th>Rolle</th><th class="text-end">Aktionen</th></tr></thead>
<thead><tr><th>User</th><th>Role</th><th class="text-end">Actions</th></tr></thead>
<tbody>
{% for m in members %}
<tr>
@@ -24,22 +24,22 @@
</td>
<td class="text-end">
{% if m.id != session.get('user_id') %}
<a href="{{ url_for('group_admin.member_edit', user_id=m.id) }}" class="btn btn-sm btn-outline-warning" title="Berechtigungen">
<a href="{{ url_for('group_admin.member_edit', user_id=m.id) }}" class="btn btn-sm btn-outline-warning" title="Permissions">
<i class="bi bi-shield-lock"></i>
</a>
<form method="post" action="{{ url_for('group_admin.member_remove', user_id=m.id) }}" class="d-inline"
onsubmit="return confirm('{{ m.username }} entfernen?')">
<button type="submit" class="btn btn-sm btn-outline-danger" title="Entfernen">
onsubmit="return confirm('Remove {{ m.username }}?')">
<button type="submit" class="btn btn-sm btn-outline-danger" title="Remove">
<i class="bi bi-person-dash"></i>
</button>
</form>
{% else %}
<span class="text-muted small">Du</span>
<span class="text-muted small">You</span>
{% endif %}
</td>
</tr>
{% else %}
<tr><td colspan="3" class="text-muted text-center py-3">Keine Mitglieder</td></tr>
<tr><td colspan="3" class="text-muted text-center py-3">No members</td></tr>
{% endfor %}
</tbody>
</table>
@@ -50,13 +50,13 @@
<!-- Benutzer einladen (nur via Benutzername - Site Admin fügt Benutzer hinzu, Gruppen admin kann nur bestehende Mitglieder verwalten) -->
<div class="col-md-4">
<div class="card border-secondary">
<div class="card-header"><i class="bi bi-info-circle me-2"></i>Hinweis</div>
<div class="card-header"><i class="bi bi-info-circle me-2"></i>Note</div>
<div class="card-body">
<p class="text-muted small">
Neue Mitglieder müssen vom <strong>Site Admin</strong> zur Gruppe hinzugefügt werden.
New members must be added by the <strong>Site Admin</strong>.
</p>
<p class="text-muted small">
Als Gruppenadmin kannst du Berechtigungen bestehender Mitglieder verwalten und Mitglieder entfernen.
As group admin you can manage permissions of existing members and remove members.
</p>
</div>
</div>