// ╔══════════════════════════════════════════════════════════════╗ // ║ SMART HOME DEMO — Hi-Fi Dashboard Mockup ║ // ║ Modelliert nach Home Assistant, dark/cyan-Brand-Adaption ║ // ╚══════════════════════════════════════════════════════════════╝ const SMD_PALETTE = { bgDeep: "#071520", bgCard: "#0D2030", bgCard2: "#11283C", accent: "#3ABDD0", soft: "#8DDBEA", text: "#ffffff", textDim: "rgba(255,255,255,0.55)", border: "rgba(141,219,234,0.12)", borderHi: "rgba(58,189,208,0.45)", // chart accents pv: "#F2A65A", // PV warm orange battery: "#5DD3B0", // battery teal-green grid: "#7B9BD3", // grid blue water: "#5BBFD6", // water cyan consumption: "#C28BD9",// purple consumption warm: "#E8A5B5", // warm pink (waschmaschine) }; // ── Mini sparkline ───────────────────────────────────────────── function Sparkline({ data, color = SMD_PALETTE.accent, w = 72, h = 22 }) { const max = Math.max(...data); const min = Math.min(...data); const range = max - min || 1; const pts = data.map((v, i) => { const x = (i / (data.length - 1)) * w; const y = h - ((v - min) / range) * h; return `${x.toFixed(1)},${y.toFixed(1)}`; }).join(" "); return ( ); } // ── Inline Material-style icons (very small, white-line) ─────── const SMDIcons = { light: (c) => , thermo: (c) => , bed: (c) => , kitchen: (c) => , shower: (c) => , sofa: (c) => , desk: (c) => , toilet: (c) => , garage: (c) => , garden: (c) => , attic: (c) => , server: (c) => , device: (c) => , shield: (c) => , media: (c) => , weather: (c) => , bolt: (c) => , scenes: (c) => , presence: (c) => , valve: (c) => , search: (c) => , plus: (c) => , menu: (c) => , edit: (c) => , msg: (c) => , arrowL: (c) => , chevR: (c) => , power: (c) => , // sidebar nav items home: (c) => , grid: (c) => , user: (c) => , building: (c) => , list: (c) => , chart: (c) => , cal: (c) => , wrench: (c) => , bug: (c) => , flow: (c) => , play: (c) => , code: (c) => , link: (c) => , drop: (c) => , cast: (c) => , fire: (c) => , car: (c) => , factory: (c) => , lock: (c) => , }; // ── Path-aware data ──────────────────────────────────────────── const SMD_DATA = { altbau: { welcome: "Familie Bauer", favorites: [ { id: "f1", name: "Wohnzimmer", state: "21,4 °C", icon: "thermo", on: true, color: SMD_PALETTE.pv }, { id: "f2", name: "Garage", state: "Geschlossen", icon: "garage", on: false }, { id: "f3", name: "Außenlicht", state: "Auto", icon: "light", on: true, color: SMD_PALETTE.pv }, { id: "f4", name: "Heizung", state: "Heizmodus", icon: "fire", on: true, color: SMD_PALETTE.warm }, { id: "f5", name: "Hauptschalter", state: "Tag", icon: "scenes", on: true }, { id: "f6", name: "Anwesenheit", state: "Zuhause", icon: "presence", on: true, color: SMD_PALETTE.battery }, ], floors: [ { name: "EG", icon: "home", rooms: [ { id: "wohnzimmer", name: "Wohnzimmer", state: "21,4 °C", icon: "sofa" }, { id: "kueche", name: "Küche", state: "20,1 °C", icon: "kitchen" }, { id: "esszimmer", name: "Esszimmer", state: "20,8 °C", icon: "kitchen" }, { id: "bad", name: "Badezimmer", state: "23,2 °C", icon: "shower" }, { id: "wc", name: "WC", state: "—", icon: "toilet" }, { id: "gang", name: "Gang", state: "19,8 °C", icon: "home" }, ]}, { name: "OG", icon: "home", rooms: [ { id: "schlafzimmer", name: "Schlafzimmer", state: "19,5 °C", icon: "bed" }, { id: "kinderzimmer", name: "Kinderzimmer", state: "20,3 °C", icon: "bed" }, { id: "buero", name: "Büro", state: "19,3 °C", icon: "desk" }, ]}, { name: "Außen", icon: "garden", rooms: [ { id: "garage", name: "Garage", state: "—", icon: "garage" }, { id: "garten", name: "Garten", state: "—", icon: "garden" }, { id: "geraete", name: "Geräte", state: "32 aktiv", icon: "device" }, ]}, ], summaries: [ { name: "Entdeckte Geräte", value: "1 Gerät zum Hinzufügen", icon: "device", color: SMD_PALETTE.accent }, { name: "Beleuchtung", value: "1 ein", icon: "light", color: SMD_PALETTE.pv }, { name: "Raumklima", value: "20,3 °", icon: "thermo", color: SMD_PALETTE.pv }, { name: "Sicherheit", value: "Aufgeschlossen", icon: "shield", color: SMD_PALETTE.warm }, { name: "Mediaplayer", value: "Keine Wiedergabe", icon: "media", color: SMD_PALETTE.consumption }, { name: "Wetter", value: "8,6 °C · Sonnig", icon: "weather", color: SMD_PALETTE.pv }, { name: "Heutige Energie", value: "7,5 kWh", icon: "bolt", color: SMD_PALETTE.accent }, ], energy: { pv: 24.34, battery: 3.6, grid: -13.25, gridCost: -1.19, home: 7.5, water: 365.4, autarkie: 100, eigenverbrauch: 27, einspeisung: 13.25, }, }, neubau: { welcome: "Familie Hofer", favorites: [ { id: "f1", name: "Beschattung", state: "Auto · 60%", icon: "grid", on: true, color: SMD_PALETTE.pv }, { id: "f2", name: "FBH Vorlauf", state: "32,4 °C", icon: "thermo", on: true, color: SMD_PALETTE.warm }, { id: "f3", name: "Lüftung KWL", state: "Stufe 2", icon: "weather", on: true, color: SMD_PALETTE.water }, { id: "f4", name: "Wallbox", state: "Lädt 11 kW", icon: "car", on: true, color: SMD_PALETTE.battery }, { id: "f5", name: "Alarm", state: "Tag-Modus", icon: "shield", on: true }, { id: "f6", name: "Szene Heim", state: "Aktiv", icon: "scenes", on: true, color: SMD_PALETTE.accent }, ], floors: [ { name: "EG", icon: "home", rooms: [ { id: "wohnen", name: "Wohnen/Essen", state: "22,1 °C", icon: "sofa" }, { id: "kueche", name: "Küche", state: "21,8 °C", icon: "kitchen" }, { id: "buero", name: "Homeoffice", state: "21,5 °C", icon: "desk" }, { id: "bad-eg", name: "Bad EG", state: "—", icon: "shower" }, { id: "garderobe", name: "Garderobe", state: "20,9 °C", icon: "home" }, ]}, { name: "OG", icon: "home", rooms: [ { id: "schlafen", name: "Schlafen", state: "19,2 °C", icon: "bed" }, { id: "kind1", name: "Kind 1", state: "20,1 °C", icon: "bed" }, { id: "kind2", name: "Kind 2", state: "20,4 °C", icon: "bed" }, { id: "bad-og", name: "Bad OG", state: "23,5 °C", icon: "shower" }, ]}, { name: "Technik & Außen", icon: "wrench", rooms: [ { id: "technik", name: "Technikraum", state: "KNX online", icon: "server" }, { id: "carport", name: "Carport", state: "Wallbox aktiv", icon: "car" }, { id: "garten", name: "Garten", state: "Bewässerung aus", icon: "garden" }, ]}, ], summaries: [ { name: "KNX-Geräte", value: "84 online · 0 Fehler", icon: "flow", color: SMD_PALETTE.accent }, { name: "Beleuchtung", value: "DALI · 6 ein", icon: "light", color: SMD_PALETTE.pv }, { name: "Raumklima FBH", value: "21,3 °", icon: "thermo", color: SMD_PALETTE.warm }, { name: "KWL", value: "Stufe 2 · 84% Eff.", icon: "weather", color: SMD_PALETTE.water }, { name: "Sicherheit", value: "Tag-Modus aktiv", icon: "shield", color: SMD_PALETTE.battery }, { name: "Wallbox", value: "Lädt · PV-Überschuss", icon: "car", color: SMD_PALETTE.pv }, { name: "Heutige Energie", value: "12,3 kWh", icon: "bolt", color: SMD_PALETTE.accent }, ], energy: { pv: 38.2, battery: 8.4, grid: -18.6, gridCost: -1.74, home: 12.3, water: 142.8, autarkie: 96, eigenverbrauch: 42, einspeisung: 18.6, }, }, gewerbe: { welcome: "Standort Lambach", favorites: [ { id: "f1", name: "Lastspitze", state: "32,4 kW", icon: "bolt", on: true, color: SMD_PALETTE.pv }, { id: "f2", name: "Tagesumsatz", state: "€ 24.860", icon: "chart", on: true, color: SMD_PALETTE.battery }, { id: "f3", name: "KUKA Roboter 1", state: "Bereit", icon: "factory", on: true, color: SMD_PALETTE.accent }, { id: "f4", name: "Zutritt Tor 1", state: "Geschlossen", icon: "lock", on: false }, { id: "f5", name: "Anwesenheit", state: "17 Mitarbeiter", icon: "presence", on: true, color: SMD_PALETTE.accent }, { id: "f6", name: "PV-Feld", state: "24,6 kW Live", icon: "grid", on: true, color: SMD_PALETTE.pv }, ], floors: [ { name: "Halle", icon: "factory", rooms: [ { id: "produktion", name: "Produktion", state: "12 MA · Linie läuft", icon: "factory" }, { id: "werkstatt", name: "Werkstatt", state: "5 MA · KUKA bereit", icon: "wrench" }, { id: "lager", name: "Lager", state: "Tor zu · 2 offen", icon: "garage" }, { id: "ausgabe", name: "Ausgabe", state: "3 Abholungen", icon: "garage" }, ]}, { name: "Büro", icon: "building", rooms: [ { id: "buero", name: "Großraum", state: "22,1 °C", icon: "desk" }, { id: "besprech", name: "Besprechung", state: "Belegt 14:00", icon: "user" }, { id: "empfang", name: "Empfang", state: "—", icon: "user" }, { id: "kueche-bz", name: "Sozialraum", state: "20,8 °C", icon: "kitchen" }, ]}, { name: "Energie & Zutritt", icon: "bolt", rooms: [ { id: "pv", name: "PV-Feld 24 kWp", state: "24,6 kW", icon: "grid" }, { id: "speicher", name: "Speicher 60 kWh", state: "68%", icon: "bolt" }, { id: "wallbox", name: "Wallbox-Park", state: "3/6 lädt", icon: "car" }, { id: "zutritt", name: "Zutrittssystem", state: "12 aktiv", icon: "lock" }, ]}, ], summaries: [ { name: "Anlagen-Status", value: "Alles betriebsbereit", icon: "shield", color: SMD_PALETTE.battery }, { name: "Tagesumsatz", value: "€ 24.860 · +8%", icon: "chart", color: SMD_PALETTE.battery }, { name: "Anwesenheit", value: "17 Mitarbeiter", icon: "presence", color: SMD_PALETTE.accent }, { name: "Werkstatt", value: "KUKA 1 bereit", icon: "factory", color: SMD_PALETTE.accent }, { name: "Leistungsabnahme", value: "32,4 kW · stabil", icon: "bolt", color: SMD_PALETTE.pv }, { name: "Zutritt", value: "Tor 1, 2 zu · Tor 3 offen", icon: "lock", color: SMD_PALETTE.warm }, { name: "PV-Eigenverbrauch", value: "73% heute", icon: "grid", color: SMD_PALETTE.pv }, ], energy: { pv: 184.2, battery: 22.4, grid: -41.6, gridCost: -3.86, home: 132.6, water: 0, autarkie: 78, eigenverbrauch: 73, einspeisung: 41.6, }, }, }; // ── Tile component (favorites + room) ────────────────────────── function SMDTile({ icon, name, state, on, color, accent, large, onClick }) { const Icon = SMDIcons[icon]; const iconColor = on ? (color || SMD_PALETTE.accent) : SMD_PALETTE.textDim; const iconBg = on ? `${(color || SMD_PALETTE.accent)}22` : "rgba(255,255,255,0.04)"; return ( ); } // ── Summary list-row (right rail) ────────────────────────────── function SMDSummaryRow({ icon, name, value, color }) { const Icon = SMDIcons[icon]; return (
{Icon && Icon(color)}
{name}
{value}
); } // ── Sidebar ──────────────────────────────────────────────────── function SMDSidebar({ activeView, onNav, tourActive, tourStep }) { const items = [ { k: "uebersicht", icon: "home", label: "Übersicht" }, { k: "energie", icon: "bolt", label: "Energie" }, { k: "kal", icon: "cal", label: "Kalender" }, ]; // Map of view→index (for cursor highlight during tour) const tourIdx = tourActive ? Math.min(tourStep, items.length - 1) : -1; return ( ); } // ── Top action bar ───────────────────────────────────────────── function SMDTopBar({ title, back, onBack, tabs, activeTab, onTab }) { return (
{back && ( )} {!tabs && (
{title}
)} {tabs && (
{tabs.map((t) => ( ))}
)}
{["plus", "search", "msg", "edit"].map((k) => ( ))}
); } // ── Übersicht View ───────────────────────────────────────────── function SMDOverview({ data, onRoom }) { return (

