diff --git a/.vscode/settings.json b/.vscode/settings.json index 981728e..55dd248 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -11,5 +11,6 @@ "string_view": "cpp", "initializer_list": "cpp", "regex": "cpp" - } + }, + "liveServer.settings.multiRootWorkspaceName": "AquaMasterMQTT" } \ No newline at end of file diff --git a/API.md b/API.md new file mode 100644 index 0000000..cc76f8f --- /dev/null +++ b/API.md @@ -0,0 +1,109 @@ +# API- und Routenbeschreibung für das AquaMaster-Projekt + +Diese Datei beschreibt alle HTTP-Routen (API und statische Seiten) für das AquaMaster-Projekt. Sie dient als Referenz für Frontend-Entwickler. + +--- + +## Statische Seiten + +| Route | Methode | Beschreibung | Antwort (Content-Type) | +|-----------------|---------|-------------------------------------|------------------------| +| `/` | GET | Hauptseite (Timer) | HTML | +| `/settings` | GET | Einstellungen-Seite | HTML | +| `/about` | GET | Info-/About-Seite | HTML | +| `/` (static) | GET | Statische Dateien (CSS, Bilder, JS) | entspr. MIME-Type | + +--- + +## API-Routen + +### Timer & Daten + +| Route | Methode | Beschreibung | Body/Parameter | Antwort (Content-Type) | +|-------------------|---------|-------------------------------------|------------------------|--------------------------------| +| `/api/data` | GET | Aktuelle Timerdaten und Status | – | JSON | + +**Beispiel-Response:** +```json +{ + "time1": 12.34, + "status1": "running", + "time2": 0, + "status2": "ready", + "best1": 10.12, + "best2": 9.87, + "learningMode": false, + "learningButton": "Start Bahn 1" +} +``` + +--- + +### Bestzeiten + +| Route | Methode | Beschreibung | Body/Parameter | Antwort (Content-Type) | +|----------------------|---------|-------------------------------------|------------------------|--------------------------------| +| `/api/reset-best` | POST | Setzt Bestzeiten zurück | – | `{ "success": true }` | + +--- + +### Button-Lernmodus + +| Route | Methode | Beschreibung | Body/Parameter | Antwort (Content-Type) | +|--------------------------|---------|-------------------------------------|------------------------|--------------------------------| +| `/api/start-learning` | POST | Startet Lernmodus | – | `{ "success": true }` | +| `/api/stop-learning` | POST | Beendet Lernmodus | – | `{ "success": true }` | +| `/api/learn/status` | GET | Status des Lernmodus | – | `{ "active": true, "step": 1 }`| +| `/api/unlearn-button` | POST | Löscht alle Button-Zuordnungen | – | `{ "success": true }` | +| `/api/buttons/status` | GET | Status der Button-Zuordnung | – | JSON (siehe unten) | + +**Beispiel-Response für `/api/buttons/status`:** +```json +{ + "lane1Start": true, + "lane1Stop": false, + "lane2Start": true, + "lane2Stop": false +} +``` + +--- + +### Einstellungen + +| Route | Methode | Beschreibung | Body/Parameter | Antwort (Content-Type) | +|------------------------|---------|-------------------------------------|------------------------|--------------------------------| +| `/api/set-max-time` | POST | Setzt max. Laufzeit & max. Anzeigezeit | `maxTime` (Sekunden, optional), `maxTimeDisplay` (Sekunden, optional) als Form-Parameter | `{ "success": true }` oder `{ "success": false }` | +| `/api/get-settings` | GET | Liefert aktuelle Einstellungen | – | `{ "maxTime": 300, "maxTimeDisplay": 20 }` | + +--- + +### Systeminfo + +| Route | Methode | Beschreibung | Antwort (Content-Type) | +|-------------------|---------|-------------------------------------|--------------------------------| +| `/api/info` | GET | Systeminfos (IP, MAC, Speicher, Lizenz, verbundene Buttons) | JSON (siehe unten) | + +**Beispiel-Response:** +```json +{ + "ip": "192.168.4.1", + "channel": 1, + "mac": "AA:BB:CC:DD:EE:FF", + "freeMemory": 123456, + "connectedButtons": 3, + "valid": "Ja", + "tier": 1 +} +``` + +--- + +## Hinweise + +- **Alle API-Routen liefern JSON zurück.** +- **POST-Requests erwarten ggf. Form-Parameter (kein JSON-Body).** +- **Statische Seiten und Assets werden direkt ausgeliefert.** +- **Kein Authentifizierungsverfahren implementiert.** + +--- \ No newline at end of file diff --git a/data/index.css b/data/index.css new file mode 100644 index 0000000..4cad1fc --- /dev/null +++ b/data/index.css @@ -0,0 +1,302 @@ +html { + overflow: hidden; + height: 100%; + width: 100%; + } + + * { + margin: 0; + padding: 0; + box-sizing: border-box; + } + + body { + font-family: "Arial", sans-serif; + background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); + height: 100vh; + width: 100vw; + display: flex; + flex-direction: column; + align-items: center; + padding: 20px; + color: white; + position: relative; + overflow: hidden; + box-sizing: border-box; + } + + .logo { + position: fixed; + top: 20px; + left: 20px; + width: 200px; + height: 60px; + z-index: 1000; + border-radius: 10px; + box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2); + transition: transform 0.3s ease; + text-decoration: none; + display: block; + cursor: pointer; + padding-left: 5px; + padding-right: 5px; + } + + .logo:hover { + transform: scale(1.1); + } + + .logo img { + width: 100%; + height: 100%; + object-fit: contain; + border-radius: 10px; + } + + .settings-btn { + position: fixed; + top: 20px; + right: 20px; + background: rgba(255, 255, 255, 0.2); + border: 2px solid rgba(255, 255, 255, 0.3); + color: white; + padding: 15px; + border-radius: 50%; + text-decoration: none; + font-size: 1.5rem; + transition: all 0.3s ease; + z-index: 1000; + width: 60px; + height: 60px; + display: flex; + align-items: center; + justify-content: center; + } + + .settings-btn:hover { + background: rgba(255, 255, 255, 0.3); + border-color: rgba(255, 255, 255, 0.5); + transform: scale(1.1); + } + + .header { + text-align: center; + margin-bottom: 2vh; + flex-shrink: 0; + } + + .header h1 { + font-size: clamp(1.8rem, 4vw, 2.5rem); + margin-bottom: 0.5vh; + text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.3); + } + + .header p { + font-size: clamp(0.8rem, 1.8vw, 1rem); + } + + .timer-container { + display: grid; + grid-template-columns: 1fr 1fr; + gap: clamp(15px, 2vw, 30px); + width: 100%; + max-width: 100%; + flex-grow: 1; + padding: 0 2vw; + max-height: 60vh; + } + + @media (max-width: 768px) { + .timer-container { + grid-template-columns: 1fr; + gap: clamp(15px, 3vw, 30px); + padding: 0 15px; + } + } + + @media (max-width: 480px) { + .timer-container { + gap: 20px; + padding: 0 10px; + } + } + + @media (min-width: 1400px) { + .timer-container { + max-width: 1400px; + padding: 0 60px; + } + } + + .lane { + background: rgba(255, 255, 255, 0.1); + backdrop-filter: blur(10px); + border-radius: 20px; + padding: clamp(15px, 2.5vh, 25px); + text-align: center; + border: 1px solid rgba(255, 255, 255, 0.2); + box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1); + transition: transform 0.3s ease; + display: flex; + flex-direction: column; + justify-content: center; + height: 100%; + overflow: hidden; + } + + .lane h2 { + font-size: clamp(1.2rem, 2.5vw, 1.8rem); + margin-bottom: clamp(10px, 1vh, 15px); + color: #fff; + } + + .time-display { + font-size: clamp(3rem, 9vw, 10rem); + font-weight: bold; + margin: clamp(10px, 1vh, 15px) 0; + font-family: "Courier New", monospace; + text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.3); + line-height: 1; + } + + .status { + font-size: clamp(3rem, 1.8vw, 1.2rem); + margin: clamp(8px, 1vh, 12px) 0; + padding: clamp(6px, 1vh, 10px) clamp(12px, 2vw, 18px); + border-radius: 20px; + display: inline-block; + font-weight: 600; + } + + .status.ready { + background-color: rgba(52, 152, 219, 0.3); + border: 2px solid #3498db; + } + + .status.running { + background-color: rgba(46, 204, 113, 0.3); + border: 2px solid #2ecc71; + animation: pulse 1s infinite; + } + + .status.finished { + background-color: rgba(231, 76, 60, 0.3); + border: 2px solid #e74c3c; + } + + @keyframes pulse { + 0% { + opacity: 1; + } + 50% { + opacity: 0.7; + } + 100% { + opacity: 1; + } + } + + .best-times { + background: rgba(255, 255, 255, 0.15); + backdrop-filter: blur(10px); + border-radius: 15px; + padding: clamp(10px, 1.5vh, 15px); + margin: 1vh 0 0 0; + width: 50%; + max-width: 50%; + text-align: center; + border: 1px solid rgba(255, 255, 255, 0.2); + flex-shrink: 0; + align-self: center; + } + + .best-times h3 { + font-size: clamp(0.9rem, 1.8vw, 1.1rem); + margin-bottom: clamp(5px, 0.5vh, 8px); + } + + .best-time-row { + display: flex; + justify-content: space-between; + margin: clamp(3px, 0.5vh, 5px) 0; + font-size: clamp(0.8rem, 1.5vw, 1rem); + font-weight: 500; + background: rgba(255, 255, 255, 0.1); + padding: clamp(5px, 1vh, 8px) clamp(8px, 1.5vw, 12px); + border-radius: 8px; + } + + .learning-mode { + background: rgba(255, 193, 7, 0.2); + border: 2px solid #ffc107; + border-radius: 15px; + padding: clamp(15px, 2vh, 20px); + margin: 2vh 0; + text-align: center; + animation: pulse 2s infinite; + width: 100%; + position: absolute; + top: 15vh; + left: 50%; + transform: translateX(-50%); + z-index: 100; + } + + .learning-mode h3 { + color: #ffc107; + margin-bottom: 10px; + font-size: clamp(1rem, 2vw, 1.3rem); + } + + .learning-mode p { + font-size: clamp(0.9rem, 1.8vw, 1.1rem); + } + + @media (max-width: 768px) { + .timer-container { + grid-template-columns: 1fr; + gap: clamp(10px, 2vh, 15px); + padding: 0 3vw; + max-height: 55vh; + } + + .settings-btn { + top: 10px; + right: 10px; + width: 40px; + height: 40px; + font-size: 1rem; + padding: 8px; + } + + .header h1 { + font-size: clamp(1.5rem, 4vw, 2rem); + } + + .header p { + font-size: clamp(0.7rem, 2vw, 0.9rem); + } + + body { + padding: 10px; + } + } + + @media (max-width: 480px) { + .settings-btn { + top: 8px; + right: 8px; + width: 35px; + height: 35px; + font-size: 0.9rem; + padding: 6px; + } + + body { + padding: 8px; + } + + .timer-container { + padding: 0 2vw; + } + } \ No newline at end of file diff --git a/data/index.html b/data/index.html index 172b663..b2d408f 100644 --- a/data/index.html +++ b/data/index.html @@ -4,314 +4,11 @@ NinjaCross Timer - + ⚙️ diff --git a/data/logo.png b/data/pictures/logo.png similarity index 100% rename from data/logo.png rename to data/pictures/logo.png diff --git a/data/settings.html b/data/settings.html index 90498da..71e8c50 100644 --- a/data/settings.html +++ b/data/settings.html @@ -5,343 +5,7 @@ Ninjacross Timer - Einstellungen - +