import { useEffect, useRef, useState } from 'react' import { HUSTLER_STUFE } from '../../../lib/hustlerStufe' import HochhausKopf from './HochhausKopf' import HochhausWelt from './HochhausWelt' import HustlerDialog from './HustlerDialog' import RegieEbene from './RegieEbene' // Von welchem Bildschirm man zurückkommt -> Etage, über die man gegangen war (Freigabe-Pult über die Etage „freigabe“, Keller über „keller“) const ETAGE_NACH_TAB = Object.freeze({ freigabe: 'freigabe', botleads: 'keller' }) // Überschrift der Seite, nur für Screenreader (Pult und Keller haben ihre eigene sichtbare Überschrift) function Ueberschrift() { return

Hustler – Hochhaus

} // Bildschirm „Hochhaus“: Spielwelt mit Regie-Ebene (T5, T8), Kopfzeile (T6) und Detailansicht eines Hustlers (T7). Zustände wie bisher im WorkersBoard. // Reine Darstellung ohne Auth-Bezug: isAdmin, der Feed (feed = { state, error, loaded, refresh }), die Hustler-Tabelle (workers), die Regie-Anbindung // (regieRef, die Seite ruft regieRef.current.push(events) bei neuen Ereignissen), der Bildschirmwechsel (onOpen(tab)) und vonTab (der Bildschirm, von dem man // zurückkommt: 'freigabe' | 'botleads' | null) kommen von der Seite. Beim Zurückkommen bekommt die Etage, über die man gegangen war, den Fokus (M2). // Die Kopfzeile steht im DOM vor der Welt, damit die Tab-Reihenfolge oben beginnt (M7); über der Welt liegt sie per z-index. // stufe (Standard HUSTLER_STUFE, hustlerStufe.js) geht an die Welt (Keller-Etage als Link nur ab Stufe 6) und an die Detailansicht (Spur-Links in den Keller nur ab Stufe 6). // Kein CSS-Import und keine Bilder: die Stile hängt WorkersPage ein (Regeln dieser Datei in styles/hustler/hustler-ui.css). export default function Hochhaus({ api, isAdmin, feed, workers, regieRef, onOpen, vonTab = null, stufe = HUSTLER_STUFE }) { const wurzelRef = useRef(null) const weltRef = useRef(null) const [auswahl, setAuswahl] = useState(null) // workerId der offenen Detailansicht (null = keine) const ready = feed.loaded && Boolean(feed.state) // Rückweg aus Pult oder Keller: Fokus auf die Etage, über die man ging (erst wenn die Welt steht; die Kamera holt sie bei Tastaturfokus ins Bild) useEffect(() => { if (!ready || !vonTab || !Object.hasOwn(ETAGE_NACH_TAB, vonTab)) return const wurzel = wurzelRef.current if (!wurzel || typeof wurzel.querySelector !== 'function') return const etage = wurzel.querySelector(`[data-hk-etage="${ETAGE_NACH_TAB[vonTab]}"]`) if (etage && typeof etage.focus === 'function') etage.focus({ preventScroll: true }) }, [ready, vonTab]) // Dienst noch nie erreicht: Pixel-Leerzustand mit Fehlertext und „Neu laden“ if (!ready && feed.error) { return (
Der Hustler-Dienst ist noch nicht erreichbar

{feed.error}

) } if (!ready) { return (
Wird geladen …
) } // Die Regie-Ebene liegt in der skalierten Bühne (Weltkoordinaten); ihr Handle ist regieRef der Seite, die neue Ereignisse hineinreicht. // Solange die Detailansicht offen ist, ruhen Rad, Ziehen und Tasten der Kamera (gesperrt). return (
{ if (weltRef.current) weltRef.current.ganz() }} /> {auswahl !== null && ( setAuswahl(null)} onWechsel={setAuswahl} /> )}
) }