Willkommen {data.welcome}

{/* Left column */}
{/* Favoriten */}

Favoriten

{data.favorites.map((f) => ( ))}
{/* Floors */} {data.floors.map((floor) => (

{SMDIcons[floor.icon] && SMDIcons[floor.icon](SMD_PALETTE.textDim)} {floor.name}

{floor.rooms.map((r) => ( onRoom && onRoom(r)}/> ))}
))}
{/* Right rail */}

Zusammenfassungen

{data.summaries.map((s, i) => )}
); } const SMD_COMMERCIAL_ROOM_DETAILS = { werkstatt: { pill: { icon: "wrench", text: "5 Mitarbeiter · KUKA Roboter 1 bereit", color: SMD_PALETTE.accent }, stats: [ { icon: "chart", name: "Tagesumsatz", state: "€ 8.420", color: SMD_PALETTE.battery }, { icon: "presence", name: "Anwesenheit", state: "5 / 6 Mitarbeiter", color: SMD_PALETTE.accent }, { icon: "factory", name: "KUKA Roboter 1", state: "Bereit · Auto", color: SMD_PALETTE.pv }, ], panels: [ { title: "Maschinen & Anlagen", tiles: [ { icon: "factory", name: "KUKA Roboter 1", state: "Auto · Zyklus 42 s", color: SMD_PALETTE.pv }, { icon: "wrench", name: "CNC Fräse", state: "Standby", color: SMD_PALETTE.soft }, { icon: "bolt", name: "Druckluft", state: "7,8 bar · OK", color: SMD_PALETTE.battery }, ]}, { title: "Personal & Aufträge", tiles: [ { icon: "presence", name: "Mitarbeiter", state: "5 anwesend", color: SMD_PALETTE.accent }, { icon: "list", name: "Auftrag SM-2418", state: "76% fertig", color: SMD_PALETTE.battery }, { icon: "chart", name: "Heute fakturierbar", state: "€ 8.420", color: SMD_PALETTE.pv }, ]}, { title: "Energie & Sicherheit", tiles: [ { icon: "bolt", name: "Werkstatt-Leistung", state: "4,8 kW", color: SMD_PALETTE.pv }, { icon: "shield", name: "Roboterzelle", state: "Tür verriegelt", color: SMD_PALETTE.battery }, { icon: "weather", name: "Absaugung", state: "Läuft · Filter OK", color: SMD_PALETTE.water }, ]}, ], scenes: [ { id: "start", name: "Werkstatt Start", state: "Licht, Druckluft, Absaugung" }, { id: "pause", name: "Pause", state: "Roboter safe, Druckluft reduziert" }, { id: "schluss", name: "Feierabend", state: "Alles aus, Alarm scharf" }, ], automations: [ { icon: "flow", name: "KUKA Störung", state: "Push + Licht rot", color: SMD_PALETTE.warm }, { icon: "flow", name: "Druckluft Nacht", state: "Leckage-Warnung aktiv", color: SMD_PALETTE.battery }, { icon: "flow", name: "Tagesumsatz Snapshot", state: "17:00 Report", color: SMD_PALETTE.accent }, ], }, produktion: { pill: { icon: "factory", text: "12 Mitarbeiter · Linie läuft", color: SMD_PALETTE.pv }, stats: [ { icon: "chart", name: "Tagesumsatz", state: "€ 16.440", color: SMD_PALETTE.battery }, { icon: "presence", name: "Anwesenheit", state: "12 / 14 Mitarbeiter", color: SMD_PALETTE.accent }, { icon: "bolt", name: "Leistung jetzt", state: "18,6 kW", color: SMD_PALETTE.pv }, ], panels: [ { title: "Linie & Maschinen", tiles: [ { icon: "factory", name: "Linie 1", state: "Produktion", color: SMD_PALETTE.battery }, { icon: "factory", name: "KUKA Roboter 2", state: "Auto · 97%", color: SMD_PALETTE.pv }, { icon: "wrench", name: "Kompressor", state: "OK · 7,9 bar", color: SMD_PALETTE.water }, ]}, { title: "Schicht & Leistung", tiles: [ { icon: "presence", name: "Schicht A", state: "12 anwesend", color: SMD_PALETTE.accent }, { icon: "list", name: "Stückzahl heute", state: "842 Teile", color: SMD_PALETTE.battery }, { icon: "chart", name: "OEE", state: "86%", color: SMD_PALETTE.pv }, ]}, { title: "Umgebung", tiles: [ { icon: "thermo", name: "Hallentemperatur", state: "20,8 °C", color: SMD_PALETTE.warm }, { icon: "weather", name: "Luftqualität", state: "CO₂ 612 ppm", color: SMD_PALETTE.water }, { icon: "shield", name: "Sicherheitskreis", state: "Geschlossen", color: SMD_PALETTE.battery }, ]}, ], scenes: [ { id: "schichtstart", name: "Schichtstart", state: "Linie freigeben" }, { id: "störung", name: "Störung", state: "Warnlicht + Eskalation" }, { id: "reinigung", name: "Reinigung", state: "Maschinen safe" }, ], automations: [ { icon: "flow", name: "Lastspitze Produktion", state: "Aktiv", color: SMD_PALETTE.pv }, { icon: "flow", name: "Störung Linie 1", state: "Eskalation aktiv", color: SMD_PALETTE.warm }, { icon: "flow", name: "Schichtreport", state: "15:00 / 23:00", color: SMD_PALETTE.accent }, ], }, lager: { pill: { icon: "garage", text: "2 Mitarbeiter · Tore überwacht", color: SMD_PALETTE.soft }, stats: [ { icon: "chart", name: "Warenausgang", state: "€ 6.120", color: SMD_PALETTE.battery }, { icon: "presence", name: "Anwesenheit", state: "2 Mitarbeiter", color: SMD_PALETTE.accent }, { icon: "garage", name: "Tore", state: "Tor 1 zu · Tor 2 offen", color: SMD_PALETTE.warm }, ], panels: [ { title: "Logistik", tiles: [ { icon: "garage", name: "Tor 1", state: "Geschlossen", color: SMD_PALETTE.battery }, { icon: "garage", name: "Tor 2", state: "Offen seit 6 min", color: SMD_PALETTE.warm }, { icon: "list", name: "Kommissionierung", state: "14 / 21 erledigt", color: SMD_PALETTE.accent }, ]}, { title: "Bestand & Klima", tiles: [ { icon: "thermo", name: "Lagertemperatur", state: "18,4 °C", color: SMD_PALETTE.warm }, { icon: "weather", name: "Luftfeuchte", state: "46%", color: SMD_PALETTE.water }, { icon: "shield", name: "Nachtmodus", state: "Automatisch", color: SMD_PALETTE.battery }, ]}, { title: "Energie", tiles: [ { icon: "bolt", name: "Lager Verbrauch", state: "1,9 kW", color: SMD_PALETTE.pv }, { icon: "light", name: "Licht Gänge", state: "Präsenzgeführt", color: SMD_PALETTE.pv }, { icon: "flow", name: "Tor-Heizung", state: "Aus", color: SMD_PALETTE.soft }, ]}, ], scenes: [ { id: "warenannahme", name: "Warenannahme", state: "Tor + Licht" }, { id: "kommission", name: "Kommissionierung", state: "Zonenlicht aktiv" }, { id: "lager-nacht", name: "Lager Nacht", state: "Tore prüfen" }, ], automations: [ { icon: "flow", name: "Tor offen > 10 min", state: "Warnung aktiv", color: SMD_PALETTE.warm }, { icon: "flow", name: "Lagerlicht Präsenz", state: "Aktiv", color: SMD_PALETTE.battery }, { icon: "flow", name: "Warenausgang Report", state: "17:30", color: SMD_PALETTE.accent }, ], }, buero: { pill: { icon: "desk", text: "8 Mitarbeiter · Raumklima OK", color: SMD_PALETTE.accent }, stats: [ { icon: "chart", name: "Tagesumsatz", state: "€ 9.310", color: SMD_PALETTE.battery }, { icon: "presence", name: "Anwesenheit", state: "8 / 10 Mitarbeiter", color: SMD_PALETTE.accent }, { icon: "thermo", name: "Klima Büros", state: "21,8 °C", color: SMD_PALETTE.warm }, ], panels: [ { title: "Bürokomfort", tiles: [ { icon: "light", name: "Arbeitslicht", state: "Automatik", color: SMD_PALETTE.pv }, { icon: "thermo", name: "Heizung/Kühlung", state: "21,8 °C", color: SMD_PALETTE.warm }, { icon: "weather", name: "CO₂", state: "684 ppm", color: SMD_PALETTE.water }, ]}, { title: "Team & Zutritt", tiles: [ { icon: "presence", name: "Mitarbeiter", state: "8 anwesend", color: SMD_PALETTE.accent }, { icon: "lock", name: "Büro-Zutritt", state: "Offen bis 18:00", color: SMD_PALETTE.battery }, { icon: "cal", name: "Besprechung", state: "14:00 belegt", color: SMD_PALETTE.soft }, ]}, { title: "Betrieb", tiles: [ { icon: "bolt", name: "Büro-Verbrauch", state: "2,1 kW", color: SMD_PALETTE.pv }, { icon: "server", name: "UniFi Netzwerk", state: "Online", color: SMD_PALETTE.battery }, { icon: "chart", name: "Anfragen heute", state: "18", color: SMD_PALETTE.accent }, ]}, ], scenes: [ { id: "arbeit", name: "Arbeitszeit", state: "Licht + Klima" }, { id: "meeting", name: "Meeting", state: "Beschattung + Display" }, { id: "büro-aus", name: "Feierabend", state: "Standby + Zutritt" }, ], automations: [ { icon: "flow", name: "CO₂ Meetingraum", state: "Aktiv", color: SMD_PALETTE.water }, { icon: "flow", name: "Büro Feierabend", state: "18:15", color: SMD_PALETTE.battery }, { icon: "flow", name: "Umsatz-Snapshot", state: "16:00", color: SMD_PALETTE.accent }, ], }, }; function getSMDCommercialProfile(room) { const id = room?.id || ""; if (SMD_COMMERCIAL_ROOM_DETAILS[id]) return SMD_COMMERCIAL_ROOM_DETAILS[id]; if (/buero|besprech|empfang|kueche/.test(id)) return SMD_COMMERCIAL_ROOM_DETAILS.buero; if (/lager|ausgabe/.test(id)) return SMD_COMMERCIAL_ROOM_DETAILS.lager; if (/produktion/.test(id)) return SMD_COMMERCIAL_ROOM_DETAILS.produktion; return SMD_COMMERCIAL_ROOM_DETAILS.werkstatt; } function SMDCommercialRoomDetail({ room }) { const profile = getSMDCommercialProfile(room); const [scene, setScene] = React.useState(profile.scenes[0]?.id || "start"); React.useEffect(() => { setScene(profile.scenes[0]?.id || "start"); }, [room?.id]); const Section = ({ title, children }) => (

{title} {SMDIcons.chevR(SMD_PALETTE.textDim)}

{children}
); const PillIcon = SMDIcons[profile.pill.icon] || SMDIcons.factory; return (
{PillIcon(profile.pill.color)} {profile.pill.text}
{profile.stats.map((s) => ( ))}
{profile.panels.map((panel) => (
{panel.tiles.map((t) => ( ))}
))}
{profile.scenes.map((s) => { const active = scene === s.id; return ( ); })}
{profile.automations.map((a) => ( ))}
); } // ── Room Detail (Büro) ───────────────────────────────────────── function SMDRoomDetail({ room, onBack }) { // Static deep-detail for "Büro" — works for all paths as a sample room const [scene, setScene] = React.useState("buero-hell"); const [dim, setDim] = React.useState(5); const [temp, setTemp] = React.useState(5.0); const Section = ({ title, action, children }) => (

