Kursverwaltung

This commit is contained in:
Bkolb 2026-04-03 21:10:30 +02:00
parent 452a3219ea
commit aa0767f790
3 changed files with 247 additions and 0 deletions

View File

@ -1488,3 +1488,118 @@ def admin_checklist():
form_values=form_values, form_values=form_values,
**get_current_user() **get_current_user()
) )
@app.route("/admin/courses", methods=["GET", "POST"])
@admin_required
def admin_courses():
conn = get_connection()
cur = conn.cursor()
form_error = None
form_values = None
video_dir = os.path.join("/app/images/videos")
video_files = []
if os.path.isdir(video_dir):
video_files = sorted([
f for f in os.listdir(video_dir)
if f.lower().endswith(".mp4")
])
if request.method == "POST":
action = request.form.get("action")
code = request.form.get("code", "").strip().upper()
title = request.form.get("title", "").strip()
description = request.form.get("description", "").strip()
min_level = request.form.get("min_level", "").strip()
video_file = request.form.get("video_file", "").strip()
sort_order = request.form.get("sort_order", "0").strip()
form_values = {
"code": code,
"title": title,
"description": description,
"min_level": min_level,
"video_file": video_file,
"sort_order": sort_order
}
if action == "create":
if not code:
form_error = "Code ist Pflicht."
elif not title:
form_error = "Titel ist Pflicht."
elif not min_level:
form_error = "Level ist Pflicht."
elif not video_file:
form_error = "Video-Datei ist Pflicht."
else:
cur.execute("""
INSERT INTO course (code, title, description, min_level, video_file, sort_order)
VALUES (%s, %s, %s, %s, %s, %s)
""", (
code,
title,
description or None,
int(min_level),
video_file,
int(sort_order or 0)
))
conn.commit()
elif action == "update":
course_id = request.form.get("id")
if not code:
form_error = "Code ist Pflicht."
elif not title:
form_error = "Titel ist Pflicht."
elif not min_level:
form_error = "Level ist Pflicht."
elif not video_file:
form_error = "Video-Datei ist Pflicht."
else:
cur.execute("""
UPDATE course
SET code=%s,
title=%s,
description=%s,
min_level=%s,
video_file=%s,
sort_order=%s
WHERE id=%s
""", (
code,
title,
description or None,
int(min_level),
video_file,
int(sort_order or 0),
int(course_id)
))
conn.commit()
elif action == "delete":
course_id = request.form.get("id")
cur.execute("DELETE FROM course WHERE id=%s", (int(course_id),))
conn.commit()
cur.execute("""
SELECT id, code, title, description, min_level, video_file, sort_order
FROM course
ORDER BY min_level, sort_order, id
""")
courses = fetchall_dict(cur)
cur.close()
conn.close()
return render_template(
"admin_courses.html",
courses=courses,
video_files=video_files,
form_error=form_error,
form_values=form_values,
**get_current_user()
)

View File

@ -0,0 +1,131 @@
{% extends "base.html" %}
{% block content %}
<h1>Kursverwaltung</h1>
{% if form_error %}
<div class="error-box">{{ form_error }}</div>
{% endif %}
<div class="admin-panel">
<h2>Neuen Kurs anlegen</h2>
<form method="post" class="admin-grid-form">
<input type="hidden" name="action" value="create">
<div class="form-row">
<label>Code</label>
<input type="text" name="code" value="{{ form_values.code if form_values else '' }}" placeholder="z.B. A1" required>
</div>
<div class="form-row">
<label>Titel</label>
<input type="text" name="title" value="{{ form_values.title if form_values else '' }}" required>
</div>
<div class="form-row">
<label>Level</label>
<select name="min_level" required>
<option value="1" {% if form_values and form_values.min_level == '1' %}selected{% endif %}>1 - Gold</option>
<option value="2" {% if form_values and form_values.min_level == '2' %}selected{% endif %}>2 - Silber</option>
<option value="3" {% if form_values and form_values.min_level == '3' %}selected{% endif %}>3 - Bronze</option>
</select>
</div>
<div class="form-row">
<label>Video-Datei</label>
<select name="video_file" required>
<option value="">Bitte wählen</option>
{% for v in video_files %}
<option value="{{ v }}" {% if form_values and form_values.video_file == v %}selected{% endif %}>
{{ v }}
</option>
{% endfor %}
</select>
</div>
<div class="form-row">
<label>Sortierung</label>
<input type="number" name="sort_order" value="{{ form_values.sort_order if form_values else '0' }}">
</div>
<div class="form-row form-row-full">
<label>Beschreibung</label>
<textarea name="description">{{ form_values.description if form_values else '' }}</textarea>
</div>
<div class="form-row form-row-full">
<button class="btn-primary">Kurs anlegen</button>
</div>
</form>
</div>
<div class="admin-panel">
<h2>Bestehende Kurse</h2>
<table class="mandanten-table">
<thead>
<tr>
<th>ID</th>
<th>Code</th>
<th>Titel</th>
<th>Level</th>
<th>Video</th>
<th>Sort</th>
<th>Aktionen</th>
</tr>
</thead>
<tbody>
{% for c in courses %}
<tr>
<form method="post">
<input type="hidden" name="id" value="{{ c.id }}">
<td>{{ c.id }}</td>
<td>
<input type="text" name="code" value="{{ c.code }}">
</td>
<td>
<input type="text" name="title" value="{{ c.title }}">
</td>
<td>
<select name="min_level">
<option value="1" {% if c.min_level == 1 %}selected{% endif %}>1 - Gold</option>
<option value="2" {% if c.min_level == 2 %}selected{% endif %}>2 - Silber</option>
<option value="3" {% if c.min_level == 3 %}selected{% endif %}>3 - Bronze</option>
</select>
</td>
<td>
<select name="video_file">
{% for v in video_files %}
<option value="{{ v }}" {% if c.video_file == v %}selected{% endif %}>
{{ v }}
</option>
{% endfor %}
</select>
</td>
<td>
<input type="number" name="sort_order" value="{{ c.sort_order }}">
</td>
<td>
<input type="hidden" name="description" value="{{ c.description or '' }}">
<button name="action" value="update" class="btn-primary btn-small">Speichern</button>
<button name="action" value="delete" class="btn-danger btn-small">Löschen</button>
</td>
</form>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% endblock %}

View File

@ -37,6 +37,7 @@
{% if is_admin %} {% if is_admin %}
<a href="/admin/mandanten">Mandanten</a> <a href="/admin/mandanten">Mandanten</a>
<a href="/admin/checklist">Checklist</a> <a href="/admin/checklist">Checklist</a>
<a href="/admin/courses">Kurse</a>
{% endif %} {% endif %}
{% if is_user_admin %} {% if is_user_admin %}
<a href="/useradmin/mandant">Useradministration</a> <a href="/useradmin/mandant">Useradministration</a>