// src/app.jsx — Root App with routing + Tweaks const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{ "palette": "editorial", "typography": "grotesk" }/*EDITMODE-END*/; // Páginas con deep-link ?page= const VALID_PAGES = ['presentacion', 'equipo', 'noticias', 'formacion', 'gestores', 'colegios-miembros', 'snde', 'admision', 'tnde', 'colegios', 'calendario']; const pageFromURL = () => { try { const params = new URLSearchParams(window.location.search); const q = params.get('admin'); if (q === 'noticias' || q === '1') return 'noticias-admin'; const p = params.get('page'); if (p && VALID_PAGES.includes(p)) return p; } catch (e) {} return 'presentacion'; }; const App = () => { // Si la URL pide modo admin (?admin=noticias o legacy ?admin=1), arrancamos en esa página. // ?page= permite deep-links (p. ej. el magic link de miembros vuelve a ?page=colegios-miembros). const [page, setPageState] = React.useState(pageFromURL); const [t, setTweak] = useTweaks(TWEAK_DEFAULTS); // Navegación interna → la URL refleja la página (links copiables desde la barra de direcciones) const setPage = React.useCallback((p) => { setPageState(p); try { const url = new URL(window.location); url.searchParams.delete('page'); url.searchParams.delete('admin'); url.searchParams.delete('nota'); url.hash = ''; if (p === 'noticias-admin') url.searchParams.set('admin', 'noticias'); else if (p !== 'presentacion') url.searchParams.set('page', p); window.history.pushState({ page: p }, '', url); } catch (e) {} }, []); // Botón atrás/adelante del navegador React.useEffect(() => { const onPop = () => setPageState(pageFromURL()); window.addEventListener('popstate', onPop); return () => window.removeEventListener('popstate', onPop); }, []); // Ancla al LLEGAR desde un link externo (p. ej. ?page=noticias#publicaciones): // la página hace scroll-top al montar, así que el scroll al ancla va con retardo. React.useEffect(() => { const h = window.location.hash; if (!h) return; const tid = setTimeout(() => { const el = document.getElementById(h.slice(1)); if (el) el.scrollIntoView({ behavior: 'smooth', block: 'start' }); }, 450); return () => clearTimeout(tid); }, []); // Apply tweak attrs to body React.useEffect(() => { if (t.palette === 'default') document.body.removeAttribute('data-palette'); else document.body.setAttribute('data-palette', t.palette); if (t.typography === 'editorial') document.body.removeAttribute('data-type'); else document.body.setAttribute('data-type', t.typography); }, [t.palette, t.typography]); const renderPage = () => { switch (page) { case 'presentacion': return ; case 'equipo': return ; case 'noticias': return ; case 'noticias-admin': return ; case 'formacion': return ; case 'gestores': return ; case 'colegios-miembros': return ; case 'snde': return ; case 'admision': return ; case 'tnde': return ; case 'colegios': return ; case 'calendario': return ; default: return ; } }; return (
{renderPage()}