Files
3d.lehrstun.de/templates/cockpit.html
Hans Puettmann 76addcb846 Herr Rechmann + L3-Titel + L2-Workflow
Drei Aenderungen aus Herbs Feedback:

1. Markus -> Herr Rechmann (60 Treffer in 26 Dateien + DB-Lektionen L2/L3)
   Konvention: Herb bleibt 'Herb' (interne Anrede fuer Claude), Markus
   wird in SuS-sichtbaren Texten als 'Herr Rechmann' ausgeschrieben.
   Wo 'Herb und Markus' stand -> 'Herb und Herr Rechmann'. Wenn das
   stilistisch zu uneinheitlich wirkt, koennen wir Herb spaeter auch
   in SuS-Texten zu 'Herr Puettmann' umziehen.

2. L3-Titel: 'Customizer — parametrisches 3D-Modell anpassen'
   -> 'Mein eigenes 3D-Modell designen'
   Begruendung Herb: 'Customizer' + 'parametrisch' wirken abschreckend.
   Methode kommt in den Aufgabe-Text, nicht in den Titel.

3. L2-Inhalt komplett geschrieben (~4.8 KB):
   - 8-Schritte-Workflow vom Stoebern auf Printables bis zum
     Druck-Abholen
   - A1-mini-Spezifika klar markiert (offen → nur PLA, 18×18 cm)
   - P-Serie-Spezifika fuer groessere Drucke
   - Tipps zur Modell-Wahl (klein anfangen, 4+ Sterne)
   - Was-tun-wenn-Tabelle bei Druckproblemen
   - Lehrer-Eskalations-Pfad: pausieren via Handy-App + Lehrer rufen

   Quellenlage: PDF-Anleitung A1 mini im OneDrive + Bambu-Wiki online
   waren beide nicht maschinell zugaenglich (pdftoppm fehlt, Wiki
   gibt HTTP 402). Workflow basiert auf Standard-Bambu-Studio-Bedienung
   + Konsistenz mit der L1-P2S-Beschreibung. Herb/Herr Rechmann pruefen
   die A1-mini-Spezifika beim Lehrer-Test und korrigieren via Inline-Edit
   (oder per Migration, wenn Inline-Edit-UI noch nicht live ist).
2026-05-24 19:51:19 +02:00

