readme
This commit is contained in:
1 parent
3ccc38fd17
commit
6bcf4f704b
1 file changed
+360
@@ -0,0 +1,360 @@
|
||||
# 💸 WhoPays - Who Pays Next?
|
||||
|
||||
Ein einfaches, elegantes Tool um zu entscheiden, wer als nächstes zahlt - mit Discord-Benachrichtigungen und PWA-Support!
|
||||
|
||||

|
||||

|
||||

|
||||
|
||||
## 🎯 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!** 🎉💸
|
||||
Reference in new issue
Block a user