import { h } from 'preact'; import { useState, useRef, useEffect } from 'preact/hooks'; interface Props { mode: 'view' | 'edit'; onOpenManual: (section?: string) => void; } const TIPS: Record> = { view: [ { text: 'Click any interface in the left panel to load it on the canvas.', section: 'view' }, { text: 'Right-click a widget to view signal info or export data as CSV.', section: 'view' }, { text: 'The ● Live button shows live streaming is active. Use the date pickers to load historical data.', section: 'history' }, { text: 'Click Edit (top-right) to open the drag-and-drop panel builder.', section: 'edit' }, { text: 'The dot in the status chip turns green when the WebSocket is connected.', section: 'view' }, ], edit: [ { text: 'Drag a signal from the left tree onto the canvas to create a widget.', section: 'edit' }, { text: 'Click a widget to select it, then adjust its properties on the right.', section: 'edit' }, { text: 'Ctrl+click to select multiple widgets; then use the align toolbar.', section: 'edit' }, { text: 'Ctrl+Z to undo, Ctrl+Y to redo. Up to 50 steps are remembered.', section: 'shortcuts' }, { text: 'Use "+ Synthetic" in the signal tree to create computed/filtered signals.', section: 'signals' }, { text: 'Arrow keys nudge the selected widget by 1 px (Shift for grid size).', section: 'shortcuts' }, ], }; export default function ContextualHelp({ mode, onOpenManual }: Props) { const [open, setOpen] = useState(false); const [tipIndex, setTipIndex] = useState(0); const ref = useRef(null); const tips = TIPS[mode]; // Close on outside click useEffect(() => { if (!open) return; function handler(e: MouseEvent) { if (ref.current && !ref.current.contains(e.target as Node)) { setOpen(false); } } document.addEventListener('mousedown', handler); return () => document.removeEventListener('mousedown', handler); }, [open]); // Cycle to a new random tip each time the popover opens function handleOpen() { setTipIndex(t => (t + 1) % tips.length); setOpen(o => !o); } const tip = tips[tipIndex]; return (
{open && ( )}
); }