# 💸 WhoPays - Who Pays Next? Ein einfaches, elegantes Tool um zu entscheiden, wer als nächstes zahlt - mit Discord-Benachrichtigungen und PWA-Support! ![Version](https://img.shields.io/badge/version-1.0.0-blue) ![License](https://img.shields.io/badge/license-MIT-green) ![PWA](https://img.shields.io/badge/PWA-Ready-purple) ## 🎯 Features - ✅ **Wechsel zwischen zwei Personen** - Einfacher Button-Klick - 🎨 **Individuelle Farben & Namen** - Komplett anpassbar - 📝 **Grund-Angabe** - Optional Grund für den Wechsel angeben - 🔔 **Discord-Benachrichtigungen** - Automatische Webhooks mit farbigen Embeds - 💾 **Persistenter Speicher** - Letzter Grund bleibt nach Container-Restart erhalten - 📱 **PWA-Support** - Als App auf Handy & Desktop installierbar - 🎭 **Animierte Übergänge** - Smooth Hintergrund- und Profilbild-Wechsel - 🐳 **Docker-Ready** - Einfache Deployment mit Docker Compose - 🔒 **Reverse-Proxy kompatibel** - Funktioniert mit Nginx, Caddy, Traefik, etc. --- ## 🚀 Quick Start ### Voraussetzungen - Docker & Docker Compose - Discord Webhook URL (optional) - Profilbilder (a.png, b.png) - Hintergrundbilder (bgA.jpg, bgB.jpg) ### Installation ```bash # 1. Repository klonen oder Dateien herunterladen git clone https://github.com/dein-username/whopays.git cd whopays # 2. Bilder hinzufügen cp deine-bilder/* img/ # 3. config.js anpassen (siehe Konfiguration) nano config.js # 4. Docker Container starten docker-compose up -d # 5. Öffne http://localhost:3000 ``` **Das war's!** 🎉 --- ## ⚙️ Konfiguration ### config.js - Zentrale Konfiguration Alle Einstellungen sind in **einer** Datei: ```javascript // config.js export const CONFIG = { A: { name: "Alice", // Name Person A colorHex: "#2ecc71", // Farbe im Web (Grün) colorDiscord: 0x2ecc71, // Farbe in Discord (gleich!) icon: "a.png", // Profilbild background: "bgA.jpg" // Hintergrundbild }, B: { name: "Bob", // Name Person B colorHex: "#e74c3c", // Farbe im Web (Rot) colorDiscord: 0xe74c3c, // Farbe in Discord (gleich!) icon: "b.png", // Profilbild background: "bgB.jpg" // Hintergrundbild } }; // Discord Webhook (optional) export const DISCORD_WEBHOOK_URL = "https://discord.com/api/webhooks/..."; // Öffentliche URL (für Discord Thumbnails) export const PUBLIC_BASE_URL = "https://your-domain.com"; ``` ### Farben ändern ```javascript // Blau & Orange A: { colorHex: "#3498db", colorDiscord: 0x3498db } B: { colorHex: "#e67e22", colorDiscord: 0xe67e22 } // Lila & Pink A: { colorHex: "#9b59b6", colorDiscord: 0x9b59b6 } B: { colorHex: "#e91e63", colorDiscord: 0xe91e63 } // Türkis & Gold A: { colorHex: "#1abc9c", colorDiscord: 0x1abc9c } B: { colorHex: "#f39c12", colorDiscord: 0xf39c12 } ``` **Wichtig:** Hex-Farbe muss genau 6 Zeichen haben (0-9, A-F)! --- ## 📂 Projektstruktur ``` whopays/ ├── config.js # Zentrale Konfiguration ├── server.js # Express Server ├── package.json # Node.js Dependencies ├── Dockerfile # Docker Build Instructions ├── docker-compose.yml # Docker Compose Config ├── state.json # Persistent State (auto-generiert) │ └── public/ # Statische Dateien ├── index.html # Frontend HTML ├── script.js # Frontend JavaScript ├── style.css # CSS Animationen ├── manifest.json # PWA Manifest ├── service-worker.js # PWA Service Worker │ └── img/ # Bilder ├── a.png # Profilbild Person A ├── b.png # Profilbild Person B ├── bgA.jpg # Hintergrund Person A ├── bgB.jpg # Hintergrund Person B ├── icon-192.png # PWA Icon (192x192) └── icon-512.png # PWA Icon (512x512) ``` --- ## 🐳 Docker Deployment ### docker-compose.yml ```yaml version: '3.8' services: whopays: build: . ports: - "3000:3000" environment: - NODE_ENV=production - PORT=3000 - PUBLIC_BASE_URL=https://your-domain.com - DISCORD_WEBHOOK_URL = "https://discord.com/api/webhooks/..."; volumes: # Bilder (persistent) - ./img:/app/public/img # State (persistent über Neustarts) - ./state.json:/app/state.json restart: unless-stopped ``` ### Befehle ```bash # Container starten docker-compose up -d # Logs anschauen docker-compose logs -f # Container neustarten docker-compose restart # Container stoppen docker-compose down # Neu bauen (nach Code-Änderungen) docker-compose down docker-compose build --no-cache docker-compose up -d ``` --- ## 📱 PWA Installation ### iOS (Safari) 1. Öffne die Website in Safari 2. Tippe auf das **Teilen**-Symbol (⎙) 3. Scrolle und tippe **"Zum Home-Bildschirm"** 4. Tippe **"Hinzufügen"** ### Android (Chrome) 1. Öffne die Website in Chrome 2. Tippe auf **Menü** (⋮) 3. Tippe **"App installieren"** 4. Tippe **"Installieren"** ### Desktop (Chrome/Edge) 1. Öffne die Website 2. Klicke auf das **⊕ Icon** in der Adressleiste 3. Oder: Menü → "WhoPays installieren" **Wichtig:** PWA funktioniert nur über HTTPS (oder localhost)! --- ## 🔒 Reverse Proxy Setup ### Nginx ```nginx server { listen 443 ssl http2; server_name whopays.your-domain.com; # PWA Files - NO AUTH location ~ ^/(service-worker\.js|manifest\.json)$ { proxy_pass http://localhost:3000; proxy_set_header X-Forwarded-Proto $scheme; add_header Service-Worker-Allowed "/" always; } # Main app location / { proxy_pass http://localhost:3000; proxy_set_header Host $host; proxy_set_header X-Forwarded-Proto $scheme; } } ``` ### Caddy (Einfachste Option!) ```caddy whopays.your-domain.com { reverse_proxy localhost:3000 } ``` Caddy macht automatisch HTTPS mit Let's Encrypt! ✅ --- ## 🔧 API Endpoints ### GET /status ```bash curl http://localhost:3000/status ``` Response: ```json { "current": "A", "lastReason": "Pizza bestellt" } ``` ### POST /toggle ```bash curl -X POST http://localhost:3000/toggle \ -H "Content-Type: application/json" \ -d '{"reason":"Kaffee trinken"}' ``` Response: ```json { "current": "B", "name": "Bob", "lastReason": "Kaffee trinken" } ``` ### GET /config ```bash curl http://localhost:3000/config ``` --- ## 🐛 Troubleshooting ### PWA lässt sich nicht installieren - Stelle sicher, dass du HTTPS verwendest - Prüfe ob `manifest.json` erreichbar ist - Icons müssen existieren: `icon-192.png` und `icon-512.png` ### Discord sendet keine Benachrichtigungen - Prüfe Webhook URL in `config.js` - Logs prüfen: `docker-compose logs | grep Discord` - Stelle sicher `PUBLIC_BASE_URL` ist korrekt ### Bilder werden nicht angezeigt - Prüfe ob Bilder in `/img/` existieren - Berechtigungen: `chmod -R 755 img/` - Container neu starten ### Farbe in Discord ungültig (HTTP 400) - Hex-Farbe muss genau 6 Zeichen haben - ✅ Richtig: `0x2ecc71` - ❌ Falsch: `0x2ecc71c` (extra Buchstabe!) --- ## 📊 Features im Detail ### Persistent Storage ```json { "current": "A", "lastReason": "Restaurant bezahlt" } ``` Bleibt erhalten durch Docker Volume Mount. ### Smooth Animations - Rotation-Animation (0.6s) - Background-Transition (0.6s) - Farb-Übergang (0.3s) - Image Preloading --- ## 📜 Lizenz MIT License - Frei nutzbar! --- ## 💡 Tipps ### Custom Domain mit Let's Encrypt ```bash sudo certbot --nginx -d whopays.your-domain.com ``` ### Mehrere Instanzen Unterschiedliche Ports in docker-compose.yml für mehrere Apps! --- **Viel Spaß beim Entscheiden, wer zahlt!** 🎉💸