import React, { useEffect, useState } from 'react'; import './App.css'; import { applyPolyfills, defineCustomElements } from 'wcs-core/loader'; import Departs from './pages/Departs'; import Arrivees from './pages/Arrivees'; import Displays from './pages/Displays'; import ClassiquesDeparts from './pages/afficheurs/classiques/ClassiquesDeparts'; import ClassiquesArrivees from './pages/afficheurs/classiques/ClassiquesArrivees'; import ClassiquesDepartsQuais from './pages/afficheurs/classiques/quais/ClassiquesDepartsQuais'; import ClassiquesArriveesQuais from './pages/afficheurs/classiques/quais/ClassiquesArriveesQuais'; import AFLDeparts from './pages/afficheurs/afl/AFLDeparts'; import AFLArrivees from './pages/afficheurs/afl/AFLArrivees'; import AFLDepartsQuais from './pages/afficheurs/afl/AFLDepartsQuais'; import AFLArriveesQuais from './pages/afficheurs/afl/AFLArriveesQuais'; import EVAArrivees from './pages/afficheurs/eva/EVAArrivees'; import EVADeparts from './pages/afficheurs/eva/EVADeparts'; import SelectAfficheur from './pages/SelectAfficheur'; import AfficheurViewportWrapper from './components/AfficheurViewportWrapper'; import sessionMemory from './lib/sessionMemory'; import { getSourceFromPath } from './services/railwayService'; applyPolyfills().then(() => defineCustomElements(window)); // Petit routeur client sans dépendances externes function useSimpleRouter() { function normalizePath(p) { if (!p) return '/'; // retirer query string et hash p = String(p).split(/[?#]/)[0]; if (p.indexOf('index.html') !== -1) return '/'; p = p.trim(); if (p !== '/') p = p.replace(/\/+$/, ''); return p || '/'; } const [route, setRoute] = useState(() => normalizePath(window.location.pathname || '/')); useEffect(() => { const onPop = () => { const p = normalizePath(window.location.pathname || '/'); console.debug('[router] popstate ->', p); setRoute(p); }; window.addEventListener('popstate', onPop); return () => window.removeEventListener('popstate', onPop); }, []); function navigate(path) { const target = normalizePath(path); const currentFull = window.location.pathname + (window.location.search || '') + (window.location.hash || ''); if (currentFull !== path) { console.debug('[router] navigate ->', path, '(normalized ->', target, ')'); try { window.history.pushState({}, '', path); } catch (e) { try { window.history.pushState({}, '', target); } catch (err) {} } setRoute(target); } else { setRoute(target); } } return { route, navigate }; } function App() { const { route, navigate } = useSimpleRouter(); const source = getSourceFromPath(route); const prefix = source === 'supabase' ? '/ferrovia' : ''; const cleanRoute = (route.replace(/^\/ferrovia/, '') || '/'); // Composant Home explicite (panels cliquables) function Home({ navigate, prefix, source }) { const panelStyle = { width: '42%', cursor: 'pointer', padding: 24, borderRadius: 10, boxShadow: '0 4px 12px rgba(0,0,0,0.08)', background: '#fff', textAlign: 'center', border: '1px solid #e0e8f6', transition: 'transform 0.15s ease' }; return (
{source === 'supabase' ? 'Mode Base de Données (Ferrovia)' : 'Mode Officiel SNCF (GTFS / Temps Réel)'}

Accueil

{source === 'supabase' ? "Consultez les afficheurs basés sur les données de votre BDD Supabase." : "Consultez les afficheurs connectés aux flux réels GTFS et Open Data SNCF."}

{ try { sessionMemory.set('afficheurMode', 'departs'); } catch (e) {} navigate(`${prefix}/departs`); }} onKeyDown={(e) => (e.key === 'Enter' || e.key === ' ' ? (function(){ try { sessionMemory.set('afficheurMode', 'departs'); } catch (e) {} navigate(`${prefix}/departs`); })() : null)} style={panelStyle} aria-label="Accéder aux départs" >

🚆 Départs

Consultez les prochains départs d'une gare. Choisissez une gare et le style d'afficheur.

{ try { sessionMemory.set('afficheurMode', 'arrivees'); } catch (e) {} navigate(`${prefix}/arrivees`); }} onKeyDown={(e) => (e.key === 'Enter' || e.key === ' ' ? (function(){ try { sessionMemory.set('afficheurMode', 'arrivees'); } catch (e) {} navigate(`${prefix}/arrivees`); })() : null)} style={panelStyle} aria-label="Accéder aux arrivées" >

🏁 Arrivées

Consultez les prochaines arrivées d'une gare en temps réel.

); } // Routes pour afficheurs : supporte le mode racine ET le mode /ferrovia if (cleanRoute.startsWith('/afficheurs/departs/classiques/quais')) { return ; } if (cleanRoute.startsWith('/afficheurs/arrivees/classiques/quais')) { return ; } if (cleanRoute.startsWith('/afficheurs/departs/classiques')) { return ; } if (cleanRoute.startsWith('/afficheurs/departs/afl/quais')) { return ; } if (cleanRoute.startsWith('/afficheurs/departs/afl')) { return ; } if (cleanRoute.startsWith('/afficheurs/departs/eva')) { return ; } if (cleanRoute.startsWith('/afficheurs/arrivees/afl/quais')) { return ; } if (cleanRoute.startsWith('/afficheurs/arrivees/afl')) { return ; } if (cleanRoute.startsWith('/afficheurs/arrivees/eva')) { return ; } if (cleanRoute.startsWith('/afficheurs/arrivees/classiques')) { return ; } let content; if (cleanRoute === '/departs') { content = navigate(prefix || '/')} navigate={navigate} />; } else if (cleanRoute === '/arrivees') { content = navigate(prefix || '/')} navigate={navigate} />; } else if (cleanRoute === '/select-afficheur') { content = { const params = new URLSearchParams(window.location.search); const gare = params.get('gare') || ''; const mode = params.get('mode') || 'departs'; navigate(`${prefix}/afficheurs/${encodeURIComponent(gare)}?mode=${mode}`); }} navigate={navigate} />; } else if (cleanRoute.startsWith('/afficheurs')) { content = navigate(prefix || '/')} navigate={navigate} />; } else { content = ; } return (
{source === 'supabase' ? ( { e.preventDefault(); navigate('/'); }} style={{ color: '#008b47', fontWeight: 600 }} title="Basculer vers le mode SNCF GTFS" > 🌐 Passer en mode SNCF Live ) : ( )}

{source === 'supabase' ? 'Affichage Ferroviaire — BDD Supabase (/ferrovia)' : 'Affichage Ferroviaire — SNCF GTFS / Temps Réel'}

Route actuelle: {route}
Source: {source === 'supabase' ? 'Supabase Database' : 'SNCF Open Data / GTFS'}
{content}
Contact Mentions Légales
); } export default App;