feat: Paket 2 - Product catalog management, guest orders, sponsor rounds, password reset, user deletion, unlimited invite links and setup wizard

This commit is contained in:
2026-09-21 11:32:41 +02:00
parent 83393e363e
commit e5ca9c3cbf
7 changed files with 910 additions and 119 deletions
+46 -5
View File
@@ -22,6 +22,12 @@
Bestellschluss: <strong>{{ event.deadline.strftime('%d.%m.%Y um %H:%M Uhr') }}</strong>
</p>
{% if event.sponsor_name %}
<div class="sponsor-badge-banner">
🎉 <strong>Runde gesponsert:</strong> Die Brotzeit geht heute auf <strong>{{ event.sponsor_name }}</strong>!
</div>
{% endif %}
<div class="banner-stats">
<span>👥 Bereits <strong>{{ order_count }}</strong> Bestellungen von Kollegen eingegangen</span>
</div>
@@ -48,7 +54,14 @@
<div class="product-info">
<h3>{{ product.name }}</h3>
<p class="product-desc">{{ product.description }}</p>
<div class="product-price">{{ "%.2f"|format(product.price) }} € <small>/ {{ product.unit }}</small></div>
<div class="product-price">
{% if event.sponsor_name %}
<span style="text-decoration: line-through; opacity: 0.6; font-size: 0.9rem;">{{ "%.2f"|format(product.price) }} €</span>
<span style="color: var(--accent-gold); font-weight: 700;"> 0,00 € (Gesponsert)</span>
{% else %}
{{ "%.2f"|format(product.price) }} € <small>/ {{ product.unit }}</small>
{% endif %}
</div>
</div>
<div class="quantity-control">
<button type="button" class="qty-btn" onclick="changeQty({{ product.id }}, -1)" {% if is_closed %}disabled{% endif %}>-</button>
@@ -63,15 +76,38 @@
<!-- Right: User Details & Summary -->
<div class="summary-section">
<div class="summary-card">
<h2>2. Zusammenfassung</h2>
<h2>2. Bestellung & Angaben</h2>
{% if current_user %}
<div class="logged-in-badge">
<div class="user-avatar">👤</div>
<div>
<strong>{{ current_user.first_name }} {{ current_user.last_name }}</strong><br>
<strong>{{ current_user.first_name }} {{ current_user.last_name }}</strong>
{% if current_user.role == 'guest' %}<small>(Gast)</small>{% endif %}
<br>
<small class="text-muted">{{ current_user.email }}</small>
</div>
</div>
{% else %}
<!-- Gast Angaben -->
<div class="guest-order-box">
<div class="privacy-note" style="margin-bottom: 12px;">
👋 <strong>Gast-Bestellung:</strong> Du bestellst ohne dauerhaftes Benutzerkonto für diesen Termin mit.
</div>
<div class="input-group">
<label for="g_first_name">Dein Vorname *</label>
<input type="text" id="g_first_name" name="guest_first_name" required placeholder="z. B. Christian">
</div>
<div class="input-group">
<label for="g_last_name">Nachname (optional)</label>
<input type="text" id="g_last_name" name="guest_last_name" placeholder="z. B. Bauer">
</div>
<div class="input-group">
<label for="g_email">E-Mail (optional für Bestätigung)</label>
<input type="email" id="g_email" name="guest_email" placeholder="name@firma.de">
</div>
</div>
{% endif %}
{% if existing_order %}
<div class="notice-box">
@@ -87,6 +123,12 @@
<div class="total-amount" id="totalAmount">0,00 €</div>
</div>
{% if event.sponsor_name %}
<div style="font-size: 0.85rem; color: var(--accent-gold); margin-bottom: 14px; text-align: center;">
🎁 Die Rechnung wird von <strong>{{ event.sponsor_name }}</strong> übernommen!
</div>
{% endif %}
<button type="submit" class="btn-submit" id="submitBtn" {% if is_closed %}disabled{% endif %}>
{% if is_closed %}
🔒 Bestellschluss vorüber
@@ -112,7 +154,7 @@
<div class="empty-icon">🏖️</div>
<h2>Aktuell keine offene Bestellrunde</h2>
<p>Für dieses Team ist im Moment keine Brotzeit geplant.</p>
{% if current_user.role == 'admin' %}
{% if current_user and current_user.role == 'admin' %}
<a href="/admin?tab=event" class="btn-primary" style="margin-top: 1rem;">Neue Bestellrunde im Cockpit anlegen</a>
{% endif %}
</div>
@@ -163,7 +205,6 @@
if (containerEl) {
containerEl.classList.add('expired');
}
// Formular sperren
if (submitBtn) {
submitBtn.disabled = true;
submitBtn.innerText = "🔒 Bestellschluss vorüber";