import { useEffect, useRef, useState } from 'react' import type { SaveStatus } from '../../hooks/useAutoSave' import { StatsPanel } from './StatsPanel' import { SoundToggle } from './SoundToggle' interface Props { wordCount: number // Live plain text of the document, for the expanded stats panel. text: string saveStatus: SaveStatus // True while a grammar checkpoint is in flight — shows the breathing rose dot. checking: boolean // True while a whole-document voice pass runs — shows a breathing honey dot. voicing: boolean // True when Petal can't reach its LLM helper — shows a gentle, reassuring note // (the writing still saves locally, so this is awareness, not an error). llmDown: boolean } const SAVE_LABEL: Record = { idle: '', pending: 'Editing…', saving: 'Saving…', saved: 'Saved just now', error: "Couldn't save", } // StatusBar is the slim footer: word count on the left, save state and the // grammar-checkpoint indicator on the right. The checkpoint dot is a soft rose // circle that breathes while a check is in flight (spec → Signature animations). export function StatusBar({ wordCount, text, saveStatus, checking, voicing, llmDown }: Props) { const label = SAVE_LABEL[saveStatus] // The expanded stats panel toggles open when the word count is clicked. const [statsOpen, setStatsOpen] = useState(false) const statsRef = useRef(null) useEffect(() => { if (!statsOpen) return const onDown = (e: MouseEvent) => { if (!statsRef.current?.contains(e.target as Node)) setStatsOpen(false) } document.addEventListener('mousedown', onDown) return () => document.removeEventListener('mousedown', onDown) }, [statsOpen]) return ( ) }