import React, { useEffect, useState } from 'react'; import { WcsCard, WcsCardBody, WcsButton, WcsBadge } from 'wcs-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 ClassiquesFlashInfo from './pages/afficheurs/classiques/ClassiquesFlashInfo'; import ClassiquesInformations from './pages/afficheurs/classiques/ClassiquesInformations'; 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)); function useSimpleRouter() { function normalizePath(p) { if (!p) return '/'; 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/, '') || '/'); function Home({ navigate, prefix, source }) { const POPULAR_HOME_GARES = [ 'Paris-Gare-de-Lyon', 'Besançon-Viotte', 'Dijon-Ville', 'Lyon-Part-Dieu', 'Marseille-Saint-Charles', 'Lille-Flandres', 'Strasbourg', 'Bordeaux-Saint-Jean' ]; return (
{source === 'supabase' ? "Consultez les afficheurs basés sur les données de votre BDD Supabase." : "Simulateur d'écrans de gare officiels connectés en direct aux flux GTFS & Open Data SNCF."}
Consultez les trains au départ, leurs voies, retards et dessertes complètes.
Suivez en direct les trains attendus en gare, provenances et voies assignées.
Accès direct par gare :