Hustler-Pixelwelt T3: Seite hält den Feed, Bildschirme Hochhaus/Pult/Keller, Vollhöhen-Rahmen
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
8bd365b1fc
commit
d8912ee363
5 files changed
+527
-23
No files matched your search
+63
-14
@@ -1,15 +1,22 @@
|
||||
import { useEffect } from 'react'
|
||||
import { useCallback, useEffect, useRef, useState } from 'react'
|
||||
import { useSearchParams } from 'react-router-dom'
|
||||
import { PageHeader, Tabs } from '../components/ui'
|
||||
import BotLeadList from '../components/workers/BotLeadList'
|
||||
import Hochhaus from '../components/workers/hochhaus/Hochhaus'
|
||||
import PultList from '../components/workers/PultList'
|
||||
import WorkersBoard from '../components/workers/WorkersBoard'
|
||||
import { useAuth } from '../context/AuthContext'
|
||||
import { useWorkersFeed } from '../hooks/useWorkersFeed'
|
||||
import { indexWorkers, reduceEvents } from '../lib/workersEvents'
|
||||
import { workersApi } from '../lib/workersClient'
|
||||
import { pickTab } from '../lib/workersView'
|
||||
import '../styles/workers.css'
|
||||
import '../styles/hustler/schrift.css'
|
||||
import '../styles/hustler/hochhaus.css'
|
||||
import '../styles/hustler/keller.css'
|
||||
import '../styles/hustler/pult.css'
|
||||
import '../styles/hustler/hustler-ui.css'
|
||||
|
||||
// Reiter der Seite (Hochhaus, Freigabe von P3, Bot-Leads von P6); die Reiterleiste erscheint erst ab zwei Reitern.
|
||||
// Bildschirme der Seite: das Hochhaus, das Pult (Freigabe von P3) und der Keller (Bot-Leads von P6). Eine Reiterleiste gibt es nicht mehr;
|
||||
// gewechselt wird im Haus (Etage Freigabe, Etage Keller) und über „◂ Hochhaus“ in Pult und Keller.
|
||||
const WORKERS_TABS = [
|
||||
{ id: 'hochhaus', label: 'Hochhaus' },
|
||||
{ id: 'freigabe', label: 'Freigabe' },
|
||||
@@ -18,14 +25,18 @@ const WORKERS_TABS = [
|
||||
|
||||
const api = workersApi
|
||||
|
||||
// Seite „Hustler“ (Dateiname bleibt WorkersPage): Titel, Reiterwahl über ?tab= und der Inhalt des gewählten Reiters.
|
||||
// ?tab=botleads&bot=<Id> (Link aus dem Ereignisstrom) zeigt einen einzelnen Bot-Lead; ein Reiterwechsel lässt bot weg.
|
||||
// Auth und Dienst-API kommen von hier; das Board selbst kennt weder Anmeldung noch Appwrite.
|
||||
// Seite „Hustler“ (Dateiname bleibt WorkersPage): Tab-Titel, Bildschirmwahl über ?tab= und der gewählte Bildschirm in voller Höhe.
|
||||
// ?tab=botleads&bot=<Id> (Link aus dem Ereignisstrom) zeigt einen einzelnen Bot-Lead; ein Wechsel per setParams lässt bot weg.
|
||||
// Auth und Dienst-API kommen von hier. Der Feed (Zustand alle 15 s, Ereignisse alle 5 s) läuft genau einmal pro Seite, egal welcher
|
||||
// Bildschirm offen ist; die Hustler-Tabelle (indexWorkers beim Schnappschuss, reduceEvents bei Ereignissen) gehört ebenfalls hierher.
|
||||
// Ereignisse gehen zusätzlich an die Regie, die nur das Hochhaus über regieRef einhängt.
|
||||
export default function WorkersPage() {
|
||||
const { isAdmin, user } = useAuth()
|
||||
const [params, setParams] = useSearchParams()
|
||||
const active = pickTab(WORKERS_TABS, params.get('tab'))
|
||||
const bot = params.get('bot') ?? ''
|
||||
const [workers, setWorkers] = useState({})
|
||||
const regieRef = useRef(null)
|
||||
|
||||
// Tab-Titel nur solange die Seite offen ist; beim Verlassen kommt der vorige Titel zurück
|
||||
useEffect(() => {
|
||||
@@ -34,15 +45,53 @@ export default function WorkersPage() {
|
||||
return () => { document.title = previous }
|
||||
}, [])
|
||||
|
||||
// Neue Ereignisse: Tabelle fortschreiben und der Regie vorspielen (die Regie kennt den Rückstau selbst)
|
||||
const onEvents = useCallback((events) => {
|
||||
setWorkers((w) => reduceEvents(w, events))
|
||||
if (regieRef.current) regieRef.current.push(events)
|
||||
}, [])
|
||||
|
||||
const { state, error, loaded, refresh } = useWorkersFeed(api, { onEvents })
|
||||
useEffect(() => {
|
||||
if (state) setWorkers(indexWorkers(state))
|
||||
}, [state])
|
||||
|
||||
return (
|
||||
<div className="page wk-page">
|
||||
<PageHeader title="Hustler" subtitle="Die Nachtschicht deiner Claude-Armee" />
|
||||
{WORKERS_TABS.length > 1 && (
|
||||
<Tabs tabs={WORKERS_TABS} active={active.id} onChange={(id) => setParams({ tab: id })} />
|
||||
<div className="hk-seite" data-tab={active.id}>
|
||||
{active.id === 'hochhaus' && (
|
||||
<Hochhaus
|
||||
api={api}
|
||||
isAdmin={isAdmin}
|
||||
feed={{ state, error, loaded, refresh }}
|
||||
workers={workers}
|
||||
regieRef={regieRef}
|
||||
onOpen={(tab) => setParams({ tab })}
|
||||
/>
|
||||
)}
|
||||
{/* Pult und Keller stecken bis T9/T10 noch in der alten hellen Hülle (.page.wk-page); hustler-ui.css gibt ihnen dafür normale Höhe */}
|
||||
{active.id === 'freigabe' && (
|
||||
<div className="page wk-page">
|
||||
<PultList
|
||||
api={api}
|
||||
me={{ id: user?.$id, name: user?.name }}
|
||||
kpis={state?.kpis}
|
||||
workers={workers}
|
||||
onBack={() => setParams({ tab: 'hochhaus' })}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
{active.id === 'botleads' && (
|
||||
<div className="page wk-page">
|
||||
<BotLeadList
|
||||
api={api}
|
||||
bot={bot}
|
||||
onClearBot={() => setParams({ tab: 'botleads' })}
|
||||
kpis={state?.kpis}
|
||||
workers={workers}
|
||||
onBack={() => setParams({ tab: 'hochhaus' })}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
{active.id === 'hochhaus' && <WorkersBoard api={api} isAdmin={isAdmin} />}
|
||||
{active.id === 'freigabe' && <PultList api={api} me={{ id: user?.$id, name: user?.name }} />}
|
||||
{active.id === 'botleads' && <BotLeadList api={api} bot={bot} onClearBot={() => setParams({ tab: 'botleads' })} />}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
Reference in new issue
Block a user