Initial commit: Schmankerl v2 - Multi-tenant FastAPI Brotzeitportal
This commit is contained in:
@@ -0,0 +1,136 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block content %}
|
||||
<div class="container">
|
||||
|
||||
<div class="admin-header">
|
||||
<div>
|
||||
<h1>👨🍳 Einkäufer-Cockpit</h1>
|
||||
<p class="admin-sub">Mandant: <strong>{{ tenant.name }}</strong> | Aktuelle Brotzeitrunde</p>
|
||||
</div>
|
||||
<div class="admin-actions-top">
|
||||
<button onclick="copyShoppingList()" class="btn-primary">📋 Einkaufsliste kopieren</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% if event %}
|
||||
<!-- Stats Cards -->
|
||||
<div class="stats-grid">
|
||||
<div class="stat-card">
|
||||
<div class="stat-label">Gesamtsumme Einkauf</div>
|
||||
<div class="stat-value">{{ "%.2f"|format(total_revenue) }} €</div>
|
||||
</div>
|
||||
<div class="stat-card">
|
||||
<div class="stat-label">Bereits bezahlt</div>
|
||||
<div class="stat-value success">{{ "%.2f"|format(total_paid) }} €</div>
|
||||
</div>
|
||||
<div class="stat-card">
|
||||
<div class="stat-label">Noch offen</div>
|
||||
<div class="stat-value warning">{{ "%.2f"|format(total_revenue - total_paid) }} €</div>
|
||||
</div>
|
||||
<div class="stat-card">
|
||||
<div class="stat-label">Teilnehmer</div>
|
||||
<div class="stat-value">{{ orders|length }} Personen</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="admin-columns">
|
||||
<!-- Aggregated Shopping List -->
|
||||
<div class="admin-card">
|
||||
<h2>🛒 Sammelliste für Metzger & Bäcker</h2>
|
||||
<p class="card-hint">Exakt aufsummierte Gesamtmengen aller Kollegen:</p>
|
||||
|
||||
<div class="shopping-table-wrapper">
|
||||
<table class="data-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Artikel</th>
|
||||
<th style="text-align: right;">Gesamtmenge</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for name, data in item_sums.items() %}
|
||||
<tr>
|
||||
<td><strong>{{ name }}</strong></td>
|
||||
<td style="text-align: right; font-size: 1.15rem; font-weight: 700; color: var(--accent);">
|
||||
{{ data.quantity }} {{ data.unit }}
|
||||
</td>
|
||||
</tr>
|
||||
{% else %}
|
||||
<tr><td colspan="2" class="empty-cell">Noch keine Bestellungen eingegangen.</td></tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Individual Orders & Payment Checklist -->
|
||||
<div class="admin-card">
|
||||
<h2>👥 Wer hat bestellt? (Strichliste)</h2>
|
||||
<p class="card-hint">Klicke auf den Status, um den Bezahlstatus zu ändern:</p>
|
||||
|
||||
<div class="orders-table-wrapper">
|
||||
<table class="data-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Kollege</th>
|
||||
<th>Bestellung</th>
|
||||
<th>Betrag</th>
|
||||
<th>Status</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for order in orders %}
|
||||
<tr>
|
||||
<td>
|
||||
<strong>{{ order.user.first_name }} {{ order.user.last_name }}</strong><br>
|
||||
<small class="text-muted">{{ order.user.email }}</small>
|
||||
</td>
|
||||
<td>
|
||||
<ul class="mini-items-list">
|
||||
{% for item in order.items %}
|
||||
<li>{{ item.quantity }}x {{ item.product.name }}</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</td>
|
||||
<td><strong>{{ "%.2f"|format(order.total_price) }} €</strong></td>
|
||||
<td>
|
||||
<form action="/admin/toggle-paid/{{ order.id }}" method="POST" style="margin: 0;">
|
||||
<button type="submit" class="badge-btn {% if order.is_paid %}paid{% else %}unpaid{% endif %}">
|
||||
{% if order.is_paid %}✓ Bezahlt{% else %}⏳ Offen{% endif %}
|
||||
</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
{% else %}
|
||||
<tr><td colspan="4" class="empty-cell">Noch keine Bestellungen vorhanden.</td></tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% else %}
|
||||
<div class="empty-state">
|
||||
<h2>Keine offene Bestellrunde gefunden</h2>
|
||||
<p>Aktuell gibt es kein aktives Event.</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function copyShoppingList() {
|
||||
let text = "🥨 Einkaufsliste für {{ event.title if event else 'Brotzeit' }}:\n\n";
|
||||
{% for name, data in item_sums.items() %}
|
||||
text += "• {{ name }}: {{ data.quantity }} {{ data.unit }}\n";
|
||||
{% endfor %}
|
||||
text += "\nGesamtsumme: {{ '%.2f'|format(total_revenue) }} €";
|
||||
|
||||
navigator.clipboard.writeText(text).then(() => {
|
||||
alert("Einkaufsliste in die Zwischenablage kopiert! Kann direkt in WhatsApp oder Slack eingefügt werden.");
|
||||
});
|
||||
}
|
||||
</script>
|
||||
{% endblock %}
|
||||
Reference in New Issue
Block a user