Vierter Eintrag der Funktionen-Gruppe (nach der News-Pinnwand, „Bald verfügbar“, ohne Preis):
- Website: Bäckerei Sonnenschein mit großer Status-Pille und Hinweis-Leiste „Betriebsurlaub 12.–26. Oktober“
(gleitet per transform ein, der Inhalt rückt nach), Desktop und Handy.
- Handy-Ebene: Finger tippt „Hinweis-Leiste anlegen“ (HINWEIS_PUNKT, Platzhalter bis zur Aufnahme).
- Uhr-Regler: echter Schieberegler unter dem MacBook (inaktiv: aria-hidden + inert) und in der Handy-Karte.
- ZeitenSteuerung (setzeUhr(null) beim Verlassen), lazy-Chunks, Kundenportal importiert aus ablauf.ts nur Typen.
- Pins in relaunch-kundenportal.test.tsx auf neun Stationen angepasst (Als App = Marke 8), Spezifikations-Zähler mitgezogen.
ACHTUNG: public/relaunch/portal/phone-12-zeiten-{390,780}.webp sind vorläufig Kopien von phone-9-termine
(damit Build und Tests laufen); Task 36 ersetzt sie durch die echte Aufnahme.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
71 lines
2.9 KiB
TypeScript
71 lines
2.9 KiB
TypeScript
import { memo, useEffect } from "react";
|
|
import { useTerminAblauf, type TerminZustand } from "./termin/ablauf";
|
|
import { useHeatmapAblauf, type HeatmapZustand } from "./heatmap/ablauf";
|
|
import { usePinnwandAblauf, type PinnwandZustand } from "./pinnwand/ablauf";
|
|
import { useChatAblauf, type ChatZustand } from "./chat/ablauf";
|
|
import { useZeitenAblauf, type ZeitenZustand } from "./zeiten/ablauf";
|
|
|
|
/**
|
|
* Taktgeber der Demos (vier Funktionen und der Chat) als unsichtbare Bauteile (rendern nichts, melden nur ihren Zustand).
|
|
* Sie liegen in einem eigenen Chunk, damit die Startseite die Ablauf-Logik erst lädt, wenn die Kundenportal-Bühne
|
|
* eine Demo-Station fast erreicht (Spezifikation 4). Die Bühne hält den gemeldeten Zustand und gibt denselben
|
|
* Zustand an Website, Handy-Ebene und Diagnose.
|
|
* `laeuft` und `statisch` kommen von useDemoLauf (Station aktiv, im Bild, Tab sichtbar, Bewegung erlaubt).
|
|
* Die Bauteile sind memoisiert: sie rechnen nur neu, wenn sich ihr eigener Ablauf bewegt, nicht bei jedem Rendern der Bühne.
|
|
*/
|
|
|
|
type Props<Z> = { laeuft: boolean; statisch: boolean; onZustand: (zustand: Z) => void };
|
|
|
|
export const TerminSteuerung = memo(function TerminSteuerung({ laeuft, statisch, onZustand }: Props<TerminZustand>) {
|
|
const zustand = useTerminAblauf(laeuft, statisch);
|
|
useEffect(() => onZustand(zustand), [zustand, onZustand]);
|
|
return null;
|
|
});
|
|
|
|
export const PinnwandSteuerung = memo(function PinnwandSteuerung({ laeuft, statisch, onZustand }: Props<PinnwandZustand>) {
|
|
const zustand = usePinnwandAblauf(laeuft, statisch);
|
|
useEffect(() => onZustand(zustand), [zustand, onZustand]);
|
|
return null;
|
|
});
|
|
|
|
export const ChatSteuerung = memo(function ChatSteuerung({ laeuft, statisch, onZustand }: Props<ChatZustand>) {
|
|
const zustand = useChatAblauf(laeuft, statisch);
|
|
useEffect(() => onZustand(zustand), [zustand, onZustand]);
|
|
return null;
|
|
});
|
|
|
|
/** `aktiv`: Station ist die aktive; sonst bleiben weder Maus-Zustand noch Auswahl der Heatmap hängen. */
|
|
export const HeatmapSteuerung = memo(function HeatmapSteuerung({
|
|
laeuft,
|
|
statisch,
|
|
aktiv,
|
|
onZustand,
|
|
}: Props<HeatmapZustand> & { aktiv: boolean }) {
|
|
const zustand = useHeatmapAblauf(laeuft, statisch);
|
|
const { setzeMaus, waehle } = zustand;
|
|
useEffect(() => {
|
|
if (!aktiv) {
|
|
setzeMaus(false);
|
|
waehle(null);
|
|
}
|
|
}, [aktiv, setzeMaus, waehle]);
|
|
useEffect(() => onZustand(zustand), [zustand, onZustand]);
|
|
return null;
|
|
});
|
|
|
|
/** `aktiv`: Station ist die aktive; sonst geht eine Bedienung des Uhr-Reglers zurück an den Ablauf (beim nächsten Mal von vorn). */
|
|
export const ZeitenSteuerung = memo(function ZeitenSteuerung({
|
|
laeuft,
|
|
statisch,
|
|
aktiv,
|
|
onZustand,
|
|
}: Props<ZeitenZustand> & { aktiv: boolean }) {
|
|
const zustand = useZeitenAblauf(laeuft, statisch);
|
|
const { setzeUhr } = zustand;
|
|
useEffect(() => {
|
|
if (!aktiv) setzeUhr(null);
|
|
}, [aktiv, setzeUhr]);
|
|
useEffect(() => onZustand(zustand), [zustand, onZustand]);
|
|
return null;
|
|
});
|