269 lines
12 KiB
HTML
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{% extends "base.html" %}
{% block title %}Cockpit — {{ vorname }}{% endblock %}
{% block content %}
{# ====== Header ====== #}
<div class="section-header">
<h1 style="display:flex; align-items:center; gap:0.5rem;">
<span style="font-size: 2.2rem;">{{ tier_emoji(tier) }}</span>
Hallo, {{ vorname }}!
</h1>
<a href="{{ url_for('profil.logout') }}" class="btn btn-secondary">Abmelden</a>
</div>
{# ====== BANNER: Lehrer-Notizen (V5-Quick-Action) ====== #}
{% for n in status.notizen %}
<div class="card" style="background: #FEF9E7; border-left: 5px solid var(--warning); margin-bottom: 0.5rem;">
<p style="margin: 0; color: #B7950B;">
<strong>📌 Lehrer-Notiz:</strong> {{ n.text }}
</p>
<form method="post" action="{{ url_for('profil.notiz_gelesen', notiz_id=n.id) }}" style="margin-top: 0.5rem;">
<button class="btn btn-secondary" style="padding: 0.2rem 0.6rem; font-size: 0.85rem;">verstanden</button>
</form>
</div>
{% endfor %}
{# ====== BANNER: Offene Rueckfragen zu eigenen Projekten (V6) ====== #}
{% for r in status.rueckfragen %}
<div class="card" style="background: #FEF9E7; border-left: 5px solid var(--warning); margin-bottom: 0.5rem;">
<p style="margin: 0; color: #B7950B;">
<strong>❓ Rueckfrage zu „{{ r.projekt_titel }}":</strong> {{ r.text }}
</p>
<p style="margin-top: 0.5rem; font-size: 0.85rem; color: var(--text-light);">
Bessere das Projekt nach, dann melde es erneut zur Freigabe.
</p>
</div>
{% endfor %}
{# ====== BANNER: Eingegangene Paarungs-Anfragen ====== #}
{% for a in status.offene_anfragen %}
<div class="card" style="background: #EBF5FB; border-left: 5px solid var(--primary); margin-bottom: 0.5rem;">
<p style="margin: 0;">
<strong>{{ tier_emoji(a.von_tier) }} {{ a.von_vorname }}</strong> moechte mit dir
zusammenarbeiten. Magst du?
</p>
<div style="margin-top: 0.5rem; display: flex; gap: 0.5rem;">
<form method="post" action="{{ url_for('profil.paarung_anfrage_beantworten', anfrage_id=a.id, aktion='annehmen') }}">
<button class="btn btn-primary" style="padding: 0.3rem 0.8rem;">Ja, gerne</button>
</form>
<form method="post" action="{{ url_for('profil.paarung_anfrage_beantworten', anfrage_id=a.id, aktion='ablehnen') }}">
<button class="btn btn-secondary" style="padding: 0.3rem 0.8rem;">Nein, lieber nicht</button>
</form>
</div>
</div>
{% endfor %}
{# ====== Check-In-Modal — wenn heute noch nichts gewaehlt wurde ====== #}
{% if not status.check_in_heute %}
<div class="card" style="border-top: 4px solid var(--primary);">
<h2>Was machst du heute? 🎯</h2>
<p style="color: var(--text-light); font-size: 0.9rem;">
Damit Herb und Herr Rechmann auf einen Blick sehen, woran du arbeitest.
Ein Klick reicht — Freitext nur, wenn du willst.
</p>
<form method="post" action="{{ url_for('profil.check_in') }}" style="margin-top: 1rem;">
<div class="check-in-optionen">
{% set hat_projekte = status.aktive_projekte | length > 0 %}
{% if hat_projekte %}
<label class="ci-option">
<input type="radio" name="modus" value="weiter_wie_bisher" checked>
<span>Ich arbeite an „{{ status.aktive_projekte[0].titel }}" weiter</span>
</label>
{% endif %}
<label class="ci-option">
<input type="radio" name="modus" value="neues_projekt" {% if not hat_projekte %}checked{% endif %}>
<span>Neues Projekt anfangen</span>
</label>
{% if status.ist_neu %}
<label class="ci-option">
<input type="radio" name="modus" value="onboarding">
<span>Onboarding-Lektion machen</span>
</label>
{% endif %}
<label class="ci-option">
<input type="radio" name="modus" value="drucken">
<span>Drucken / auf Drucker warten</span>
</label>
<label class="ci-option">
<input type="radio" name="modus" value="helfen">
<span>Jemandem helfen</span>
</label>
<label class="ci-option">
<input type="radio" name="modus" value="sonstiges">
<span>Sonstiges</span>
</label>
</div>
<input type="text" name="freitext" placeholder="(optional) was genau …"
style="width: 100%; padding: 0.5rem; margin-top: 0.6rem; border: 1px solid var(--border); border-radius: 4px;">
<button class="btn btn-primary" style="margin-top: 0.6rem;">Los geht's</button>
</form>
</div>
{% else %}
<div class="card" style="background: #EAFBF1; border-left: 4px solid var(--success);">
<p style="margin: 0; font-size: 0.9rem;">
<strong>Heute eingecheckt:</strong>
{% if status.check_in_heute.modus == 'weiter_wie_bisher' %}Arbeite weiter
{% elif status.check_in_heute.modus == 'neues_projekt' %}Neues Projekt
{% elif status.check_in_heute.modus == 'onboarding' %}Onboarding
{% elif status.check_in_heute.modus == 'drucken' %}Drucken
{% elif status.check_in_heute.modus == 'helfen' %}Hilft anderen
{% else %}{{ status.check_in_heute.modus }}{% endif %}
{% if status.check_in_heute.freitext %} &mdash; „{{ status.check_in_heute.freitext }}"{% endif %}
</p>
</div>
{% endif %}
<div class="grid" style="grid-template-columns: 1fr 1fr; gap: 1rem; margin-top: 1rem;">
{# ====== ONBOARDING-KARTE (V1: nur wenn nicht fertig) ====== #}
{% if status.ist_neu %}
<div class="card" style="grid-column: span 2; border-top: 4px solid var(--success);">
<h2>Dein Onboarding-Pfad 🚀</h2>
<p style="color: var(--text-light); margin-bottom: 1rem;">
Drei Lektionen, damit du allein klarkommst. Du klickst selbst „fertig", wenn du soweit bist.
</p>
<div class="onboarding-liste">
{% for l in status.onboarding.lektionen %}
<div class="onb-zeile onb-{{ l.status }}{% if l.aktuell %} onb-aktuell{% endif %}">
<span class="onb-icon">
{% if l.status == 'fertig' %}✅
{% elif l.status == 'laeuft' %}🟡
{% else %}⚪{% endif %}
</span>
<span class="onb-titel">
<strong>L{{ l.nummer }}</strong> &mdash; {{ l.titel }}
</span>
<span class="onb-aktion">
{% if l.status != 'fertig' %}
<a href="{{ url_for('oeffentlich.lektion_detail', nummer=l.nummer) }}"
class="btn btn-secondary" style="padding: 0.2rem 0.6rem; font-size: 0.8rem;">
ansehen
</a>
<form method="post" action="{{ url_for('profil.lektion_status_setzen', nummer=l.nummer) }}" style="display:inline;">
{% if l.status == 'offen' %}
<button name="status" value="laeuft" class="btn btn-secondary" style="padding: 0.2rem 0.6rem; font-size: 0.8rem;">starte</button>
{% else %}
<button name="status" value="fertig" class="btn btn-primary" style="padding: 0.2rem 0.6rem; font-size: 0.8rem;">fertig ✓</button>
{% endif %}
</form>
{% else %}
<form method="post" action="{{ url_for('profil.lektion_status_setzen', nummer=l.nummer) }}" style="display:inline;">
<button name="status" value="laeuft" class="btn btn-secondary" style="padding: 0.2rem 0.6rem; font-size: 0.75rem; opacity: 0.6;">nochmal</button>
</form>
{% endif %}
</span>
</div>
{% endfor %}
</div>
{% if not status.darf_slots_buchen %}
<p style="margin-top: 1rem; font-size: 0.85rem; color: var(--text-light);">
Drucker reservieren kannst du, sobald <strong>L1 (Sicherheit)</strong> erledigt ist.
</p>
{% endif %}
</div>
{% endif %}
{# ====== PROJEKT-KARTE (V1: nur wenn Projekte oder Onboarding fertig) ====== #}
{% if status.hat_projekte or not status.ist_neu %}
<div class="card">
<h2>{% if status.paarung %}Euer Projekt{% else %}Dein Projekt{% endif %}</h2>
{% if status.aktive_projekte %}
{% for p in status.aktive_projekte %}
<div style="margin-bottom: 0.8rem;">
<strong>{{ p.titel }}</strong>
{% if p.beschreibung_md %}
<div style="margin-top: 0.3rem; font-size: 0.9rem;">{{ p.beschreibung_md|markdown }}</div>
{% endif %}
</div>
{% endfor %}
{% else %}
<p style="color: var(--text-light);">
Du hast noch kein laufendes Projekt.
</p>
<p style="margin-top: 0.5rem; font-size: 0.85rem; color: var(--text-light);">
<em>Projekt-Anlage kommt mit Etappe 6.</em>
</p>
{% endif %}
</div>
{% endif %}
{# ====== PAARUNG / TEAM-KARTE — immer wenn Paarung aktiv, sonst nur fuer Erfahrene ====== #}
{% if status.paarung or not status.ist_neu %}
<div class="card">
<h2>{% if status.paarung %}Dein Team{% else %}Allein arbeiten?{% endif %}</h2>
{% if status.paarung %}
<p style="font-size: 1.1rem;">
Du arbeitest mit
<strong>{{ tier_emoji(status.paarung.partner.tier) }} {{ status.paarung.partner.vorname }}</strong>
zusammen seit {{ status.paarung.gebildet_am[:10] }}.
</p>
<form method="post" action="{{ url_for('profil.paarung_aufloesen') }}"
onsubmit="return confirm('Paarung wirklich aufloesen?')"
style="margin-top: 0.8rem;">
<button class="btn btn-secondary" style="font-size: 0.85rem;">Paarung aufloesen</button>
</form>
{% else %}
<p style="color: var(--text-light); margin-bottom: 0.5rem;">
Du kannst dich mit jemandem zusammenschliessen — frag im Cockpit-Untermenue.
</p>
{% if andere_profile %}
<details>
<summary style="cursor:pointer; color: var(--primary);">Anfrage stellen</summary>
<div id="paarung-suche" style="margin-top: 0.5rem;">
{% for andere in andere_profile %}
<form method="post" action="{{ url_for('profil.paarung_anfragen', andere_profil_id=andere.id) }}"
style="display: inline-block; margin: 0.2rem;">
<button class="btn btn-secondary" style="padding: 0.3rem 0.6rem; font-size: 0.85rem;">
{{ tier_emoji(andere.tier) }} {{ andere.vorname }}
</button>
</form>
{% endfor %}
</div>
</details>
{% else %}
<p style="font-size: 0.85rem; color: var(--text-light); margin-top: 0.5rem;">
<em>Noch niemand sonst in der AG.</em>
</p>
{% endif %}
{% endif %}
</div>
{% endif %}
{# ====== DRUCKER-/SLOT-KARTE (V1: nur wenn L1 fertig) ====== #}
{% if status.darf_slots_buchen %}
<div class="card" style="grid-column: span 2; opacity: 0.7;">
<h2>🖨️ Drucker reservieren</h2>
<p style="color: var(--text-light);">
Slot-System kommt mit <em>Etappe 7</em>. Bis dahin: sprich dich vor Ort ab.
</p>
</div>
{% endif %}
</div>
{% endblock %}
{% block scripts %}
<style>
.check-in-optionen { display: flex; flex-direction: column; gap: 0.4rem; }
.ci-option {
display: flex; gap: 0.6rem; align-items: center;
padding: 0.5rem 0.7rem; border-radius: 6px; cursor: pointer;
transition: background 0.15s;
}
.ci-option:hover { background: #F2F3F4; }
.ci-option input[type=radio] { margin: 0; }
.onboarding-liste { display: flex; flex-direction: column; gap: 0.5rem; }
.onb-zeile {
display: flex; gap: 0.7rem; align-items: center;
padding: 0.5rem 0.7rem; border-radius: 6px;
background: #F2F3F4;
}
.onb-zeile.onb-fertig { background: #EAFBF1; opacity: 0.8; }
.onb-zeile.onb-aktuell { background: #EBF5FB; border-left: 4px solid var(--primary); }
.onb-icon { font-size: 1.2rem; }
.onb-titel { flex: 1; }
.onb-aktion { display: flex; gap: 0.3rem; }
</style>
{% endblock %}