Kursfortschrittsanzeige
This commit is contained in:
parent
bc3b2505b6
commit
989422a4a7
@ -1119,9 +1119,20 @@ def course_start(course_id):
|
||||
cur.close()
|
||||
conn.close()
|
||||
|
||||
show_course_progress = True
|
||||
course_progress_title = f"{course['code']} – {course['title']}"
|
||||
course_progress_current = 1
|
||||
course_progress_total = 8
|
||||
course_progress_percent = int((course_progress_current / course_progress_total) * 100)
|
||||
|
||||
return render_template(
|
||||
"course_video.html",
|
||||
course=course,
|
||||
show_course_progress=show_course_progress,
|
||||
course_progress_title=course_progress_title,
|
||||
course_progress_current=course_progress_current,
|
||||
course_progress_total=course_progress_total,
|
||||
course_progress_percent=course_progress_percent,
|
||||
**get_current_user()
|
||||
)
|
||||
|
||||
@ -1142,6 +1153,13 @@ def course_page(course_id, page_number):
|
||||
if not page:
|
||||
abort(404)
|
||||
|
||||
cur.execute("""
|
||||
SELECT *
|
||||
FROM course
|
||||
WHERE id = %s
|
||||
""", (course_id,))
|
||||
course = fetchone_dict(cur)
|
||||
|
||||
# Fortschritt speichern
|
||||
cur.execute("""
|
||||
INSERT INTO user_course_progress (user_id, course_id, last_page)
|
||||
@ -1155,10 +1173,21 @@ def course_page(course_id, page_number):
|
||||
cur.close()
|
||||
conn.close()
|
||||
|
||||
show_course_progress = True
|
||||
course_progress_title = f"{course['code']} – {course['title']}"
|
||||
course_progress_current = page_number+1
|
||||
course_progress_total = 8
|
||||
course_progress_percent = int((course_progress_current / course_progress_total) * 100)
|
||||
|
||||
return render_template(
|
||||
page["template_name"],
|
||||
course_id=course_id,
|
||||
page_number=page_number,
|
||||
show_course_progress=show_course_progress,
|
||||
course_progress_title=course_progress_title,
|
||||
course_progress_current=course_progress_current,
|
||||
course_progress_total=course_progress_total,
|
||||
course_progress_percent=course_progress_percent,
|
||||
**get_current_user()
|
||||
)
|
||||
|
||||
@ -1591,7 +1620,7 @@ def admin_courses():
|
||||
cur.execute("""
|
||||
SELECT id, code, title, description, min_level, video_file, sort_order
|
||||
FROM course
|
||||
ORDER BY min_level, sort_order, id
|
||||
ORDER BY code
|
||||
""")
|
||||
courses = fetchall_dict(cur)
|
||||
|
||||
|
||||
@ -68,12 +68,12 @@
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>Code</th>
|
||||
<th style="width:60px;">Code</th>
|
||||
<th>Titel</th>
|
||||
<th>Level</th>
|
||||
<th style="width:120px;">Level</th>
|
||||
<th>Video</th>
|
||||
<th>Sort</th>
|
||||
<th>Aktionen</th>
|
||||
<th style="width:80px;">Sort</th>
|
||||
<th style="width:160px;">Aktionen</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
@ -81,26 +81,34 @@
|
||||
{% for c in courses %}
|
||||
<tr>
|
||||
<form method="post">
|
||||
<input type="hidden" name="id" value="{{ c.id }}">
|
||||
|
||||
<td>{{ c.id }}</td>
|
||||
|
||||
<td>
|
||||
<input type="hidden" name="id" value="{{ c.id }}">
|
||||
{{ c.id }}
|
||||
</td>
|
||||
|
||||
<!-- CODE -->
|
||||
<td>
|
||||
<input type="text" name="code" value="{{ c.code }}">
|
||||
<input type="text" name="code" value="{{ c.code }}" maxlength="5" class="input-small">
|
||||
</td>
|
||||
|
||||
<!-- TITEL + BESCHREIBUNG -->
|
||||
<td>
|
||||
<input type="text" name="title" value="{{ c.title }}">
|
||||
<input type="text" name="title" value="{{ c.title }}" class="input-full">
|
||||
|
||||
<textarea name="description" class="textarea-inline"
|
||||
placeholder="Beschreibung">{{ c.description or '' }}</textarea>
|
||||
</td>
|
||||
|
||||
<!-- LEVEL -->
|
||||
<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>
|
||||
<option value="1" {% if c.min_level == 1 %}selected{% endif %}>Gold</option>
|
||||
<option value="2" {% if c.min_level == 2 %}selected{% endif %}>Silber</option>
|
||||
<option value="3" {% if c.min_level == 3 %}selected{% endif %}>Bronze</option>
|
||||
</select>
|
||||
</td>
|
||||
|
||||
<!-- VIDEO -->
|
||||
<td>
|
||||
<select name="video_file">
|
||||
{% for v in video_files %}
|
||||
@ -111,15 +119,17 @@
|
||||
</select>
|
||||
</td>
|
||||
|
||||
<!-- SORT -->
|
||||
<td>
|
||||
<input type="number" name="sort_order" value="{{ c.sort_order }}">
|
||||
<input type="number" name="sort_order" value="{{ c.sort_order }}" class="input-small">
|
||||
</td>
|
||||
|
||||
<!-- ACTIONS -->
|
||||
<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 %}
|
||||
|
||||
@ -72,6 +72,23 @@
|
||||
<main class="content-area">
|
||||
<section class="content-box">
|
||||
|
||||
{% if show_course_progress %}
|
||||
<div class="course-progress-box">
|
||||
|
||||
<div class="course-progress-header">
|
||||
<strong>{{ course_progress_title }}</strong>
|
||||
<span>{{ course_progress_current }} / {{ course_progress_total }}</span>
|
||||
</div>
|
||||
|
||||
<div class="course-progress-bar">
|
||||
<div class="course-progress-fill"
|
||||
style="width: {{ course_progress_percent }}%;">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% block content %}
|
||||
{% endblock %}
|
||||
|
||||
|
||||
45
app/flask-postgres/app/templates/course/A1_page0.html
Normal file
45
app/flask-postgres/app/templates/course/A1_page0.html
Normal file
@ -0,0 +1,45 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<h2>AI Governance Basics</h2>
|
||||
|
||||
<section class="content-section ai-explainer">
|
||||
<div class="content-wrapper">
|
||||
<h2 class="section-title">Willkommen zu Compliance Verification und zum Modul A1 – AI Governance Basics</h2>
|
||||
|
||||
<p class="lead">
|
||||
In diesem Kurs lernen Sie die Grundlagen dafür, wie moderne KI-Systeme funktionieren,
|
||||
</p>
|
||||
|
||||
<p>
|
||||
warum sie so leistungsfähig – aber gleichzeitig fehleranfällig – sind,
|
||||
in welchen Unternehmensbereichen KI eingesetzt wird,
|
||||
und welche Mindestregeln für einen sicheren und verantwortungsvollen Umgang gelten.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Unser Ziel ist nicht,
|
||||
Sie zu Programmiererinnen oder Technikern zu machen.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Unser Ziel ist,
|
||||
dass Sie ein realistisches Grundverständnis entwickeln:
|
||||
</p>
|
||||
|
||||
<ul class="key-points">
|
||||
<li>Was KI kann.</li>
|
||||
<li>Was KI nicht kann.</li>
|
||||
<li>Und welche Verantwortung Sie im Alltag tragen.</li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<div class="course-nav">
|
||||
<a href="/course/{{ course_id }}" class="btn-secondary">Zurück</a>
|
||||
<a href="/course/{{ course_id }}/page/2" class="btn-primary">Weiter</a>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
@ -41,8 +41,8 @@
|
||||
</section>
|
||||
|
||||
<div class="course-nav">
|
||||
<a href="/course/{{ course_id }}" class="btn-secondary">Zurück</a>
|
||||
<a href="/course/{{ course_id }}/page/2" class="btn-primary">Weiter</a>
|
||||
<a href="/course/{{ course_id }}/page/1" class="btn-secondary">Zurück</a>
|
||||
<a href="/course/{{ course_id }}/page/3" class="btn-secondary">Weiter</a>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
@ -56,8 +56,8 @@
|
||||
</section>
|
||||
|
||||
<div class="course-nav">
|
||||
<a href="/course/{{ course_id }}/page/1" class="btn-secondary">Zurück</a>
|
||||
<a href="/course/{{ course_id }}/page/3" class="btn-secondary">Weiter</a>
|
||||
<a href="/course/{{ course_id }}/page/2" class="btn-secondary">Zurück</a>
|
||||
<a href="/course/{{ course_id }}/page/4" class="btn-secondary">Weiter</a>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
@ -75,8 +75,8 @@
|
||||
</section>
|
||||
|
||||
<div class="course-nav">
|
||||
<a href="/course/{{ course_id }}/page/2" class="btn-secondary">Zurück</a>
|
||||
<a href="/course/{{ course_id }}/page/4" class="btn-secondary">Weiter</a>
|
||||
<a href="/course/{{ course_id }}/page/3" class="btn-secondary">Zurück</a>
|
||||
<a href="/course/{{ course_id }}/page/5" class="btn-secondary">Weiter</a>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
@ -42,8 +42,8 @@
|
||||
</section>
|
||||
|
||||
<div class="course-nav">
|
||||
<a href="/course/{{ course_id }}/page/3" class="btn-secondary">Zurück</a>
|
||||
<a href="/course/{{ course_id }}/page/5" class="btn-secondary">Weiter</a>
|
||||
<a href="/course/{{ course_id }}/page/4" class="btn-secondary">Zurück</a>
|
||||
<a href="/course/{{ course_id }}/page/6" class="btn-secondary">Weiter</a>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
@ -85,8 +85,8 @@
|
||||
</section>
|
||||
|
||||
<div class="course-nav">
|
||||
<a href="/course/{{ course_id }}/page/4" class="btn-secondary">Zurück</a>
|
||||
<a href="/course/{{ course_id }}/assessment" class="btn-primary">Zum Assessment</a>
|
||||
<a href="/course/{{ course_id }}/page/5" class="btn-secondary">Zurück</a>
|
||||
<a href="/course/{{ course_id }}/page/7" class="btn-secondary">Weiter</a>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
@ -31,7 +31,7 @@
|
||||
</section>
|
||||
|
||||
<div class="course-nav">
|
||||
<a href="/course/{{ course_id }}/page/5" class="btn-secondary">Zurück</a>
|
||||
<a href="/course/{{ course_id }}/page/6" class="btn-secondary">Zurück</a>
|
||||
<a href="/course/{{ course_id }}/assessment" class="btn-primary">Zum Assessment</a>
|
||||
</div>
|
||||
|
||||
|
||||
@ -58,8 +58,8 @@
|
||||
</section>
|
||||
|
||||
<div class="course-nav">
|
||||
<a href="/course/{{ course_id }}/page/4" class="btn-secondary">Zurück</a>
|
||||
<a href="/course/{{ course_id }}/page/6" class="btn-primary">Weiter</a>
|
||||
<a href="/course/{{ course_id }}/page/5" class="btn-secondary">Zurück</a>
|
||||
<a href="/course/{{ course_id }}/page/7" class="btn-primary">Weiter</a>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
@ -50,8 +50,8 @@
|
||||
</section>
|
||||
|
||||
<div class="course-nav">
|
||||
<a href="/course/{{ course_id }}/page/1" class="btn-secondary">Zurück</a>
|
||||
<a href="/course/{{ course_id }}/page/3" class="btn-primary">Weiter</a>
|
||||
<a href="/course/{{ course_id }}/page/3" class="btn-secondary">Zurück</a>
|
||||
<a href="/course/{{ course_id }}/page/5" class="btn-primary">Weiter</a>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
@ -52,8 +52,8 @@
|
||||
</section>
|
||||
|
||||
<div class="course-nav">
|
||||
<a href="/course/{{ course_id }}/page/1" class="btn-secondary">Zurück</a>
|
||||
<a href="/course/{{ course_id }}/page/3" class="btn-primary">Weiter</a>
|
||||
<a href="/course/{{ course_id }}/page/4" class="btn-secondary">Zurück</a>
|
||||
<a href="/course/{{ course_id }}/page/6" class="btn-primary">Weiter</a>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
@ -54,8 +54,8 @@
|
||||
</section>
|
||||
|
||||
<div class="course-nav">
|
||||
<a href="/course/{{ course_id }}/page/1" class="btn-secondary">Zurück</a>
|
||||
<a href="/course/{{ course_id }}/page/3" class="btn-primary">Weiter</a>
|
||||
<a href="/course/{{ course_id }}/page/5" class="btn-secondary">Zurück</a>
|
||||
<a href="/course/{{ course_id }}/page/7" class="btn-primary">Weiter</a>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
@ -31,7 +31,7 @@
|
||||
</section>
|
||||
|
||||
<div class="course-nav">
|
||||
<a href="/course/{{ course_id }}/page/1" class="btn-secondary">Zurück</a>
|
||||
<a href="/course/{{ course_id }}/page/6" class="btn-secondary">Zurück</a>
|
||||
<a href="/course/{{ course_id }}/assessment" class="btn-primary">Zum Assessment</a>
|
||||
</div>
|
||||
|
||||
|
||||
@ -1020,4 +1020,74 @@ button {
|
||||
.highlight-quote {
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.mandanten-table textarea {
|
||||
width: 100%;
|
||||
min-height: 70px;
|
||||
padding: 10px 12px;
|
||||
border: 1px solid #cfd8e3;
|
||||
border-radius: 10px;
|
||||
font-size: 14px;
|
||||
box-sizing: border-box;
|
||||
resize: vertical;
|
||||
font-family: Arial, Helvetica, sans-serif;
|
||||
}
|
||||
|
||||
/* ===============================
|
||||
Kursverwaltung Tabelle
|
||||
=============================== */
|
||||
|
||||
.input-small {
|
||||
width: 60px;
|
||||
padding: 6px 8px;
|
||||
}
|
||||
|
||||
.input-full {
|
||||
width: 100%;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
.textarea-inline {
|
||||
width: 100%;
|
||||
min-height: 60px;
|
||||
padding: 8px 10px;
|
||||
border: 1px solid #cfd8e3;
|
||||
border-radius: 8px;
|
||||
font-size: 14px;
|
||||
resize: vertical;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
/* ===============================
|
||||
Kursfortschritt (grün/grau)
|
||||
=============================== */
|
||||
|
||||
.course-progress-box {
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.course-progress-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
font-size: 14px;
|
||||
margin-bottom: 6px;
|
||||
color: #334155;
|
||||
}
|
||||
|
||||
/* Hintergrund = grau */
|
||||
.course-progress-bar {
|
||||
width: 100%;
|
||||
height: 12px;
|
||||
background: #e5e7eb; /* grau */
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* Fortschritt = grün */
|
||||
.course-progress-fill {
|
||||
height: 100%;
|
||||
background: #22c55e; /* grün */
|
||||
border-radius: 8px;
|
||||
transition: width 0.3s ease;
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user