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:
@@ -17,17 +17,17 @@ def login():
|
||||
if request.method == "POST":
|
||||
user = check_login(request.form.get("username", ""), request.form.get("password", ""))
|
||||
if user and user["is_site_admin"]:
|
||||
flash("Bitte nutze den Site-Admin-Login.", "warning")
|
||||
flash("Please use the Site Admin login.", "warning")
|
||||
return redirect(url_for("auth.admin_login"))
|
||||
if user:
|
||||
groups = get_user_groups(user["id"])
|
||||
if not groups:
|
||||
error = "Du bist keiner Gruppe zugewiesen. Wende dich an einen Admin."
|
||||
error = "You are not assigned to any group. Please contact an admin."
|
||||
else:
|
||||
_set_user_session(user, groups)
|
||||
return redirect(url_for("panel.dashboard"))
|
||||
else:
|
||||
error = "Falscher Benutzername oder Passwort."
|
||||
error = "Incorrect username or password."
|
||||
return render_template("auth/login.html", error=error)
|
||||
|
||||
|
||||
@@ -46,9 +46,9 @@ def admin_login():
|
||||
session["permissions"] = {}
|
||||
return redirect(url_for("site_admin.dashboard"))
|
||||
elif user:
|
||||
error = "Keine Site-Admin-Berechtigung."
|
||||
error = "No Site Admin privileges."
|
||||
else:
|
||||
error = "Falscher Benutzername oder Passwort."
|
||||
error = "Incorrect username or password."
|
||||
return render_template("auth/admin_login.html", error=error)
|
||||
|
||||
|
||||
@@ -66,7 +66,7 @@ def switch_group(group_id):
|
||||
groups = get_user_groups(user_id)
|
||||
target = next((g for g in groups if g["id"] == group_id), None)
|
||||
if not target:
|
||||
flash("Gruppe nicht gefunden oder kein Zugriff.", "danger")
|
||||
flash("Group not found or no access.", "danger")
|
||||
return redirect(url_for("panel.dashboard"))
|
||||
_apply_group(target)
|
||||
return redirect(url_for("panel.dashboard"))
|
||||
|
||||
@@ -11,15 +11,15 @@ group_admin = Blueprint("group_admin", __name__, url_prefix="/group-admin")
|
||||
|
||||
ALL_PERMISSIONS = [
|
||||
("view_dashboard", "Dashboard"),
|
||||
("view_players", "Spieler"),
|
||||
("view_players", "Players"),
|
||||
("view_sessions", "Sessions"),
|
||||
("view_chat", "Chat"),
|
||||
("view_commands", "Commands"),
|
||||
("view_deaths", "Tode"),
|
||||
("view_blocks", "Block-Events"),
|
||||
("view_proxy", "Proxy-Events"),
|
||||
("view_server_events", "Server-Events"),
|
||||
("view_perms", "Berechtigungen"),
|
||||
("view_deaths", "Deaths"),
|
||||
("view_blocks", "Block Events"),
|
||||
("view_proxy", "Proxy Events"),
|
||||
("view_server_events", "Server Events"),
|
||||
("view_perms", "Permissions"),
|
||||
]
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ def group_admin_required(f):
|
||||
if session.get("is_site_admin"):
|
||||
return redirect(url_for("site_admin.dashboard"))
|
||||
if session.get("role") != "admin":
|
||||
flash("Du hast keine Gruppen-Admin-Berechtigung.", "danger")
|
||||
flash("You do not have group admin permission.", "danger")
|
||||
return redirect(url_for("panel.dashboard"))
|
||||
return f(*args, **kwargs)
|
||||
return decorated
|
||||
@@ -74,7 +74,7 @@ def member_add():
|
||||
role = request.form.get("role", "member")
|
||||
if user_id:
|
||||
db.add_group_member(user_id, group_id, role)
|
||||
flash("Mitglied hinzugefügt.", "success")
|
||||
flash("Member added.", "success")
|
||||
return redirect(url_for("group_admin.members"))
|
||||
|
||||
|
||||
@@ -86,7 +86,7 @@ def member_edit(user_id):
|
||||
member = db.get_group_member(user_id, group_id)
|
||||
user = db.get_user_by_id(user_id)
|
||||
if not member or not user:
|
||||
flash("Mitglied nicht gefunden.", "danger")
|
||||
flash("Member not found.", "danger")
|
||||
return redirect(url_for("group_admin.members"))
|
||||
|
||||
raw_perms = member.get("permissions")
|
||||
@@ -96,7 +96,7 @@ def member_edit(user_id):
|
||||
role = request.form.get("role", "member")
|
||||
new_perms = {key: (request.form.get(key) == "1") for key, _ in ALL_PERMISSIONS}
|
||||
db.update_member(user_id, group_id, role, new_perms)
|
||||
flash("Berechtigungen aktualisiert.", "success")
|
||||
flash("Permissions updated.", "success")
|
||||
return redirect(url_for("group_admin.members"))
|
||||
|
||||
return render_template("group_admin/member_edit.html",
|
||||
@@ -108,10 +108,10 @@ def member_edit(user_id):
|
||||
@group_admin_required
|
||||
def member_remove(user_id):
|
||||
if user_id == session["user_id"]:
|
||||
flash("Du kannst dich nicht selbst entfernen.", "danger")
|
||||
flash("You cannot remove yourself.", "danger")
|
||||
else:
|
||||
db.remove_group_member(user_id, session["group_id"])
|
||||
flash("Mitglied entfernt.", "success")
|
||||
flash("Member removed.", "success")
|
||||
return redirect(url_for("group_admin.members"))
|
||||
|
||||
|
||||
@@ -135,7 +135,7 @@ def database():
|
||||
database_name = request.form.get("database", "").strip()
|
||||
|
||||
if not all([host, port, user, database_name]):
|
||||
error = "Host, Port, Benutzer und Datenbankname sind Pflichtfelder."
|
||||
error = "Host, Port, User and Database name are required."
|
||||
else:
|
||||
try:
|
||||
# Verbindung testen
|
||||
@@ -147,7 +147,7 @@ def database():
|
||||
)
|
||||
test.close()
|
||||
db.set_group_db_creds(group_id, host, int(port), user, password, database_name)
|
||||
flash("Datenbankverbindung gespeichert und getestet ✓", "success")
|
||||
flash("Database connection saved and tested ✓", "success")
|
||||
return redirect(url_for("group_admin.database"))
|
||||
except Exception as e:
|
||||
error = f"Verbindungstest fehlgeschlagen: {e}"
|
||||
@@ -160,5 +160,5 @@ def database():
|
||||
@group_admin_required
|
||||
def database_delete():
|
||||
db.delete_group_db_creds(session["group_id"])
|
||||
flash("Datenbankverbindung entfernt.", "success")
|
||||
flash("Database connection removed.", "success")
|
||||
return redirect(url_for("group_admin.database"))
|
||||
|
||||
@@ -38,7 +38,7 @@ def perm_required(perm):
|
||||
return f(*args, **kwargs)
|
||||
perms = session.get("permissions", {})
|
||||
if not perms.get(perm, False):
|
||||
flash("Du hast keine Berechtigung, diese Seite zu sehen.", "danger")
|
||||
flash("You do not have permission to view this page.", "danger")
|
||||
return redirect(url_for("panel.dashboard"))
|
||||
return f(*args, **kwargs)
|
||||
return wrapped
|
||||
@@ -139,7 +139,7 @@ def dashboard():
|
||||
ORDER BY timestamp DESC LIMIT 20
|
||||
""")
|
||||
except Exception as e:
|
||||
flash(f"Datenbankfehler: {e}", "danger")
|
||||
flash(f"Database error: {e}", "danger")
|
||||
return render_template("panel/no_db.html")
|
||||
|
||||
return render_template("panel/dashboard.html",
|
||||
@@ -176,7 +176,7 @@ def players():
|
||||
def player_detail(uuid):
|
||||
player = query("SELECT * FROM players WHERE uuid = %s", (uuid,), fetchone=True)
|
||||
if not player:
|
||||
flash("Spieler nicht gefunden.", "danger")
|
||||
flash("Player not found.", "danger")
|
||||
return redirect(url_for("panel.players"))
|
||||
perms = session.get("permissions", {})
|
||||
is_admin = session.get("is_site_admin") or session.get("role") == "admin"
|
||||
|
||||
@@ -64,12 +64,12 @@ def group_new():
|
||||
name = request.form.get("name", "").strip()
|
||||
desc = request.form.get("description", "").strip()
|
||||
if not name:
|
||||
flash("Gruppenname darf nicht leer sein.", "danger")
|
||||
flash("Group name must not be empty.", "danger")
|
||||
elif db.get_group_by_name(name):
|
||||
flash("Eine Gruppe mit diesem Namen existiert bereits.", "danger")
|
||||
flash("A group with that name already exists.", "danger")
|
||||
else:
|
||||
db.create_group(name, desc)
|
||||
flash(f"Gruppe '{name}' erstellt.", "success")
|
||||
flash(f"Group '{name}' created.", "success")
|
||||
return redirect(url_for("site_admin.groups"))
|
||||
return render_template("admin/group_edit.html", group=None)
|
||||
|
||||
@@ -79,16 +79,16 @@ def group_new():
|
||||
def group_edit(group_id):
|
||||
group = db.get_group_by_id(group_id)
|
||||
if not group:
|
||||
flash("Gruppe nicht gefunden.", "danger")
|
||||
flash("Group not found.", "danger")
|
||||
return redirect(url_for("site_admin.groups"))
|
||||
if request.method == "POST":
|
||||
name = request.form.get("name", "").strip()
|
||||
desc = request.form.get("description", "").strip()
|
||||
if not name:
|
||||
flash("Gruppenname darf nicht leer sein.", "danger")
|
||||
flash("Group name must not be empty.", "danger")
|
||||
else:
|
||||
db.update_group(group_id, name, desc)
|
||||
flash("Gruppe aktualisiert.", "success")
|
||||
flash("Group updated.", "success")
|
||||
return redirect(url_for("site_admin.groups"))
|
||||
return render_template("admin/group_edit.html", group=group)
|
||||
|
||||
@@ -97,7 +97,7 @@ def group_edit(group_id):
|
||||
@admin_required
|
||||
def group_delete(group_id):
|
||||
db.delete_group(group_id)
|
||||
flash("Gruppe gelöscht.", "success")
|
||||
flash("Group deleted.", "success")
|
||||
return redirect(url_for("site_admin.groups"))
|
||||
|
||||
|
||||
@@ -120,7 +120,7 @@ def group_member_add(group_id):
|
||||
role = request.form.get("role", "member")
|
||||
if user_id:
|
||||
db.add_group_member(user_id, group_id, role)
|
||||
flash("Mitglied hinzugefügt.", "success")
|
||||
flash("Member added.", "success")
|
||||
return redirect(url_for("site_admin.group_members", group_id=group_id))
|
||||
|
||||
|
||||
@@ -128,7 +128,7 @@ def group_member_add(group_id):
|
||||
@admin_required
|
||||
def group_member_remove(group_id, user_id):
|
||||
db.remove_group_member(user_id, group_id)
|
||||
flash("Mitglied entfernt.", "success")
|
||||
flash("Member removed.", "success")
|
||||
return redirect(url_for("site_admin.group_members", group_id=group_id))
|
||||
|
||||
|
||||
@@ -141,7 +141,7 @@ def group_member_toggle_role(group_id, user_id):
|
||||
new_role = "member" if member["role"] == "admin" else "admin"
|
||||
perms = member["permissions"] if isinstance(member["permissions"], dict) else (_json.loads(member["permissions"]) if member["permissions"] else {})
|
||||
db.update_member(user_id, group_id, new_role, perms)
|
||||
flash(f"Rolle auf '{new_role}' geändert.", "success")
|
||||
flash(f"Role changed to '{new_role}'.", "success")
|
||||
return redirect(url_for("site_admin.group_members", group_id=group_id))
|
||||
|
||||
|
||||
@@ -164,12 +164,12 @@ def user_new():
|
||||
password = request.form.get("password", "")
|
||||
is_site_admin = request.form.get("is_site_admin") == "1"
|
||||
if not username or not email or not password:
|
||||
flash("Alle Felder sind Pflichtfelder.", "danger")
|
||||
flash("All fields are required.", "danger")
|
||||
elif db.get_user_by_username(username):
|
||||
flash("Benutzername bereits vergeben.", "danger")
|
||||
flash("Username already taken.", "danger")
|
||||
else:
|
||||
db.create_user(username, email, password, is_site_admin)
|
||||
flash(f"Nutzer '{username}' erstellt.", "success")
|
||||
flash(f"User '{username}' created.", "success")
|
||||
return redirect(url_for("site_admin.users"))
|
||||
return render_template("admin/user_edit.html", user=None)
|
||||
|
||||
@@ -179,7 +179,7 @@ def user_new():
|
||||
def user_edit(user_id):
|
||||
user = db.get_user_by_id(user_id)
|
||||
if not user:
|
||||
flash("Nutzer nicht gefunden.", "danger")
|
||||
flash("User not found.", "danger")
|
||||
return redirect(url_for("site_admin.users"))
|
||||
if request.method == "POST":
|
||||
username = request.form.get("username", "").strip()
|
||||
@@ -189,8 +189,8 @@ def user_edit(user_id):
|
||||
db.update_user(user_id, username, email, is_site_admin)
|
||||
if new_password:
|
||||
db.change_password(user_id, new_password)
|
||||
flash("Passwort geändert.", "info")
|
||||
flash("Nutzer aktualisiert.", "success")
|
||||
flash("Password changed.", "info")
|
||||
flash("User updated.", "success")
|
||||
return redirect(url_for("site_admin.users"))
|
||||
return render_template("admin/user_edit.html", user=user)
|
||||
|
||||
@@ -199,10 +199,10 @@ def user_edit(user_id):
|
||||
@admin_required
|
||||
def user_delete(user_id):
|
||||
if user_id == session.get("user_id"):
|
||||
flash("Du kannst dich nicht selbst löschen.", "danger")
|
||||
flash("You cannot delete yourself.", "danger")
|
||||
else:
|
||||
db.delete_user(user_id)
|
||||
flash("Nutzer gelöscht.", "success")
|
||||
flash("User deleted.", "success")
|
||||
return redirect(url_for("site_admin.users"))
|
||||
|
||||
|
||||
@@ -213,13 +213,13 @@ def user_delete(user_id):
|
||||
@site_admin.route("/view-group/<int:group_id>")
|
||||
@admin_required
|
||||
def view_group(group_id):
|
||||
"""Site-Admin wechselt temporär in eine Gruppe, um deren MC-Daten zu sehen."""
|
||||
"""Site Admin temporarily switches into a group to view its MC data."""
|
||||
group = db.get_group_by_id(group_id)
|
||||
if not group:
|
||||
flash("Gruppe nicht gefunden.", "danger")
|
||||
flash("Group not found.", "danger")
|
||||
return redirect(url_for("site_admin.dashboard"))
|
||||
if not db.has_db_configured(group_id):
|
||||
flash("Für diese Gruppe ist noch keine Datenbank konfiguriert.", "warning")
|
||||
flash("No database configured for this group.", "warning")
|
||||
return redirect(url_for("site_admin.dashboard"))
|
||||
# Alle Berechtigungen als Admin
|
||||
all_perms = {k: True for k in ["view_dashboard","view_players","view_sessions",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<!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">
|
||||
@@ -16,8 +16,8 @@
|
||||
</a>
|
||||
<div class="d-flex align-items-center gap-3">
|
||||
<a href="{{ url_for('site_admin.dashboard') }}" class="nav-link text-white {{ 'fw-bold' if request.endpoint == 'site_admin.dashboard' }}">Dashboard</a>
|
||||
<a href="{{ url_for('site_admin.groups') }}" class="nav-link text-white {{ 'fw-bold' if request.endpoint == 'site_admin.groups' }}">Gruppen</a>
|
||||
<a href="{{ url_for('site_admin.users') }}" class="nav-link text-white {{ 'fw-bold' if request.endpoint == 'site_admin.users' }}">Benutzer</a>
|
||||
<a href="{{ url_for('site_admin.groups') }}" class="nav-link text-white {{ 'fw-bold' if request.endpoint == 'site_admin.groups' }}">Groups</a>
|
||||
<a href="{{ url_for('site_admin.users') }}" class="nav-link text-white {{ 'fw-bold' if request.endpoint == 'site_admin.users' }}">Users</a>
|
||||
<a href="{{ url_for('auth.logout') }}" class="btn btn-outline-light btn-sm">
|
||||
<i class="bi bi-box-arrow-right"></i> Logout
|
||||
</a>
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
<div class="card border-0 bg-secondary bg-opacity-25">
|
||||
<div class="card-body text-center">
|
||||
<div class="fs-2 fw-bold text-danger">{{ stats.group_count }}</div>
|
||||
<div class="text-muted">Gruppen</div>
|
||||
<div class="text-muted">Groups</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -16,7 +16,7 @@
|
||||
<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.user_count }}</div>
|
||||
<div class="text-muted">Benutzer</div>
|
||||
<div class="text-muted">Users</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -24,7 +24,7 @@
|
||||
<div class="card border-0 bg-secondary bg-opacity-25">
|
||||
<div class="card-body text-center">
|
||||
<div class="fs-2 fw-bold text-success">{{ stats.db_configured }}</div>
|
||||
<div class="text-muted">DBs konfiguriert</div>
|
||||
<div class="text-muted">DBs configured</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -42,14 +42,14 @@
|
||||
<div class="col-md-6">
|
||||
<div class="card border-secondary">
|
||||
<div class="card-header d-flex justify-content-between align-items-center">
|
||||
<span><i class="bi bi-collection-fill me-2"></i>Gruppen</span>
|
||||
<span><i class="bi bi-collection-fill me-2"></i>Groups</span>
|
||||
<a href="{{ url_for('site_admin.group_new') }}" class="btn btn-sm btn-success">
|
||||
<i class="bi bi-plus-lg"></i> Neu
|
||||
<i class="bi bi-plus-lg"></i> New
|
||||
</a>
|
||||
</div>
|
||||
<div class="card-body p-0">
|
||||
<table class="table table-hover mb-0">
|
||||
<thead><tr><th>Name</th><th>Mitglieder</th><th>DB</th><th></th></tr></thead>
|
||||
<thead><tr><th>Name</th><th>Members</th><th>DB</th><th></th></tr></thead>
|
||||
<tbody>
|
||||
{% for g in groups %}
|
||||
<tr>
|
||||
@@ -57,28 +57,28 @@
|
||||
<td>{{ g.member_count }}</td>
|
||||
<td>
|
||||
{% if g.has_db %}
|
||||
<span class="badge bg-success">Konfiguriert</span>
|
||||
<span class="badge bg-success">Configured</span>
|
||||
{% else %}
|
||||
<span class="badge bg-secondary">Keine</span>
|
||||
<span class="badge bg-secondary">None</span>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td class="text-end">
|
||||
<a href="{{ url_for('site_admin.view_group', group_id=g.id) }}" class="btn btn-sm btn-outline-info" title="Browse">
|
||||
<i class="bi bi-eye"></i>
|
||||
</a>
|
||||
<a href="{{ url_for('site_admin.group_edit', group_id=g.id) }}" class="btn btn-sm btn-outline-secondary" title="Bearbeiten">
|
||||
<a href="{{ url_for('site_admin.group_edit', group_id=g.id) }}" class="btn btn-sm btn-outline-secondary" title="Edit">
|
||||
<i class="bi bi-pencil"></i>
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
{% else %}
|
||||
<tr><td colspan="4" class="text-muted text-center py-3">Keine Gruppen vorhanden</td></tr>
|
||||
<tr><td colspan="4" class="text-muted text-center py-3">No groups yet</td></tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="card-footer text-end">
|
||||
<a href="{{ url_for('site_admin.groups') }}" class="text-muted small">Alle Gruppen →</a>
|
||||
<a href="{{ url_for('site_admin.groups') }}" class="text-muted small">All groups →</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -86,14 +86,14 @@
|
||||
<div class="col-md-6">
|
||||
<div class="card border-secondary">
|
||||
<div class="card-header d-flex justify-content-between align-items-center">
|
||||
<span><i class="bi bi-people-fill me-2"></i>Benutzer</span>
|
||||
<span><i class="bi bi-people-fill me-2"></i>Users</span>
|
||||
<a href="{{ url_for('site_admin.user_new') }}" class="btn btn-sm btn-success">
|
||||
<i class="bi bi-plus-lg"></i> Neu
|
||||
<i class="bi bi-plus-lg"></i> New
|
||||
</a>
|
||||
</div>
|
||||
<div class="card-body p-0">
|
||||
<table class="table table-hover mb-0">
|
||||
<thead><tr><th>Benutzer</th><th>Gruppen</th><th>Admin</th><th></th></tr></thead>
|
||||
<thead><tr><th>User</th><th>Groups</th><th>Admin</th><th></th></tr></thead>
|
||||
<tbody>
|
||||
{% for u in users %}
|
||||
<tr>
|
||||
@@ -101,19 +101,19 @@
|
||||
<td>{{ u.group_count }}</td>
|
||||
<td>{% if u.is_site_admin %}<span class="badge bg-danger"><i class="bi bi-shield-fill"></i></span>{% endif %}</td>
|
||||
<td class="text-end">
|
||||
<a href="{{ url_for('site_admin.user_edit', user_id=u.id) }}" class="btn btn-sm btn-outline-secondary" title="Bearbeiten">
|
||||
<a href="{{ url_for('site_admin.user_edit', user_id=u.id) }}" class="btn btn-sm btn-outline-secondary" title="Edit">
|
||||
<i class="bi bi-pencil"></i>
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
{% else %}
|
||||
<tr><td colspan="4" class="text-muted text-center py-3">Keine Benutzer vorhanden</td></tr>
|
||||
<tr><td colspan="4" class="text-muted text-center py-3">No users yet</td></tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="card-footer text-end">
|
||||
<a href="{{ url_for('site_admin.users') }}" class="text-muted small">Alle Benutzer →</a>
|
||||
<a href="{{ url_for('site_admin.users') }}" class="text-muted small">All users →</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
{% extends "admin/base.html" %}
|
||||
{% block title %}{{ 'Gruppe bearbeiten' if group else 'Neue Gruppe' }}{% endblock %}
|
||||
{% block title %}{{ 'Edit Group' if group else 'New Group' }}{% endblock %}
|
||||
{% block content %}
|
||||
<div class="d-flex align-items-center gap-2 mb-4">
|
||||
<a href="{{ url_for('site_admin.groups') }}" class="btn btn-sm btn-outline-secondary">
|
||||
<i class="bi bi-arrow-left"></i>
|
||||
</a>
|
||||
<h2 class="mb-0">{{ 'Gruppe bearbeiten' if group else 'Neue Gruppe erstellen' }}</h2>
|
||||
<h2 class="mb-0">{{ 'Edit Group' if group else 'Create New Group' }}</h2>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
@@ -14,19 +14,19 @@
|
||||
<div class="card-body">
|
||||
<form method="post">
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Gruppenname *</label>
|
||||
<label class="form-label">Group Name *</label>
|
||||
<input type="text" name="name" class="form-control" required
|
||||
value="{{ group.name if group else request.form.get('name', '') }}">
|
||||
</div>
|
||||
<div class="mb-4">
|
||||
<label class="form-label">Beschreibung</label>
|
||||
<label class="form-label">Description</label>
|
||||
<textarea name="description" class="form-control" rows="3">{{ group.description if group else request.form.get('description', '') }}</textarea>
|
||||
</div>
|
||||
<div class="d-flex gap-2">
|
||||
<button type="submit" class="btn btn-success">
|
||||
<i class="bi bi-check-lg me-1"></i>{{ 'Speichern' if group else 'Erstellen' }}
|
||||
<i class="bi bi-check-lg me-1"></i>{{ 'Save' if group else 'Create' }}
|
||||
</button>
|
||||
<a href="{{ url_for('site_admin.groups') }}" class="btn btn-outline-secondary">Abbrechen</a>
|
||||
<a href="{{ url_for('site_admin.groups') }}" class="btn btn-outline-secondary">Cancel</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
@@ -1,21 +1,21 @@
|
||||
{% extends "admin/base.html" %}
|
||||
{% block title %}Mitglieder – {{ group.name }}{% endblock %}
|
||||
{% block title %}Members – {{ group.name }}{% endblock %}
|
||||
{% block content %}
|
||||
<div class="d-flex align-items-center gap-2 mb-4">
|
||||
<a href="{{ url_for('site_admin.groups') }}" class="btn btn-sm btn-outline-secondary">
|
||||
<i class="bi bi-arrow-left"></i>
|
||||
</a>
|
||||
<h2 class="mb-0">Mitglieder: <span class="text-success">{{ group.name }}</span></h2>
|
||||
<h2 class="mb-0">Members: <span class="text-success">{{ group.name }}</span></h2>
|
||||
</div>
|
||||
|
||||
<div class="row g-3">
|
||||
<!-- Aktuelle Mitglieder -->
|
||||
<div class="col-md-7">
|
||||
<div class="card border-secondary">
|
||||
<div class="card-header"><i class="bi bi-people-fill me-2"></i>Aktuelle Mitglieder ({{ members|length }})</div>
|
||||
<div class="card-header"><i class="bi bi-people-fill me-2"></i>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>
|
||||
@@ -29,20 +29,20 @@
|
||||
</td>
|
||||
<td class="text-end">
|
||||
<form method="post" action="{{ url_for('site_admin.group_member_toggle_role', group_id=group.id, user_id=m.id) }}" class="d-inline">
|
||||
<button type="submit" class="btn btn-sm btn-outline-warning" title="Rolle wechseln">
|
||||
<button type="submit" class="btn btn-sm btn-outline-warning" title="Toggle role">
|
||||
<i class="bi bi-arrow-left-right"></i>
|
||||
</button>
|
||||
</form>
|
||||
<form method="post" action="{{ url_for('site_admin.group_member_remove', group_id=group.id, user_id=m.id) }}" class="d-inline"
|
||||
onsubmit="return confirm('{{ m.username }} aus Gruppe entfernen?')">
|
||||
<button type="submit" class="btn btn-sm btn-outline-danger" title="Entfernen">
|
||||
onsubmit="return confirm('Remove {{ m.username }} from group?')">
|
||||
<button type="submit" class="btn btn-sm btn-outline-danger" title="Remove">
|
||||
<i class="bi bi-person-dash"></i>
|
||||
</button>
|
||||
</form>
|
||||
</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>
|
||||
@@ -53,12 +53,12 @@
|
||||
<!-- Benutzer hinzufügen -->
|
||||
<div class="col-md-5">
|
||||
<div class="card border-secondary">
|
||||
<div class="card-header"><i class="bi bi-person-plus-fill me-2"></i>Benutzer hinzufügen</div>
|
||||
<div class="card-header"><i class="bi bi-person-plus-fill me-2"></i>Add User</div>
|
||||
<div class="card-body">
|
||||
{% if non_members %}
|
||||
<form method="post" action="{{ url_for('site_admin.group_member_add', group_id=group.id) }}">
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Benutzer auswählen</label>
|
||||
<label class="form-label">Select User</label>
|
||||
<select name="user_id" class="form-select">
|
||||
{% for u in non_members %}
|
||||
<option value="{{ u.id }}">{{ u.username }}</option>
|
||||
@@ -66,18 +66,18 @@
|
||||
</select>
|
||||
</div>
|
||||
<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">Member</option>
|
||||
<option value="admin">Admin</option>
|
||||
</select>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-success w-100">
|
||||
<i class="bi bi-person-plus-fill me-1"></i>Hinzufügen
|
||||
<i class="bi bi-person-plus-fill me-1"></i>Add
|
||||
</button>
|
||||
</form>
|
||||
{% else %}
|
||||
<p class="text-muted text-center py-3">Alle Benutzer sind bereits Mitglied.</p>
|
||||
<p class="text-muted text-center py-3">All users are already members.</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
{% extends "admin/base.html" %}
|
||||
{% block title %}Gruppen{% endblock %}
|
||||
{% block title %}Groups{% endblock %}
|
||||
{% block content %}
|
||||
<div class="d-flex justify-content-between align-items-center mb-4">
|
||||
<h2><i class="bi bi-collection-fill me-2"></i>Gruppen</h2>
|
||||
<h2><i class="bi bi-collection-fill me-2"></i>Groups</h2>
|
||||
<a href="{{ url_for('site_admin.group_new') }}" class="btn btn-success">
|
||||
<i class="bi bi-plus-lg me-1"></i>Neue Gruppe
|
||||
<i class="bi bi-plus-lg me-1"></i>New Group
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
<table class="table table-hover mb-0">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ID</th><th>Name</th><th>Beschreibung</th><th>Mitglieder</th><th>DB</th><th>Erstellt</th><th class="text-end">Aktionen</th>
|
||||
<th>ID</th><th>Name</th><th>Description</th><th>Members</th><th>DB</th><th>Created</th><th class="text-end">Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@@ -25,32 +25,32 @@
|
||||
<td>{{ g.member_count }}</td>
|
||||
<td>
|
||||
{% if g.has_db %}
|
||||
<span class="badge bg-success"><i class="bi bi-database-fill-check me-1"></i>Konfiguriert</span>
|
||||
<span class="badge bg-success"><i class="bi bi-database-fill-check me-1"></i>Configured</span>
|
||||
{% else %}
|
||||
<span class="badge bg-secondary">Keine DB</span>
|
||||
<span class="badge bg-secondary">No DB</span>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td class="text-muted small">{{ g.created_at | fmt_dt }}</td>
|
||||
<td class="text-end">
|
||||
<a href="{{ url_for('site_admin.view_group', group_id=g.id) }}" class="btn btn-sm btn-outline-info" title="Daten browsen">
|
||||
<a href="{{ url_for('site_admin.view_group', group_id=g.id) }}" class="btn btn-sm btn-outline-info" title="Browse data">
|
||||
<i class="bi bi-eye"></i>
|
||||
</a>
|
||||
<a href="{{ url_for('site_admin.group_members', group_id=g.id) }}" class="btn btn-sm btn-outline-secondary" title="Mitglieder">
|
||||
<a href="{{ url_for('site_admin.group_members', group_id=g.id) }}" class="btn btn-sm btn-outline-secondary" title="Members">
|
||||
<i class="bi bi-people-fill"></i>
|
||||
</a>
|
||||
<a href="{{ url_for('site_admin.group_edit', group_id=g.id) }}" class="btn btn-sm btn-outline-warning" title="Bearbeiten">
|
||||
<a href="{{ url_for('site_admin.group_edit', group_id=g.id) }}" class="btn btn-sm btn-outline-warning" title="Edit">
|
||||
<i class="bi bi-pencil"></i>
|
||||
</a>
|
||||
<form method="post" action="{{ url_for('site_admin.group_delete', group_id=g.id) }}" class="d-inline"
|
||||
onsubmit="return confirm('Gruppe {{ g.name }} löschen?')">
|
||||
<button type="submit" class="btn btn-sm btn-outline-danger" title="Löschen">
|
||||
onsubmit="return confirm('Delete group {{ g.name }}?')">
|
||||
<button type="submit" class="btn btn-sm btn-outline-danger" title="Delete">
|
||||
<i class="bi bi-trash3"></i>
|
||||
</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
{% else %}
|
||||
<tr><td colspan="7" class="text-muted text-center py-4">Noch keine Gruppen vorhanden.</td></tr>
|
||||
<tr><td colspan="7" class="text-muted text-center py-4">No groups yet.</td></tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
{% extends "admin/base.html" %}
|
||||
{% block title %}{{ 'Benutzer bearbeiten' if user else 'Neuer Benutzer' }}{% endblock %}
|
||||
{% block title %}{{ 'Edit User' if user else 'New User' }}{% endblock %}
|
||||
{% block content %}
|
||||
<div class="d-flex align-items-center gap-2 mb-4">
|
||||
<a href="{{ url_for('site_admin.users') }}" class="btn btn-sm btn-outline-secondary">
|
||||
<i class="bi bi-arrow-left"></i>
|
||||
</a>
|
||||
<h2 class="mb-0">{{ 'Benutzer bearbeiten: ' ~ user.username if user else 'Neuer Benutzer' }}</h2>
|
||||
<h2 class="mb-0">{{ 'Edit User: ' ~ user.username if user else 'New User' }}</h2>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
@@ -14,16 +14,16 @@
|
||||
<div class="card-body">
|
||||
<form method="post">
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Benutzername *</label>
|
||||
<label class="form-label">Username *</label>
|
||||
<input type="text" name="username" class="form-control" required
|
||||
value="{{ user.username if user else request.form.get('username', '') }}">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">{{ 'Neues Passwort (leer lassen = unverändert)' if user else 'Passwort *' }}</label>
|
||||
<label class="form-label">{{ 'New Password (leave blank = unchanged)' if user else 'Password *' }}</label>
|
||||
<input type="password" name="password" class="form-control"
|
||||
{{ '' if user else 'required' }}>
|
||||
{% if not user %}
|
||||
<div class="form-text">Mindestens 8 Zeichen empfohlen.</div>
|
||||
<div class="form-text">Minimum 8 characters recommended.</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="mb-4">
|
||||
@@ -32,15 +32,15 @@
|
||||
value="1" {{ 'checked' if user and user.is_site_admin }}>
|
||||
<label class="form-check-label" for="is_site_admin">
|
||||
<span class="text-danger fw-semibold"><i class="bi bi-shield-fill me-1"></i>Site Admin</span>
|
||||
<small class="text-muted d-block">Voller Zugriff auf alle Gruppen und Einstellungen</small>
|
||||
<small class="text-muted d-block">Full access to all groups and settings</small>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="d-flex gap-2">
|
||||
<button type="submit" class="btn btn-success">
|
||||
<i class="bi bi-check-lg me-1"></i>{{ 'Speichern' if user else 'Erstellen' }}
|
||||
<i class="bi bi-check-lg me-1"></i>{{ 'Save' if user else 'Create' }}
|
||||
</button>
|
||||
<a href="{{ url_for('site_admin.users') }}" class="btn btn-outline-secondary">Abbrechen</a>
|
||||
<a href="{{ url_for('site_admin.users') }}" class="btn btn-outline-secondary">Cancel</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
{% extends "admin/base.html" %}
|
||||
{% block title %}Benutzer{% endblock %}
|
||||
{% block title %}Users{% endblock %}
|
||||
{% block content %}
|
||||
<div class="d-flex justify-content-between align-items-center mb-4">
|
||||
<h2><i class="bi bi-people-fill me-2"></i>Benutzer</h2>
|
||||
<h2><i class="bi bi-people-fill me-2"></i>Users</h2>
|
||||
<a href="{{ url_for('site_admin.user_new') }}" class="btn btn-success">
|
||||
<i class="bi bi-person-plus-fill me-1"></i>Neuer Benutzer
|
||||
<i class="bi bi-person-plus-fill me-1"></i>New User
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
<div class="card-body p-0">
|
||||
<table class="table table-hover mb-0">
|
||||
<thead>
|
||||
<tr><th>Benutzer</th><th>Gruppen</th><th>Site Admin</th><th>Erstellt</th><th class="text-end">Aktionen</th></tr>
|
||||
<tr><th>User</th><th>Groups</th><th>Site Admin</th><th>Created</th><th class="text-end">Actions</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for u in users %}
|
||||
@@ -23,7 +23,7 @@
|
||||
<span class="badge bg-secondary me-1">{{ g.name }}
|
||||
{% if g.role == 'admin' %}<i class="bi bi-star-fill ms-1 text-warning"></i>{% endif %}
|
||||
</span>
|
||||
{% else %}<span class="text-muted small">Keine</span>{% endfor %}
|
||||
{% else %}<span class="text-muted small">None</span>{% endfor %}
|
||||
</td>
|
||||
<td>
|
||||
{% if u.is_site_admin %}
|
||||
@@ -32,19 +32,19 @@
|
||||
</td>
|
||||
<td class="text-muted small">{{ u.created_at | fmt_dt }}</td>
|
||||
<td class="text-end">
|
||||
<a href="{{ url_for('site_admin.user_edit', user_id=u.id) }}" class="btn btn-sm btn-outline-warning" title="Bearbeiten">
|
||||
<a href="{{ url_for('site_admin.user_edit', user_id=u.id) }}" class="btn btn-sm btn-outline-warning" title="Edit">
|
||||
<i class="bi bi-pencil"></i>
|
||||
</a>
|
||||
<form method="post" action="{{ url_for('site_admin.user_delete', user_id=u.id) }}" class="d-inline"
|
||||
onsubmit="return confirm('Benutzer {{ u.username }} löschen?')">
|
||||
<button type="submit" class="btn btn-sm btn-outline-danger" title="Löschen">
|
||||
onsubmit="return confirm('Delete user {{ u.username }}?')">
|
||||
<button type="submit" class="btn btn-sm btn-outline-danger" title="Delete">
|
||||
<i class="bi bi-trash3"></i>
|
||||
</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
{% else %}
|
||||
<tr><td colspan="5" class="text-muted text-center py-4">Keine Benutzer vorhanden.</td></tr>
|
||||
<tr><td colspan="5" class="text-muted text-center py-4">No users yet.</td></tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<!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">
|
||||
@@ -16,7 +16,7 @@
|
||||
<div class="text-center mb-4">
|
||||
<i class="bi bi-shield-fill-check fs-1 text-danger"></i>
|
||||
<h3 class="fw-bold mt-2">Site Admin</h3>
|
||||
<p class="text-muted small">Administrativer Zugang</p>
|
||||
<p class="text-muted small">Administrative Access</p>
|
||||
</div>
|
||||
|
||||
{% with messages = get_flashed_messages(with_categories=true) %}
|
||||
@@ -31,7 +31,7 @@
|
||||
<div class="card-body">
|
||||
<form method="post">
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Benutzername</label>
|
||||
<label class="form-label">Username</label>
|
||||
<div class="input-group">
|
||||
<span class="input-group-text text-danger"><i class="bi bi-person-fill"></i></span>
|
||||
<input type="text" name="username" class="form-control" required autofocus
|
||||
@@ -39,7 +39,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Passwort</label>
|
||||
<label class="form-label">Password</label>
|
||||
<div class="input-group">
|
||||
<span class="input-group-text text-danger"><i class="bi bi-lock-fill"></i></span>
|
||||
<input type="password" name="password" class="form-control" required>
|
||||
@@ -54,7 +54,7 @@
|
||||
|
||||
<div class="text-center mt-3">
|
||||
<a href="{{ url_for('auth.login') }}" class="text-muted small">
|
||||
<i class="bi bi-arrow-left me-1"></i>Zurück zum normalen Login
|
||||
<i class="bi bi-arrow-left me-1"></i>Back to regular login
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<!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">
|
||||
@@ -31,7 +31,7 @@
|
||||
<div class="card-body">
|
||||
<form method="post">
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Benutzername</label>
|
||||
<label class="form-label">Username</label>
|
||||
<div class="input-group">
|
||||
<span class="input-group-text"><i class="bi bi-person-fill"></i></span>
|
||||
<input type="text" name="username" class="form-control" required autofocus
|
||||
@@ -39,14 +39,14 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Passwort</label>
|
||||
<label class="form-label">Password</label>
|
||||
<div class="input-group">
|
||||
<span class="input-group-text"><i class="bi bi-lock-fill"></i></span>
|
||||
<input type="password" name="password" class="form-control" required>
|
||||
</div>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-success w-100">
|
||||
<i class="bi bi-box-arrow-in-right me-1"></i> Einloggen
|
||||
<i class="bi bi-box-arrow-in-right me-1"></i> Login
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<!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">
|
||||
@@ -101,7 +101,7 @@
|
||||
<!-- Gruppen-Switcher -->
|
||||
{% if not session.get('is_site_admin') and user_groups and user_groups|length > 1 %}
|
||||
<div class="mb-2">
|
||||
<small class="text-muted">Gruppe wechseln:</small>
|
||||
<small class="text-muted">Switch group:</small>
|
||||
{% for g in user_groups %}
|
||||
<a href="{{ url_for('auth.switch_group', group_id=g.id) }}"
|
||||
class="btn btn-sm w-100 mt-1 {{ 'btn-success' if g.id == session.get('group_id') else 'btn-outline-secondary' }}">
|
||||
@@ -114,13 +114,13 @@
|
||||
<!-- Admin-Links -->
|
||||
{% if session.get('role') == 'admin' and not session.get('is_site_admin') %}
|
||||
<a href="{{ url_for('group_admin.dashboard') }}" class="btn btn-outline-warning btn-sm mb-1">
|
||||
<i class="bi bi-gear-fill"></i> Gruppe verwalten
|
||||
<i class="bi bi-gear-fill"></i> Manage Group
|
||||
</a>
|
||||
{% endif %}
|
||||
{% if session.get('is_site_admin') %}
|
||||
{% if session.get('admin_viewing') %}
|
||||
<a href="{{ url_for('site_admin.stop_view') }}" class="btn btn-warning btn-sm mb-1">
|
||||
<i class="bi bi-arrow-left"></i> Zurück zum Admin
|
||||
<i class="bi bi-arrow-left"></i> Back to Admin
|
||||
</a>
|
||||
{% else %}
|
||||
<a href="{{ url_for('site_admin.dashboard') }}" class="btn btn-outline-danger btn-sm mb-1">
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -1,22 +1,22 @@
|
||||
{% extends "base.html" %}
|
||||
{% block title %}No Database{% endblock %}
|
||||
{% block page_title %}<i class="bi bi-database-fill-x me-2"></i>Keine Datenbank{% endblock %}
|
||||
{% block page_title %}<i class="bi bi-database-fill-x me-2"></i>No Database{% endblock %}
|
||||
{% block content %}
|
||||
<div class="row justify-content-center mt-5">
|
||||
<div class="col-md-6 text-center">
|
||||
<i class="bi bi-database-fill-x display-1 text-muted mb-4"></i>
|
||||
<h3 class="mb-3">Keine Datenbank konfiguriert</h3>
|
||||
<h3 class="mb-3">No database configured</h3>
|
||||
<p class="text-muted mb-4">
|
||||
Für diese Gruppe ist noch keine MC-Datenbank eingerichtet.
|
||||
No MC database has been set up for this group.
|
||||
{% if session.get('role') == 'admin' %}
|
||||
Du kannst die Verbindung als Gruppen-Admin konfigurieren.
|
||||
You can configure the connection as group admin.
|
||||
{% else %}
|
||||
Bitte wende dich an deinen Gruppenadmin.
|
||||
Please contact your group admin.
|
||||
{% endif %}
|
||||
</p>
|
||||
{% if session.get('role') == 'admin' %}
|
||||
<a href="{{ url_for('group_admin.database') }}" class="btn btn-success btn-lg">
|
||||
<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>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
4449
web_all_content.txt
Normal file
4449
web_all_content.txt
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user