{title} {SMDIcons.chevR(SMD_PALETTE.textDim)}

{action}
{children}
); return (
{/* temperature pill (centered) */}
{SMDIcons.thermo(SMD_PALETTE.warm)} 19,3 °C
{/* Beleuchtung */}
{SMDIcons.power(SMD_PALETTE.pv)} Ein }>
{SMDIcons.light(SMD_PALETTE.pv)}
Decke Büro
{dim} %
setDim(parseInt(e.target.value))} style={{ width: "100%", height: 6, accentColor: SMD_PALETTE.pv, cursor: "pointer", }}/>
{/* Raumklima */}
{SMDIcons.fire(SMD_PALETTE.warm)}
Thermostat
Heizbetrieb
{temp.toFixed(1)} °C
{/* Mediaplayer */}
{SMDIcons.cast(SMD_PALETTE.accent)}
Alexa Büro
Pausiert
{/* Szenen */}
{[ { id: "nacht", name: "Nachtlicht", state: "Vor 3 Jahren" }, { id: "buero-hell", name: "Büro Hell", state: "Vor 3 Jahren" }, { id: "gedimmt", name: "Gedimmt", state: "Unbekannt" }, { id: "fokus", name: "Fokus", state: "Letzte Woche" }, ].map((s) => { const active = scene === s.id; return ( ); })}
{/* Hardware groups */}

