diff --git a/apps/ui/main.py b/apps/ui/main.py index 8f04b53..b78d8d7 100644 --- a/apps/ui/main.py +++ b/apps/ui/main.py @@ -77,6 +77,19 @@ async def index(request: Request) -> HTMLResponse: return await dashboard(request) +@app.get("/rooms", response_class=HTMLResponse) +async def rooms(request: Request) -> HTMLResponse: + """Render the rooms overview page. + + Args: + request: The FastAPI request object + + Returns: + HTMLResponse: Rendered rooms template + """ + return templates.TemplateResponse("rooms.html", {"request": request}) + + @app.get("/dashboard", response_class=HTMLResponse) async def dashboard(request: Request) -> HTMLResponse: """Render the dashboard with rooms and devices. diff --git a/apps/ui/redesign_ui.txt b/apps/ui/redesign_ui.txt new file mode 100644 index 0000000..62a8f15 --- /dev/null +++ b/apps/ui/redesign_ui.txt @@ -0,0 +1,188 @@ +/** +Copilot-Aufgabe: Erzeuge eine neue Home-Dashboard-Seite mit Raum-Kacheln. + +Ziel: +Die Seite soll alle Räume als kleine Kacheln darstellen. Auf dem iPhone +sollen immer zwei Kacheln nebeneinander passen. Jede Kachel zeigt: +- Raumname +- Icon (z. B. Wohnzimmer, Küche, Bad, etc.) basierend auf room_id oder einem Mapping +- Anzahl der Geräte im Raum +- Optional: Zusammenfassung wichtiger States (z.B. Anzahl offener Fenster, aktive Lichter) + +Datenquelle: +- GET /layout → { "rooms": [{ "name": "...", "devices": [...] }] } + (Achtung: rooms ist ein Array, kein Dictionary!) +- GET /devices → Geräteliste für Feature-Checks + +Interaktion: +- Beim Klick/Touch auf eine Raum-Kachel → Navigation zu /room/{room_name} + +Layout-Anforderungen: +- 2-Spalten-Grid auf kleinen Screens (max-width ~ 600px) +- 3–4 Spalten auf größeren Screens +- Kachelgröße kompakt (ca. 140px x 110px) +- Icon ~32px +- Text ~14–16px +- Responsive via CSS-Grid oder Flexbox +- Minimaler Einsatz von Tailwind (bevorzugt vanilla CSS) + +Akzeptanzkriterien: +- Die Seite lädt alle Räume über die API (fetch). +- Räume werden in der Reihenfolge aus layout.yaml angezeigt. +- Jede Kachel zeigt: Icon + Raumname + Geräteanzahl. +- iPhone-Darstellung verifiziert: zwei Kacheln nebeneinander. +- Funktionierende Navigation zu /room/{room_name}. +- Die Komponente ist vollständig lauffähig. +- Fehlerbehandlung bei API-Fehlern implementiert. +*/ + +/** +Copilot-Aufgabe: Erzeuge eine Geräte-Grid-Ansicht für einen Raum. + +Ziel: +Die Seite zeigt alle Geräte, die in diesem Raum laut layout.yaml liegen. +Die Darstellung erfolgt als kompakte Kacheln, ebenfalls 2 Spalten auf iPhone. + +Datenquelle: +- GET /layout → Räume + device_id + title +- GET /devices → Typ + Features +- GET /devices/{id}/state (optional zur Initialisierung) +- Live-Updates: SSE /realtime + +Auf einer Gerät-Kachel sollen erscheinen: +- passendes Icon (abhängig von type) +- title (aus layout) +- wichtigste Eigenschaft aus dem State: + - light: power on/off oder brightness in % + - thermostat: current temperature + - contact: open/closed + - temp_humidity: temperature und/oder humidity + - outlet: on/off + - cover: position % + +Interaktion: +- Klick/Touch → Navigation zu /device/{device_id} + +Akzeptanzkriterien: +- Der Raum wird anhand room_id aus der URL geladen. +- Geräte werden über Join(layout, devices) des Raums selektiert. +- Kacheln sind 2-spaltig auf iPhone. +- State wird initial geladen und per SSE aktualisiert. +- Navigation zu /device/{id} funktioniert. +- Icons passend zum Typ generiert. +*/ + +/** +Copilot-Aufgabe: Erzeuge eine Detailansicht für ein einzelnes Gerät. + +Ziel: +Die Seite zeigt: +- Titel des Geräts (title aus layout) +- Raumname +- Gerätetyp +- State-Werte aus GET /devices/{id}/state +- Live-Updates via SSE +- Steuer-Elemente abhängig vom type + features: + - light: toggle, brightness-slider, optional color-picker + - thermostat: target-temp-slider + - outlet: toggle + - contact: nur Anzeige + - temp_humidity: nur Anzeigen von Temperatur/Humidity + - cover: position-slider und open/close/stop Buttons + +API-Integration: +- Set-Kommandos senden via POST /devices/{id}/set +- Validierung: Nur unterstützte Features sichtbar machen + +UI-Vorgaben: +- Kompakt, aber komplett +- Buttons gut für Touch erreichbar +- Slider in voller Breite +- Werte (temperature, humidity, battery) übersichtlich gruppiert + +Akzeptanzkriterien: +- Device wird korrekt geladen (layout + devices + state). +- Steuerung funktioniert (light on/off, brightness, target temp etc.). +- SSE aktualisiert alle angezeigten Werte live. +- Fehler (z. B. POST /set nicht erreichbar) werden UI-seitig angezeigt. +*/ + +/** +Copilot-Aufgabe: Erzeuge einen API-Client für das UI. + +Der Client soll bereitstellen: +- getLayout(): Layout-Daten +- getDevices(): Device-Basisdaten +- getDeviceState(device_id) +- setDeviceState(device_id, type, payload) +- connectRealtime(onEvent): SSE-Listener + +Anforderungen: +- API_BASE aus .env oder UI-Konfiguration +- Fehlerbehandlung +- Timeout optional +- Types für: + - Room + - Device + - DeviceState + - RealtimeEvent + +Akzeptanzkriterien: +- Der Client ist voll funktionsfähig und wird im UI genutzt. +- Ein Hook useRealtime(device_id) wird erzeugt. +- Ein Hook useRooms() and useDevices() existieren. +*/ + +/** +Copilot-Aufgabe: Erzeuge das UI-Routing. + +Routen: +- "/" → Home (Räume) +- "/room/:roomId" → RoomView +- "/device/:deviceId" → DeviceView + +Anforderungen: +- React Router v6 oder v7 +- Layout-Komponente optional +- Loading/Fehlerzustände +- Responsive Verhalten beibehalten + +Akzeptanzkriterien: +- Navigation funktioniert zwischen allen Seiten. +- Browser-Back funktioniert erwartungsgemäß. +- Routes unterstützen Refresh ohne Fehler. +*/ + +/** +Copilot-Aufgabe: Implementiere einen React-Hook useRealtime(deviceId: string | null). + +Ziel: +- SSE-Stream /realtime abonnieren +- Nur Events für deviceId liefern +- onMessage → setState +- automatische Reconnects +- Fehlerlogging + +Akzeptanz: +- Der Hook kann in RoomView & DeviceView genutzt werden. +- Live-Updates werden korrekt gemerged. +- Disconnect/Reload funktioniert sauber. +*/ + +/** +Copilot-Aufgabe: Erzeuge eine Icon-Komponente. + +Ziel: +Basierend auf device.type und ggf. features ein passendes SVG ausliefern: +- light → Lightbulb +- thermostat → Thermostat +- contact → Door/Window-Sensor +- temp_humidity → Thermometer+Droplet +- outlet → Power-Plug +- cover → Blinds/Rollershutter + +Akzeptanz: +- Icons skalieren sauber +- funktionieren in allen Kachel-Komponenten +*/ + diff --git a/apps/ui/templates/rooms.html b/apps/ui/templates/rooms.html new file mode 100644 index 0000000..0486b58 --- /dev/null +++ b/apps/ui/templates/rooms.html @@ -0,0 +1,306 @@ + + + + + + Räume - Home Automation + + + + ← Dashboard + +
+

🏠 Räume

+ +
+
Lade Räume...
+ +
+ + + +