import { useEffect, useLayoutEffect, useState } from 'react'; import type { ThemeMode } from './components/AppSettingsWindow'; import CanvasStudio from './pages/CanvasStudio'; import FindPage from './pages/FindPage'; import HelpPage from './pages/HelpPage'; import OrdersPage from './pages/OrdersPage'; import TemplateHome from './pages/TemplateHome'; import TestWorkbench from './pages/TestWorkbench'; import { CanvasDocument, WordcloudReplaceSession, WordcloudStickerPayload } from './types'; import { createDefaultDocument } from './lib/canvasDocument'; type AppPage = 'home' | 'canvas' | 'wordcloud' | 'orders' | 'find' | 'help'; const getStoredTheme = (): ThemeMode => { const stored = window.localStorage.getItem('wordcloud-theme'); return stored === 'light' || stored === 'dark' || stored === 'system' ? stored : 'system'; }; const getSystemTheme = () => window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'; export default function App() { const [page, setPage] = useState('home'); const [themeMode, setThemeMode] = useState(getStoredTheme); const [systemTheme, setSystemTheme] = useState<'light' | 'dark'>(getSystemTheme); const [initialDocument, setInitialDocument] = useState(null); const [pendingWordcloudSticker, setPendingWordcloudSticker] = useState(null); const [pendingReplaceSession, setPendingReplaceSession] = useState(null); const openHelp = () => setPage('help'); useLayoutEffect(() => { const resolvedTheme = themeMode === 'system' ? systemTheme : themeMode; document.documentElement.dataset.theme = resolvedTheme; document.documentElement.dataset.themeMode = themeMode; document.documentElement.style.colorScheme = resolvedTheme; window.localStorage.setItem('wordcloud-theme', themeMode); }, [themeMode, systemTheme]); useEffect(() => { const media = window.matchMedia('(prefers-color-scheme: dark)'); const handleChange = (event: MediaQueryListEvent) => { setSystemTheme(event.matches ? 'dark' : 'light'); }; setSystemTheme(media.matches ? 'dark' : 'light'); media.addEventListener('change', handleChange); return () => media.removeEventListener('change', handleChange); }, []); if (page === 'wordcloud') { return ( setPage('canvas')} onOpenHome={() => setPage('home')} onOpenHelp={openHelp} replaceSession={pendingReplaceSession} onConsumeReplaceSession={() => setPendingReplaceSession(null)} onImportWordcloudSticker={(payload) => { setPendingWordcloudSticker(payload); setPendingReplaceSession(null); setPage('canvas'); }} /> ); } if (page === 'canvas') { return ( setPage('home')} onOpenWordcloud={() => { setPendingReplaceSession(null); setPage('wordcloud'); }} onOpenHelp={openHelp} onReplaceWordcloudNames={(session) => { setPendingReplaceSession(session); setPage('wordcloud'); }} initialDocument={initialDocument} onConsumeInitialDocument={() => setInitialDocument(null)} pendingWordcloudSticker={pendingWordcloudSticker} onConsumeWordcloudSticker={() => setPendingWordcloudSticker(null)} /> ); } if (page === 'help') { return ( setPage('home')} onOpenCanvas={() => setPage('canvas')} onOpenWordcloud={() => setPage('wordcloud')} onOpenOrders={() => setPage('orders')} onOpenFind={() => setPage('find')} /> ); } if (page === 'orders') { return ( setPage('home')} /> ); } if (page === 'find') { return ( setPage('home')} /> ); } return ( { setInitialDocument(createDefaultDocument()); setPage('canvas'); }} onUseTemplate={(template) => { setInitialDocument(template.document); setPage('canvas'); }} onOpenOrders={() => setPage('orders')} onOpenFind={() => setPage('find')} onOpenHelp={openHelp} /> ); }