Hauptschalter Büro

Thermostat — Detail

Präsenz Büro

{/* Automation */}

{SMDIcons.flow(SMD_PALETTE.textDim)} Automationen

); } // ── Energy distribution diagram ──────────────────────────────── function SMDEnergyDist({ e }) { // 4 nodes around center "Home" — PV top, Water right, Battery bottom, Grid left const cx = 220, cy = 200; const nodeR = 38; const dist = 130; const nodes = { pv: { x: cx, y: cy - dist, label: "PV", value: `${e.pv.toFixed(1)} kWh`, color: SMD_PALETTE.pv, icon: "bolt" }, water: { x: cx + dist, y: cy, label: "Wasser", value: `${e.water.toFixed(0)} L`, color: SMD_PALETTE.water, icon: "drop" }, battery: { x: cx, y: cy + dist, label: "Batterie", value: `${e.battery > 0 ? '↓' : '↑'} ${Math.abs(e.battery).toFixed(2)} kWh`, color: SMD_PALETTE.warm, icon: "bolt" }, grid: { x: cx - dist, y: cy, label: "Netz", value: `${e.grid > 0 ? '→' : '←'} ${Math.abs(e.grid).toFixed(2)} kWh`, color: SMD_PALETTE.grid, icon: "factory" }, home: { x: cx, y: cy, label: "Home", value: `${e.home.toFixed(1)} kWh`, color: SMD_PALETTE.accent, icon: "home" }, }; const Node = ({ n, big }) => { const r = big ? nodeR : nodeR; const Icon = SMDIcons[n.icon]; return (
{Icon && Icon(n.color)}
{n.value}
{n.label}
); }; // curved paths between nodes (PV→Home, Battery→Home, Grid→Home, Water→Home) const Path = ({ from, to, color, dashed }) => { const fx = from.x, fy = from.y, tx = to.x, ty = to.y; // simple quadratic curve toward center const mx = (fx + tx) / 2, my = (fy + ty) / 2; return ( ); }; // animated dots along path (approx via small circles + animateMotion) const FlowDot = ({ from, to, color, dur = 3 }) => ( ); return ( ); } // ── Bar chart (stacked-ish) ──────────────────────────────────── function SMDBarChart({ values, colors, height = 180, max, min = 0, suffix = "kW", label }) { // values: array of {pos: [up bars], neg: [down bars]} per timestep const w = 520, h = height; const padL = 36, padR = 12, padT = 12, padB = 22; const innerH = h - padT - padB; const innerW = w - padL - padR; const range = max - min; const zeroY = padT + (max / range) * innerH; const barW = innerW / values.length * 0.6; const slot = innerW / values.length; const yTicks = []; const tickStep = (max - min) / 4; for (let i = 0; i <= 4; i++) { const v = max - tickStep * i; yTicks.push({ v: Number(v.toFixed(1)), y: padT + (i / 4) * innerH }); } return ( {/* y-axis ticks + grid */} {yTicks.map((t, i) => ( {t.v} ))} {/* unit */} {suffix} {/* bars */} {values.map((step, i) => { const x = padL + slot * i + (slot - barW) / 2; let yPos = zeroY; let yNeg = zeroY; return ( {step.pos && step.pos.map((seg, j) => { const segH = (seg / range) * innerH; yPos -= segH; return ; })} {step.neg && step.neg.map((seg, j) => { const segH = (Math.abs(seg) / range) * innerH; const r = ; yNeg += segH; return r; })} ); })} {/* x labels (every 4th) */} {values.map((_, i) => i % 4 === 0 && ( {`${i}:00`} ))} ); } // ── Area chart (PV vs grid) ──────────────────────────────────── function SMDAreaChart({ height = 180 }) { const w = 520, h = height; const padL = 36, padR = 12, padT = 12, padB = 22; const innerH = h - padT - padB; const innerW = w - padL - padR; // Bell curve PV + smaller grid line const N = 24; const pv = Array.from({length: N}, (_, i) => { const x = (i - 12) / 5; return Math.max(0, 12 * Math.exp(-x*x) + (Math.random() - 0.5) * 1.2); }); pv[0] = 0; pv[N-1] = 0; pv[3] = 0; pv[4] = 0.4; pv[5] = 1.2; const grid = pv.map((v, i) => i > 6 && i < 14 ? Math.max(0, v - 4 - Math.random()) : v * 0.3); const max = 14; const toX = (i) => padL + (i / (N-1)) * innerW; const toY = (v) => padT + innerH - (v / max) * innerH; const pvPath = pv.map((v, i) => `${i === 0 ? 'M' : 'L'}${toX(i)},${toY(v)}`).join(" ") + ` L${toX(N-1)},${toY(0)} L${toX(0)},${toY(0)} Z`; const gridPath = grid.map((v, i) => `${i === 0 ? 'M' : 'L'}${toX(i)},${toY(v)}`).join(" ") + ` L${toX(N-1)},${toY(0)} L${toX(0)},${toY(0)} Z`; return ( {[0, 4, 8, 12, 14].map((v, i) => { const y = toY(v); return ( {v} ); })} kW `${i === 0 ? 'M' : 'L'}${toX(i)},${toY(v)}`).join(" ")} fill="none" stroke={SMD_PALETTE.pv} strokeWidth="1.5"/> {[0, 4, 8, 12, 16, 20].map((hr, i) => ( {`${hr}:00`} ))} ); } // ── Energy Source row ────────────────────────────────────────── function SMDQuelle({ color, name, value, cost }) { return (
{name}
{value}
{cost}
); } // ── Energy View ──────────────────────────────────────────────── function SMDEnergyView({ data }) { const e = data.energy; // build mock bar data const N = 24; const usage = Array.from({length: N}, (_, i) => { const isDay = i > 6 && i < 18; return { pos: isDay ? [Math.max(0, (Math.random()-0.5) * 2 + 1.2)] : [0], neg: !isDay ? [-Math.random() * 1.2 - 0.3] : [], }; }); return (
{/* Energieverteilung */}

