const { useState, useEffect } = React; const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{ "density": "comfy", "palette": "warm", "accent": "tomaat", "showSauzenOnCard": true }/*EDITMODE-END*/; function App() { const [view, setView] = useState(() => localStorage.getItem('npd-view') || 'kanban'); const [pickedId, setPickedId] = useState(null); const [newOpen, setNewOpen] = useState(false); const [tweaks, setTweaks] = useState(TWEAK_DEFAULTS); const [tweaksOpen, setTweaksOpen] = useState(false); const [search, setSearch] = useState(''); const [, setRevision] = useState(0); useEffect(() => { localStorage.setItem('npd-view', view); }, [view]); // Apply palette / accent to body useEffect(() => { document.body.className = `palette-${tweaks.palette} accent-${tweaks.accent}` + (tweaks.density === 'compact' ? ' density-compact' : ''); }, [tweaks]); // Edit-mode protocol useEffect(() => { const handler = (e) => { if (e.data?.type === '__activate_edit_mode') setTweaksOpen(true); if (e.data?.type === '__deactivate_edit_mode') setTweaksOpen(false); }; window.addEventListener('message', handler); window.parent.postMessage({ type: '__edit_mode_available' }, '*'); return () => window.removeEventListener('message', handler); }, []); useEffect(() => { const handler = () => { setRevision((value) => value + 1); setPickedId((currentId) => { if (!currentId) return currentId; return window.PROJECTEN.some((project) => project.id === currentId) ? currentId : null; }); }; window.addEventListener('dashboard:data-changed', handler); return () => window.removeEventListener('dashboard:data-changed', handler); }, []); const picked = pickedId ? (window.PROJECTEN.find((project) => project.id === pickedId) || null) : null; const handleSetView = (nextView) => { setView(nextView); setPickedId(null); }; const onPick = (p) => setPickedId(p?.id || null); const onCreated = (projectId) => { setNewOpen(false); const freshProject = window.PROJECTEN.find((project) => project.id === projectId); if (freshProject) setPickedId(freshProject.id); }; return (