Merge remote changes

This commit is contained in:
2026-02-10 13:15:10 +01:00
3 changed files with 34 additions and 1 deletions

View File

@@ -41,6 +41,7 @@ Für Bestellungen per Mail zusätzlich:
Optional: Optional:
- `APP_API_KEY` Schutz fuer `/wawi/api/bestand` und `/wawi/order` - `APP_API_KEY` Schutz fuer `/wawi/api/bestand` und `/wawi/order`
- `COOKIE_SECURE` `0` fuer http lokal, `1` fuer https - `COOKIE_SECURE` `0` fuer http lokal, `1` fuer https
- `PAYPAL_ACCOUNT` PayPal-E-Mail für Bestellformular (z.B. `paypal@beispiel.de`)
## Benutzerverwaltung ## Benutzerverwaltung
Beim ersten Start wird **ein Admin** aus ENV erzeugt: Beim ersten Start wird **ein Admin** aus ENV erzeugt:
@@ -59,10 +60,12 @@ python import_from_html.py /pfad/zu/hellas_bestand.html --truncate
## LiveShopAnsicht (index.html) ## LiveShopAnsicht (index.html)
`index.html` lädt den Bestand aus der WaWiApp: `index.html` lädt den Bestand aus der WaWiApp:
- APIProxy: `/wawi/proxy/bestand` - APIProxy: `/wawi/proxy/bestand`
- Konfiguration: `/wawi/config` (lädt PayPal-Konto aus ENV)
Wenn du diese Datei auf einem Webserver auslieferst, stelle sicher, dass die WaWiApp unter `/wawi` erreichbar ist. Wenn du diese Datei auf einem Webserver auslieferst, stelle sicher, dass die WaWiApp unter `/wawi` erreichbar ist.
Wenn du Bestellungen direkt aus `index.html` abschickst, muss der `X-Order-Key` bzw. `?key=` dem `APP_API_KEY` entsprechen. Wenn du Bestellungen direkt aus `index.html` abschickst, muss der `X-Order-Key` bzw. `?key=` dem `APP_API_KEY` entsprechen.
Der Key wird in `index.html` im ScriptBlock gesetzt: `const ORDER_KEY = ""` (neben der Formularlogik). Trage dort deinen Key ein. Der Key wird in `index.html` im ScriptBlock gesetzt: `const ORDER_KEY = ""`. Trage dort deinen Key ein (oder leer lassen, wenn kein API-Key erforderlich).
Das PayPal-Konto wird automatisch aus der ENV-Variable `PAYPAL_ACCOUNT` geladen.
## Umgebungsvariablen (ENV) ## Umgebungsvariablen (ENV)
**Pflicht/Empfohlen für Produktion** **Pflicht/Empfohlen für Produktion**
@@ -80,6 +83,7 @@ Der Key wird in `index.html` im ScriptBlock gesetzt: `const ORDER_KEY = ""` (
**Optional** **Optional**
- `APP_API_KEY` gemeinsamer APIKey für `/wawi/api/bestand` **und** `/wawi/order` - `APP_API_KEY` gemeinsamer APIKey für `/wawi/api/bestand` **und** `/wawi/order`
- `COOKIE_SECURE` `1` (default) setzt SecureCookie, `0` deaktiviert für http - `COOKIE_SECURE` `1` (default) setzt SecureCookie, `0` deaktiviert für http
- `PAYPAL_ACCOUNT` PayPal-E-Mail-Adresse für Bestellungen (wird im Bestellformular angezeigt)
## Deployment (systemd + Gunicorn) ## Deployment (systemd + Gunicorn)
1) App nach `/var/www/hellas/wawi` kopieren 1) App nach `/var/www/hellas/wawi` kopieren
@@ -112,6 +116,7 @@ Environment="SMTP_PASS=dein_pass"
Environment="SMTP_FROM=bestand@example.com" Environment="SMTP_FROM=bestand@example.com"
Environment="ORDER_TO=admin@example.com, zweite@example.com" Environment="ORDER_TO=admin@example.com, zweite@example.com"
Environment="APP_API_KEY=api_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" Environment="APP_API_KEY=api_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
Environment="PAYPAL_ACCOUNT=dein-paypal@beispiel.de"
ExecStart=/var/www/hellas/wawi/.venv/bin/gunicorn -w 3 -b 127.0.0.1:8000 app:app ExecStart=/var/www/hellas/wawi/.venv/bin/gunicorn -w 3 -b 127.0.0.1:8000 app:app
Restart=always Restart=always

View File

@@ -886,8 +886,13 @@ def order():
db = get_db() db = get_db()
cursor = db.execute( cursor = db.execute(
""" """
<<<<<<< HEAD
INSERT INTO orders (name, handy, email, mannschaft, artikel, groesse, menge, notiz, created_at, done, completed_by, completed_at, canceled, canceled_by, canceled_at, payment_method, payment_status) INSERT INTO orders (name, handy, email, mannschaft, artikel, groesse, menge, notiz, created_at, done, completed_by, completed_at, canceled, canceled_by, canceled_at, payment_method, payment_status)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, 0, NULL, NULL, 0, NULL, NULL, ?, 'unpaid') VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, 0, NULL, NULL, 0, NULL, NULL, ?, 'unpaid')
=======
INSERT INTO orders (name, handy, mannschaft, artikel, groesse, menge, notiz, created_at, done, completed_by, completed_at, canceled, canceled_by, canceled_at, payment_method, payment_status)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, 0, NULL, NULL, 0, NULL, NULL, ?, 'unpaid')
>>>>>>> origin/main
""", """,
( (
data.get("name"), data.get("name"),
@@ -1026,7 +1031,11 @@ def orders():
"""Bestellliste in der Verwaltung.""" """Bestellliste in der Verwaltung."""
rows = get_db().execute( rows = get_db().execute(
""" """
<<<<<<< HEAD
SELECT id, name, handy, email, mannschaft, artikel, groesse, menge, notiz, created_at, done, completed_by, completed_at, canceled, canceled_by, canceled_at, payment_method, payment_status, paid_at, paid_by SELECT id, name, handy, email, mannschaft, artikel, groesse, menge, notiz, created_at, done, completed_by, completed_at, canceled, canceled_by, canceled_at, payment_method, payment_status, paid_at, paid_by
=======
SELECT id, name, handy, mannschaft, artikel, groesse, menge, notiz, created_at, done, completed_by, completed_at, canceled, canceled_by, canceled_at, payment_method, payment_status, paid_at, paid_by
>>>>>>> origin/main
FROM orders FROM orders
ORDER BY id DESC ORDER BY id DESC
LIMIT 500 LIMIT 500

View File

@@ -198,6 +198,25 @@ input[type="text"], input[type="number"] {
} }
.to-top:hover { transform: translateY(-2px); } .to-top:hover { transform: translateY(-2px); }
.badge {
display: inline-block;
padding: 4px 10px;
border-radius: 4px;
font-size: 13px;
font-weight: 600;
white-space: nowrap;
}
.badge.success {
background: rgba(123, 213, 141, 0.2);
color: var(--ok);
border: 1px solid rgba(123, 213, 141, 0.4);
}
.badge.warning {
background: rgba(243, 213, 42, 0.2);
color: var(--accent);
border: 1px solid rgba(243, 213, 42, 0.4);
}
@media (max-width: 720px) { @media (max-width: 720px) {
.actions { display: flex; gap: 6px; flex-wrap: wrap; } .actions { display: flex; gap: 6px; flex-wrap: wrap; }
.btn.small { padding: 6px 8px; } .btn.small { padding: 6px 8px; }