Energieverteilung

{SMDIcons.chevR(SMD_PALETTE.textDim)}
{/* Quellen-Tabelle + KPIs */}

Quellen

Quelle
Verbrauch
Kosten
0 ? '−' : ''}${Math.abs(e.battery).toFixed(2)} kWh`} cost=""/>
{/* KPI gauges */}
{/* Charts row */}

Stromquellen

Stromnutzung

+{e.home.toFixed(1)} kWh
{/* Per-device consumption */}

Gesamtverbrauch · Einzelgeräte

Heute · pro Gerät
); } const SMD_DEVICES = [ { name: "Büro EG", color: "#C8A88A", kwh: 4.3 }, { name: "Werkstatt", color: "#E89BB4", kwh: 2.8 }, { name: "Küche & Esszimmer", color: "#7AA8E0", kwh: 1.4 }, { name: "Speisekammer", color: "#7DBC7D", kwh: 1.2 }, { name: "Wärmepumpe", color: "#A0AED9", kwh: 0.7 }, { name: "Büro OG", color: "#5DC8A8", kwh: 0.6 }, { name: "Audio Wohnzimmer", color: "#E8C76E", kwh: 0.45 }, { name: "Saugroboter", color: "#5DC8A8", kwh: 0.4 }, { name: "Mediawand", color: "#9DD9C2", kwh: 0.32 }, { name: "Badezimmer", color: "#A8D5E8", kwh: 0.22 }, { name: "Kaffeemaschine", color: "#E07B6B", kwh: 0.18 }, { name: "Außenbeleuchtung", color: "#B89DDB", kwh: 0.12 }, { name: "Sauna", color: "#C29DD9", kwh: 0.08 }, { name: "Waschmaschine", color: "#E8C76E", kwh: 0.05 }, ]; function SMDDeviceList() { const max = Math.max(...SMD_DEVICES.map(d => d.kwh)); const labelW = 168; return (
{SMD_DEVICES.map((d, i) => { const pct = (d.kwh / max) * 100; return (
{d.name}
{d.kwh.toFixed(2)} kWh
); })}
012345 kWh
); } // ── Gauge (semi-circle) ──────────────────────────────────────── function SMDGauge({ value, max, label, suffix, color, wide }) { const pct = Math.min(1, Math.max(0, value / max)); const r = 50, cx = 70, cy = 60; // Halbkreis von links (180°) nach rechts (0°), oben offen const x1 = cx - r; // 20, 60 const y1 = cy; // 60 const xEnd = cx + r; // 120, 60 const yEnd = cy; // Länge des kompletten Halbkreis-Pfads = π · r const arcLen = Math.PI * r; const dashOffset = arcLen * (1 - pct); return (
{/* Hintergrund-Bogen */} {/* Wert-Bogen via dasharray, klippt sauber bei 0% und 100% */} {value.toFixed(value >= 10 || suffix === " %" ? 0 : 2)}{suffix}
{label}
); } // ── Main DEMO component ──────────────────────────────────────── function SmartHomeDemo({ pathKey }) { const data = SMD_DATA[pathKey] || SMD_DATA.altbau; const [view, setView] = React.useState("uebersicht"); // uebersicht | raum | energie const [room, setRoom] = React.useState(null); const [eTab, setETab] = React.useState("Zusammenfassung"); const onRoom = (r) => { setRoom(r); setView("raum"); }; const onBack = () => { setView("uebersicht"); setRoom(null); }; const onNav = (k) => { if (k === "uebersicht" || k === "raum") { setView("uebersicht"); setRoom(null); } else if (k === "energie") setView("energie"); }; let title, tabs, activeTab, onTab; if (view === "energie") { tabs = ["Zusammenfassung", "Strom", "Wasser", "Jetzt"]; activeTab = eTab; onTab = setETab; } else if (view === "raum") { title = room?.name || "Raum"; } else { title = "Übersicht"; } return (
{view === "uebersicht" && } {view === "raum" && (pathKey === "gewerbe" ? : )} {view === "energie" && }
); } // ── Section wrapper for the landing page ─────────────────────── function SmartHomeDemoSection({ pathKey }) { const isGewerbe = pathKey === "gewerbe"; return (
LIVE-DEMO

So sieht{" "} {isGewerbe ? "dein Objekt" : "dein Zuhause"} {" "} aus.

{isGewerbe ? "Eine Betriebsoberfläche aus dem Alltag — klick dich durch Bereiche, Zutritt, Technikstatus und Energiedashboard. Dein Objekt wird ähnlich strukturiert: mit deinen Flächen, deinen Anlagen, deinen Werten." : "Eine echte Konfiguration aus dem Alltag — klick dich durch Räume, Szenen und das Energiedashboard. Dein Setup wird ähnlich aussehen, mit deinen Räumen, deinen Geräten, deinen Werten."}

↑ Sidebar zeigt Hauptbereiche
· {isGewerbe ? "Bereiche klickbar — Detail mit Kennzahlen + Anlagen" : "Räume klickbar — Detail mit Szenen + Geräten"}
· Energie-Tab zeigt PV-Fluss, Quellen, Autarkiegrad
); } window.SmartHomeDemoSection = SmartHomeDemoSection; window.SmartHomeDemo = SmartHomeDemo; // Im Konfigurator (Step 2) bauen wir den Room-Detail dynamisch fuer den // aktuellen Raum nach -- Komponenten + Palette dafuer exposen. window.SMD_PALETTE = SMD_PALETTE; window.SMDIcons = SMDIcons; window.SMDTile = SMDTile;