diff --git a/package-lock.json b/package-lock.json index 377c485..cc6dedd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,11 +1,11 @@ { - "name": "afficeheurs-ferrovia.", + "name": "afficheurs-ferrovia", "version": "0.1.0", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "afficeheurs-ferrovia.", + "name": "afficheurs-ferrovia", "version": "0.1.0", "dependencies": { "dependencies": "^0.0.1", diff --git a/package.json b/package.json index 4e1c900..b2d801a 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "web-vitals": "^2.1.4" }, "scripts": { - "start": "PORT=4010 react-scripts start", + "start": "react-scripts start", "build": "react-scripts build", "serve": "serve -s build -l 4010", "start:prod": "serve -s build -l 4010", diff --git a/public/sw.js b/public/sw.js new file mode 100644 index 0000000..847f370 --- /dev/null +++ b/public/sw.js @@ -0,0 +1,52 @@ +const CACHE_NAME = 'ferrovia-pwa-v1'; + +self.addEventListener('install', (event) => { + event.waitUntil( + caches.open(CACHE_NAME).then((cache) => { + return cache.addAll([ + './', + './index.html', + './manifest.json', + './favicon.ico', + './logo192.png', + './logo512.png' + ]); + }) + ); + self.skipWaiting(); +}); + +self.addEventListener('activate', (event) => { + event.waitUntil( + caches.keys().then((cacheNames) => { + return Promise.all( + cacheNames.filter((name) => name !== CACHE_NAME).map((name) => caches.delete(name)) + ); + }) + ); + self.clients.claim(); +}); + +self.addEventListener('fetch', (event) => { + // Ignorer les requêtes non-GET et les requêtes vers d'autres origines ou APIs + if (event.request.method !== 'GET' || !event.request.url.startsWith(self.location.origin)) { + return; + } + + event.respondWith( + caches.match(event.request).then((cachedResponse) => { + if (cachedResponse) { + return cachedResponse; + } + return fetch(event.request).then((networkResponse) => { + return caches.open(CACHE_NAME).then((cache) => { + cache.put(event.request, networkResponse.clone()); + return networkResponse; + }); + }).catch(() => { + // En cas d'échec réseau total, on pourrait retourner un fallback hors-ligne + return caches.match('./index.html'); + }); + }) + ); +}); diff --git a/public/type/data.json b/public/type/data.json index 585eebd..b1bd9de 100644 --- a/public/type/data.json +++ b/public/type/data.json @@ -1,5 +1,5 @@ { - "generatedAt": "2025-10-24T21:56:22.827Z", + "generatedAt": "2026-10-24T21:56:22.827Z", "logos": [ { "file": "logo-aleop.svg", @@ -8,11 +8,12 @@ "name": "Aleop" }, { - "file": "logo-auvergerhonealpes.svg", - "path": "/logo-auvergerhonealpes.svg", + "file": "sncf-voyageurs-logo.png", + "path": "/sncf-voyageurs-logo.png", "slug": "auvergerhonealpes", - "name": "Auvergerhonealpes" + "name": "TER AURA" }, + { "file": "logo-breizhgo.svg", "path": "/logo-breizhgo.svg",, diff --git a/scratch/patch_app.js b/scratch/patch_app.js new file mode 100644 index 0000000..08625a3 --- /dev/null +++ b/scratch/patch_app.js @@ -0,0 +1,204 @@ +const fs = require('fs'); + +const filePath = 'c:\\Users\\mathi\\Documents\\Développement WEB\\ferrovia-infogare\\src\\App.js'; + +let content = fs.readFileSync(filePath, 'utf-8'); + +content = content.replace( + "import React, { useEffect, useState } from 'react';", + "import React, { useEffect, useState } from 'react';\nimport { WcsCard, WcsCardBody, WcsButton, WcsBadge } from 'wcs-react';" +); + +const home_component_old = ` return ( +
+ {/* Carte de bienvenue */} +
+
+
+

🚅 Téléaffichage Ferroviaire SNCF

+

+ {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."} +

+
+ + {source === 'supabase' ? '🗄️ Mode Supabase' : '🌐 Mode SNCF Live'} + +
+ + {/* Cartes principales : Départs / Arrivées */} +
+
{ + try { sessionMemory.set('afficheurMode', 'departs'); } catch (e) {} + navigate(\`\${prefix}/departs\`); + }} + onKeyDown={(e) => { + if (e.key === 'Enter' || e.key === ' ') { + try { sessionMemory.set('afficheurMode', 'departs'); } catch (e) {} + navigate(\`\${prefix}/departs\`); + } + }} + > +
+ 🚆 + Départs +

Prochains Départs

+

+ Consultez les trains au départ, leurs voies, retards et dessertes complètes. +

+
+
+ + Consulter les Départs › + +
+
+ +
{ + try { sessionMemory.set('afficheurMode', 'arrivees'); } catch (e) {} + navigate(\`\${prefix}/arrivees\`); + }} + onKeyDown={(e) => { + if (e.key === 'Enter' || e.key === ' ') { + try { sessionMemory.set('afficheurMode', 'arrivees'); } catch (e) {} + navigate(\`\${prefix}/arrivees\`); + } + }} + > +
+ 🏁 + Arrivées +

Prochaines Arrivées

+

+ Suivez en direct les trains attendus en gare, provenances et voies assignées. +

+
+
+ + Consulter les Arrivées › + +
+
+
+ + {/* Raccourcis rapides vers les gares */} +
+ Accès direct par gare : +
+ {POPULAR_HOME_GARES.map((gName) => ( + + ))} +
+
+ + {/* Présentation des types d'afficheurs */} +
+
+ ✨ Formats disponibles : Afficheurs Fluides & Lumineux (AFL), Téléaffichage historique (Classiques), Écrans Vidéo Voyageurs (EVA) et Écrans par Quai / Voie. +
+
+
+
+ );`; + +const home_component_new = ` return ( +
+ + +
+
+

🚅 Téléaffichage Ferroviaire SNCF

+

+ {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."} +

+
+ + {source === 'supabase' ? '🗄️ Mode Supabase' : '🌐 Mode SNCF Live'} + +
+ +
+ { + try { sessionMemory.set('afficheurMode', 'departs'); } catch (e) {} + navigate(\`\${prefix}/departs\`); + }}> + +
+ 🚆 + Départs +
+

Prochains Départs

+

Consultez les trains au départ, leurs voies, retards et dessertes complètes.

+ Consulter les Départs +
+
+ + { + try { sessionMemory.set('afficheurMode', 'arrivees'); } catch (e) {} + navigate(\`\${prefix}/arrivees\`); + }}> + +
+ 🏁 + Arrivées +
+

Prochaines Arrivées

+

Suivez en direct les trains attendus en gare, provenances et voies assignées.

+ Consulter les Arrivées +
+
+
+ +
+

Accès direct par gare :

+
+ {POPULAR_HOME_GARES.map((gName) => ( + { + try { sessionMemory.set('afficheurMode', 'departs'); } catch (e) {} + navigate(\`\${prefix}/afficheurs/\${encodeURIComponent(gName)}?mode=departs\`); + }} + > + 📍 {gName.replace(/-/g, ' ')} + + ))} +
+
+ +
+
+ ✨ Formats disponibles : Afficheurs Fluides & Lumineux (AFL), Téléaffichage historique (Classiques), Écrans Vidéo Voyageurs (EVA) et Écrans par Quai / Voie. +
+
+
+
+ );`; + +content = content.replace(home_component_old, home_component_new); +fs.writeFileSync(filePath, content, 'utf-8'); +console.log('App.js patched successfully'); diff --git a/scratch/patch_app.py b/scratch/patch_app.py new file mode 100644 index 0000000..dd2284c --- /dev/null +++ b/scratch/patch_app.py @@ -0,0 +1,207 @@ +import os + +file_path = r"c:\Users\mathi\Documents\Développement WEB\ferrovia-infogare\src\App.js" + +with open(file_path, "r", encoding="utf-8") as f: + content = f.read() + +# Make the changes in App.js for the Home component +new_content = content.replace( + "import React, { useEffect, useState } from 'react';", + "import React, { useEffect, useState } from 'react';\nimport { WcsCard, WcsCardBody, WcsButton, WcsBadge } from 'wcs-react';" +) + +home_component_old = """ return ( +
+ {/* Carte de bienvenue */} +
+
+
+

🚅 Téléaffichage Ferroviaire SNCF

+

+ {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."} +

+
+ + {source === 'supabase' ? '🗄️ Mode Supabase' : '🌐 Mode SNCF Live'} + +
+ + {/* Cartes principales : Départs / Arrivées */} +
+
{ + try { sessionMemory.set('afficheurMode', 'departs'); } catch (e) {} + navigate(`${prefix}/departs`); + }} + onKeyDown={(e) => { + if (e.key === 'Enter' || e.key === ' ') { + try { sessionMemory.set('afficheurMode', 'departs'); } catch (e) {} + navigate(`${prefix}/departs`); + } + }} + > +
+ 🚆 + Départs +

Prochains Départs

+

+ Consultez les trains au départ, leurs voies, retards et dessertes complètes. +

+
+
+ + Consulter les Départs › + +
+
+ +
{ + try { sessionMemory.set('afficheurMode', 'arrivees'); } catch (e) {} + navigate(`${prefix}/arrivees`); + }} + onKeyDown={(e) => { + if (e.key === 'Enter' || e.key === ' ') { + try { sessionMemory.set('afficheurMode', 'arrivees'); } catch (e) {} + navigate(`${prefix}/arrivees`); + } + }} + > +
+ 🏁 + Arrivées +

Prochaines Arrivées

+

+ Suivez en direct les trains attendus en gare, provenances et voies assignées. +

+
+
+ + Consulter les Arrivées › + +
+
+
+ + {/* Raccourcis rapides vers les gares */} +
+ Accès direct par gare : +
+ {POPULAR_HOME_GARES.map((gName) => ( + + ))} +
+
+ + {/* Présentation des types d'afficheurs */} +
+
+ ✨ Formats disponibles : Afficheurs Fluides & Lumineux (AFL), Téléaffichage historique (Classiques), Écrans Vidéo Voyageurs (EVA) et Écrans par Quai / Voie. +
+
+
+
+ );""" + +home_component_new = """ return ( +
+ + +
+
+

🚅 Téléaffichage Ferroviaire SNCF

+

+ {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."} +

+
+ + {source === 'supabase' ? '🗄️ Mode Supabase' : '🌐 Mode SNCF Live'} + +
+ +
+ { + try { sessionMemory.set('afficheurMode', 'departs'); } catch (e) {} + navigate(`${prefix}/departs`); + }}> + +
+ 🚆 + Départs +
+

Prochains Départs

+

Consultez les trains au départ, leurs voies, retards et dessertes complètes.

+ Consulter les Départs +
+
+ + { + try { sessionMemory.set('afficheurMode', 'arrivees'); } catch (e) {} + navigate(`${prefix}/arrivees`); + }}> + +
+ 🏁 + Arrivées +
+

Prochaines Arrivées

+

Suivez en direct les trains attendus en gare, provenances et voies assignées.

+ Consulter les Arrivées +
+
+
+ +
+

Accès direct par gare :

+
+ {POPULAR_HOME_GARES.map((gName) => ( + { + try { sessionMemory.set('afficheurMode', 'departs'); } catch (e) {} + navigate(`${prefix}/afficheurs/${encodeURIComponent(gName)}?mode=departs`); + }} + > + 📍 {gName.replace(/-/g, ' ')} + + ))} +
+
+ +
+
+ ✨ Formats disponibles : Afficheurs Fluides & Lumineux (AFL), Téléaffichage historique (Classiques), Écrans Vidéo Voyageurs (EVA) et Écrans par Quai / Voie. +
+
+
+
+ );""" + +new_content = new_content.replace(home_component_old, home_component_new) + +with open(file_path, "w", encoding="utf-8") as f: + f.write(new_content) diff --git a/src/App.js b/src/App.js index f99cf66..d6009fc 100644 --- a/src/App.js +++ b/src/App.js @@ -1,4 +1,5 @@ import React, { useEffect, useState } from 'react'; +import { WcsCard, WcsCardBody, WcsButton, WcsBadge } from 'wcs-react'; import './App.css'; import { applyPolyfills, defineCustomElements } from 'wcs-core/loader'; @@ -24,11 +25,9 @@ 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(); @@ -74,7 +73,6 @@ function App() { const prefix = source === 'supabase' ? '/ferrovia' : ''; const cleanRoute = (route.replace(/^\/ferrovia/, '') || '/'); - // Composant Home moderne & responsive pour Mobile, Tablette et Desktop function Home({ navigate, prefix, source }) { const POPULAR_HOME_GARES = [ 'Paris-Gare-de-Lyon', @@ -88,118 +86,85 @@ function App() { ]; return ( -
- {/* Carte de bienvenue */} -
-
-
-

🚅 Téléaffichage Ferroviaire SNCF

-

- {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."} -

+
+ + +
+
+

🚅 Téléaffichage Ferroviaire SNCF

+

+ {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."} +

+
+ + {source === 'supabase' ? '🗄️ Mode Supabase' : '🌐 Mode SNCF Live'} +
- - {source === 'supabase' ? '🗄️ Mode Supabase' : '🌐 Mode SNCF Live'} - -
- {/* Cartes principales : Départs / Arrivées */} -
-
{ - try { sessionMemory.set('afficheurMode', 'departs'); } catch (e) {} - navigate(`${prefix}/departs`); - }} - onKeyDown={(e) => { - if (e.key === 'Enter' || e.key === ' ') { +
+ { try { sessionMemory.set('afficheurMode', 'departs'); } catch (e) {} navigate(`${prefix}/departs`); - } - }} - > -
- 🚆 - Départs -

Prochains Départs

-

- Consultez les trains au départ, leurs voies, retards et dessertes complètes. -

-
-
- - Consulter les Départs › - -
-
+ }}> + +
+ 🚆 + Départs +
+

Prochains Départs

+

Consultez les trains au départ, leurs voies, retards et dessertes complètes.

+ Consulter les Départs +
+ -
{ - try { sessionMemory.set('afficheurMode', 'arrivees'); } catch (e) {} - navigate(`${prefix}/arrivees`); - }} - onKeyDown={(e) => { - if (e.key === 'Enter' || e.key === ' ') { + { try { sessionMemory.set('afficheurMode', 'arrivees'); } catch (e) {} navigate(`${prefix}/arrivees`); - } - }} - > -
- 🏁 - Arrivées -

Prochaines Arrivées

-

- Suivez en direct les trains attendus en gare, provenances et voies assignées. -

-
-
- - Consulter les Arrivées › - + }}> + +
+ 🏁 + Arrivées +
+

Prochaines Arrivées

+

Suivez en direct les trains attendus en gare, provenances et voies assignées.

+ Consulter les Arrivées +
+ +
+ +
+

Accès direct par gare :

+
+ {POPULAR_HOME_GARES.map((gName) => ( + { + try { sessionMemory.set('afficheurMode', 'departs'); } catch (e) {} + navigate(`${prefix}/afficheurs/${encodeURIComponent(gName)}?mode=departs`); + }} + > + 📍 {gName.replace(/-/g, ' ')} + + ))}
-
- {/* Raccourcis rapides vers les gares */} -
- Accès direct par gare : -
- {POPULAR_HOME_GARES.map((gName) => ( - - ))} -
-
- - {/* Présentation des types d'afficheurs */} -
-
+
+
✨ Formats disponibles : Afficheurs Fluides & Lumineux (AFL), Téléaffichage historique (Classiques), Écrans Vidéo Voyageurs (EVA) et Écrans par Quai / Voie.
-
-
+ +
); } - // Routes pour afficheurs : supporte le mode racine ET le mode /ferrovia if ( cleanRoute.startsWith('/afficheurs/classiques/flash-info') || cleanRoute.startsWith('/afficheurs/classiques/flash-circulation') || diff --git a/src/components/AfficheurViewportWrapper.js b/src/components/AfficheurViewportWrapper.js index eb89e66..87ef58e 100644 --- a/src/components/AfficheurViewportWrapper.js +++ b/src/components/AfficheurViewportWrapper.js @@ -1,23 +1,24 @@ -import React, { useState, useEffect } from 'react'; +import React, { useState, useEffect, useRef } from 'react'; import './AfficheurViewportWrapper.css'; +import { createPortal } from 'react-dom'; -/** - * AfficheurViewportWrapper - * Assure un affichage 16:9 strict (1920x1080) sur tous les appareils - * (Mobile portrait, Mobile paysage, Tablettes, Ordinateurs, TV). - * Ajoute automatiquement des bordures noires (letterboxing / pillarboxing) - * pour conserver fidèlement les proportions du design original sans distorsion. - */ export default function AfficheurViewportWrapper({ children }) { const [scale, setScale] = useState(1); + const [pipWindow, setPipWindow] = useState(null); + const containerRef = useRef(null); + const [isPipSupported, setIsPipSupported] = useState(false); + const [autoPipTriggered, setAutoPipTriggered] = useState(false); + + const isMobile = typeof window !== 'undefined' && (window.innerWidth <= 768 || /Mobi|Android/i.test(navigator.userAgent)); useEffect(() => { + if ('documentPictureInPicture' in window) { + setIsPipSupported(true); + } + const calculateScale = () => { - // Dimensions de la fenêtre d'affichage (support viewport iOS / Android safe area) const w = window.innerWidth || (document.documentElement && document.documentElement.clientWidth) || 1920; const h = window.innerHeight || (document.documentElement && document.documentElement.clientHeight) || 1080; - - // Échelle basée sur la résolution standard 1920x1080 (16:9) const scaleX = w / 1920; const scaleY = h / 1080; const s = Math.min(scaleX, scaleY); @@ -27,7 +28,6 @@ export default function AfficheurViewportWrapper({ children }) { calculateScale(); window.addEventListener('resize', calculateScale); window.addEventListener('orientationchange', calculateScale); - if (window.visualViewport) { window.visualViewport.addEventListener('resize', calculateScale); } @@ -41,16 +41,136 @@ export default function AfficheurViewportWrapper({ children }) { }; }, []); + const togglePiP = async () => { + if (pipWindow) { + pipWindow.close(); + return; + } + + if ('documentPictureInPicture' in window) { + try { + const pipW = isMobile ? window.innerWidth * 0.8 : 1920 / 3; + const pipH = isMobile ? (window.innerWidth * 0.8) * (1080 / 1920) : 1080 / 3; + + const pip = await window.documentPictureInPicture.requestWindow({ + width: Math.max(pipW, 300), + height: Math.max(pipH, 170), + }); + + [...document.styleSheets].forEach((styleSheet) => { + try { + const cssRules = [...styleSheet.cssRules].map(rule => rule.cssText).join(''); + const style = document.createElement('style'); + style.textContent = cssRules; + pip.document.head.appendChild(style); + } catch(e) { + const link = document.createElement('link'); + link.rel = 'stylesheet'; + link.type = styleSheet.type; + link.media = styleSheet.media; + link.href = styleSheet.href; + pip.document.head.appendChild(link); + } + }); + + pip.document.body.classList.add('pip-mode'); + pip.document.body.style.margin = '0'; + pip.document.body.style.padding = '0'; + pip.document.body.style.overflow = 'hidden'; + pip.document.body.style.width = '100vw'; + pip.document.body.style.height = '100vh'; + pip.document.body.style.backgroundColor = '#000'; + pip.document.body.style.display = 'flex'; + pip.document.body.style.justifyContent = 'center'; + pip.document.body.style.alignItems = 'center'; + + const updatePipScale = () => { + const w = pip.innerWidth; + const h = pip.innerHeight; + const pipScale = Math.min(w / 1920, h / 1080); + pip.document.body.style.setProperty('--pip-scale', pipScale); + }; + updatePipScale(); + pip.addEventListener('resize', updatePipScale); + + pip.addEventListener("pagehide", () => { + setPipWindow(null); + }); + + setPipWindow(pip); + setAutoPipTriggered(true); + } catch (err) { + console.error('Failed to enter PiP mode', err); + } + } + }; + + const content = ( +
+ {children} +
+ ); + return ( -
-
- {children} -
+
+ {!pipWindow && content} + + {isMobile && isPipSupported && !pipWindow && !autoPipTriggered && ( +
+ 📱 +

Appuyez pour lancer l'afficheur

+

Le mode Picture-in-Picture s'activera pour une meilleure expérience sur mobile.

+
+ )} + + {pipWindow && ( +
+

L'afficheur est en cours de lecture dans le lecteur réduit (PiP)

+

Vous pouvez naviguer sur votre téléphone, l'afficheur restera au premier plan.

+ +
+ )} + + {pipWindow && createPortal( +
+ {content} +
, + pipWindow.document.body + )} +
); } diff --git a/src/index.js b/src/index.js index d563c0f..c60d81b 100644 --- a/src/index.js +++ b/src/index.js @@ -15,3 +15,14 @@ root.render( // to log results (for example: reportWebVitals(console.log)) // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals reportWebVitals(); + +// Register PWA Service Worker +if ('serviceWorker' in navigator) { + window.addEventListener('load', () => { + navigator.serviceWorker.register('/sw.js').then(registration => { + console.log('SW registered: ', registration); + }).catch(registrationError => { + console.log('SW registration failed: ', registrationError); + }); + }); +} diff --git a/src/pages/Arrivees.js b/src/pages/Arrivees.js index 634a2e6..f8c131d 100644 --- a/src/pages/Arrivees.js +++ b/src/pages/Arrivees.js @@ -1,5 +1,5 @@ import React, { useEffect, useState, useMemo } from 'react'; -import WcsButton from '../components/WcsButton'; +import { WcsCard, WcsCardBody, WcsButton, WcsInput, WcsBadge, WcsHorizontalStepper } from 'wcs-react'; import sessionMemory from '../lib/sessionMemory'; import { getSourceFromPath, searchGares } from '../services/railwayService'; @@ -90,139 +90,112 @@ export default function Arrivees({ onBack, navigate }) { } }; + const steps = [ + { text: 'Choix de la gare', button: { kind: 'Text', text: '1' }, complete: false }, + { text: "Type d'afficheur", button: { kind: 'Text', text: '2' }, disable: true }, + { text: 'Options & Affichage', button: { kind: 'Text', text: '3' }, disable: true } + ]; + return ( -
- {/* Stepper */} -
-
- 1 - Choix de la gare -
- › -
- 2 - Type d'afficheur -
- › -
- 3 - Options & Affichage -
-
+
+ -
- {/* Header */} -
-
-

🏁 Prochaines Arrivées

-

Recherchez une gare pour afficher le tableau des arrivées en temps réel.

+ + +
+
+

🏁 Prochaines Arrivées

+

Recherchez une gare pour afficher le tableau des arrivées en temps réel.

+
+ + {source === 'supabase' ? '🗄️ BDD Ferrovia' : '🌐 SNCF GTFS Live'} +
- - {source === 'supabase' ? '🗄️ BDD Ferrovia' : '🌐 SNCF GTFS Live'} - -
- {/* Barre de recherche */} -
- setSearch(e.target.value)} - className="launcher-search-input" - aria-label="Rechercher une gare" - autoFocus - /> - {search && ( - - )} -
- - {/* Suggestions rapides / Gares populaires */} -
- Gares fréquentes : -
- {POPULAR_GARES.map((gName) => ( - - ))} +
+ setSearch(e.target.value)} + style={{ width: '100%' }} + clearable={true} + />
-
- {loading &&

⏳ Chargement des gares...

} - {error &&

⚠️ Erreur : {error}

} - - {/* Invitation à la recherche en mode SNCF */} - {source === 'sncf' && search.trim().length < 2 && ( -
-

- 💡 Saisissez au moins 2 lettres pour chercher parmi plus de 3 500 gares du réseau français. -

-
- )} - - {/* Aucun résultat */} - {source === 'sncf' && search.trim().length >= 2 && displayedGares.length === 0 && ( -
- Aucune gare trouvée pour « {search} ». -
- )} - - {/* Liste des résultats */} - {displayedGares.length > 0 && ( -
- {displayedGares.map((g) => { - const nom = g.nom; - return ( -
handleSelectGare(nom)} - onKeyDown={(e) => (e.key === 'Enter' ? handleSelectGare(nom) : null)} - tabIndex={0} - role="listitem" +
+

Gares fréquentes :

+
+ {POPULAR_GARES.map((gName) => ( + handleSelectGare(gName)} > -
-
{nom}
- {g.commune && ( -
- {g.commune} {g.departement ? `(${g.departement})` : ''} -
- )} -
-
- {g.uic && UIC {g.uic}} - › -
-
- ); - })} + {gName.replace(/-/g, ' ')} + + ))} +
- )} - {/* Navigation retour */} -
- -
-
+ {loading &&

⏳ Chargement des gares...

} + {error &&

⚠️ Erreur : {error}

} + + {source === 'sncf' && search.trim().length < 2 && ( +
+

+ 💡 Saisissez au moins 2 lettres pour chercher parmi plus de 3 500 gares du réseau français. +

+
+ )} + + {source === 'sncf' && search.trim().length >= 2 && displayedGares.length === 0 && ( +
+ Aucune gare trouvée pour « {search} ». +
+ )} + + {displayedGares.length > 0 && ( +
+ {displayedGares.map((g) => { + const nom = g.nom; + return ( + handleSelectGare(nom)} + > + +
+
{nom}
+ {g.commune && ( +
+ {g.commune} {g.departement ? `(${g.departement})` : ''} +
+ )} +
+
+ {g.uic && {g.uic}} + › +
+
+
+ ); + })} +
+ )} + +
+ + ← Retour à l'accueil + +
+ +
); } - diff --git a/src/pages/Departs.js b/src/pages/Departs.js index 880e1b7..00b4b25 100644 --- a/src/pages/Departs.js +++ b/src/pages/Departs.js @@ -1,5 +1,5 @@ import React, { useEffect, useState, useMemo } from 'react'; -import WcsButton from '../components/WcsButton'; +import { WcsCard, WcsCardBody, WcsButton, WcsInput, WcsBadge, WcsHorizontalStepper } from 'wcs-react'; import sessionMemory from '../lib/sessionMemory'; import { getSourceFromPath, searchGares } from '../services/railwayService'; @@ -90,139 +90,112 @@ export default function Departs({ onBack, navigate }) { } }; + const steps = [ + { text: 'Choix de la gare', button: { kind: 'Text', text: '1' }, complete: false }, + { text: "Type d'afficheur", button: { kind: 'Text', text: '2' }, disable: true }, + { text: 'Options & Affichage', button: { kind: 'Text', text: '3' }, disable: true } + ]; + return ( -
- {/* Stepper */} -
-
- 1 - Choix de la gare -
- › -
- 2 - Type d'afficheur -
- › -
- 3 - Options & Affichage -
-
+
+ -
- {/* Header */} -
-
-

🚆 Prochains Départs

-

Recherchez une gare pour afficher le tableau des départs en temps réel.

+ + +
+
+

🚆 Prochains Départs

+

Recherchez une gare pour afficher le tableau des départs en temps réel.

+
+ + {source === 'supabase' ? '🗄️ BDD Ferrovia' : '🌐 SNCF GTFS Live'} +
- - {source === 'supabase' ? '🗄️ BDD Ferrovia' : '🌐 SNCF GTFS Live'} - -
- {/* Barre de recherche */} -
- setSearch(e.target.value)} - className="launcher-search-input" - aria-label="Rechercher une gare" - autoFocus - /> - {search && ( - - )} -
- - {/* Suggestions rapides / Gares populaires */} -
- Gares fréquentes : -
- {POPULAR_GARES.map((gName) => ( - - ))} +
+ setSearch(e.target.value)} + style={{ width: '100%' }} + clearable={true} + />
-
- {loading &&

⏳ Chargement des gares...

} - {error &&

⚠️ Erreur : {error}

} - - {/* Invitation à la recherche en mode SNCF */} - {source === 'sncf' && search.trim().length < 2 && ( -
-

- 💡 Saisissez au moins 2 lettres pour chercher parmi plus de 3 500 gares du réseau français. -

-
- )} - - {/* Aucun résultat */} - {source === 'sncf' && search.trim().length >= 2 && displayedGares.length === 0 && ( -
- Aucune gare trouvée pour « {search} ». -
- )} - - {/* Liste des résultats */} - {displayedGares.length > 0 && ( -
- {displayedGares.map((g) => { - const nom = g.nom; - return ( -
handleSelectGare(nom)} - onKeyDown={(e) => (e.key === 'Enter' ? handleSelectGare(nom) : null)} - tabIndex={0} - role="listitem" +
+

Gares fréquentes :

+
+ {POPULAR_GARES.map((gName) => ( + handleSelectGare(gName)} > -
-
{nom}
- {g.commune && ( -
- {g.commune} {g.departement ? `(${g.departement})` : ''} -
- )} -
-
- {g.uic && UIC {g.uic}} - › -
-
- ); - })} + {gName.replace(/-/g, ' ')} + + ))} +
- )} - {/* Navigation retour */} -
- -
-
+ {loading &&

⏳ Chargement des gares...

} + {error &&

⚠️ Erreur : {error}

} + + {source === 'sncf' && search.trim().length < 2 && ( +
+

+ 💡 Saisissez au moins 2 lettres pour chercher parmi plus de 3 500 gares du réseau français. +

+
+ )} + + {source === 'sncf' && search.trim().length >= 2 && displayedGares.length === 0 && ( +
+ Aucune gare trouvée pour « {search} ». +
+ )} + + {displayedGares.length > 0 && ( +
+ {displayedGares.map((g) => { + const nom = g.nom; + return ( + handleSelectGare(nom)} + > + +
+
{nom}
+ {g.commune && ( +
+ {g.commune} {g.departement ? `(${g.departement})` : ''} +
+ )} +
+
+ {g.uic && {g.uic}} + › +
+
+
+ ); + })} +
+ )} + +
+ + ← Retour à l'accueil + +
+ +
); } - diff --git a/src/pages/Displays.js b/src/pages/Displays.js index 5833e95..1a17e5b 100644 --- a/src/pages/Displays.js +++ b/src/pages/Displays.js @@ -1,5 +1,5 @@ import React from 'react'; -import WcsButton from '../components/WcsButton'; +import { WcsCard, WcsCardBody, WcsButton, WcsBadge, WcsHorizontalStepper } from 'wcs-react'; import sessionMemory from '../lib/sessionMemory'; import { getSourceFromPath } from '../services/railwayService'; @@ -21,6 +21,7 @@ export default function Displays({ onBack, navigate }) { id: 'classiques', label: 'Classiques', sublabel: 'Téléaffichage Historique', + sublabel: 'Téléaffichage Historique', tag: 'Rétro / Vintage', tagType: 'retro', icon: '📺', @@ -33,7 +34,7 @@ export default function Displays({ onBack, navigate }) { tag: 'Gares Connectées', tagType: 'modern', icon: '📱', - desc: 'Écrans d\'information enrichis avec multimédia, infogare et dessertes complètes.' + desc: "Écrans d'information enrichis avec multimédia, infogare et dessertes complètes." }, { id: 'transilien', @@ -46,8 +47,7 @@ export default function Displays({ onBack, navigate }) { } ]; - // Nettoyage du chemin pour extraire la gare même avec /ferrovia - const cleanPath = (typeof window !== 'undefined' ? window.location.pathname : '').replace(/^\/ferrovia/, ''); + const cleanPath = (typeof window !== 'undefined' ? window.location.pathname : '').replace(/ferrovia/, ''); const parts = cleanPath.split('/').filter(Boolean); const typeIds = types.map(t => t.id); let gare = null; @@ -63,14 +63,13 @@ export default function Displays({ onBack, navigate }) { const g = paramsForGare.get('gare'); if (g) { try { - gare = decodeURIComponent(String(g).replace(/\+/g, ' ')).replace(/-/g, ' '); + gare = decodeURIComponent(String(g).replace(/\\+/g, ' ')).replace(/-/g, ' '); } catch (e) { gare = String(g).replace(/-/g, ' '); } } } - // Déterminer le mode (departs/arrivees) const params = new URLSearchParams(window.location.search || ''); let mode = params.get('mode'); if (!mode) { @@ -83,96 +82,73 @@ export default function Displays({ onBack, navigate }) { const formattedGareName = gare ? gare.replace(/-/g, ' ') : 'Non sélectionnée'; + const steps = [ + { text: formattedGareName, button: { kind: 'Icon', iconName: 'check' }, complete: true }, + { text: "Type d'afficheur", button: { kind: 'Text', text: '2' }, complete: false }, + { text: 'Options & Affichage', button: { kind: 'Text', text: '3' }, disable: true } + ]; + return ( -
- {/* Stepper */} -
-
- ✓ - {formattedGareName} -
- › -
- 2 - Type d'afficheur -
- › -
- 3 - Options & Affichage -
-
+
+ -
- {/* Header */} -
-
-

Sélectionnez le style d'afficheur

-

- Gare : {formattedGareName} • Mode : {mode === 'arrivees' ? '🏁 Arrivées' : '🚆 Départs'} -

-
- - {source === 'supabase' ? '🗄️ BDD Ferrovia' : '🌐 SNCF GTFS'} - -
- - {/* Grille de sélection tactile des styles d'afficheurs */} -
- {types.map((t) => ( -
{ - if (typeof navigate === 'function') { - const kebab = gare ? String(gare).trim().replace(/\s+/g, '-').replace(/\//g, '/') : ''; - navigate(`${prefix}/select-afficheur?gare=${encodeURIComponent(kebab)}&mode=${mode}&type=${t.id}`); - } - }} - onKeyDown={(e) => { - if (e.key === 'Enter' || e.key === ' ') { - const kebab = gare ? String(gare).trim().replace(/\s+/g, '-').replace(/\//g, '/') : ''; - navigate(`${prefix}/select-afficheur?gare=${encodeURIComponent(kebab)}&mode=${mode}&type=${t.id}`); - } - }} - > -
- {t.icon} - - {t.tag} - -

{t.label}

-
{t.sublabel}
-

{t.desc}

-
- -
- - Choisir ce style › - -
+ + +
+
+

Sélectionnez le style d'afficheur

+

+ Gare : {formattedGareName} • Mode : {mode === 'arrivees' ? '🏁 Arrivées' : '🚆 Départs'} +

- ))} -
+ + {source === 'supabase' ? '🗄️ BDD Ferrovia' : '🌐 SNCF GTFS'} + +
- {/* Navigation retour */} -
- { +
+ {types.map((t) => ( + { + if (typeof navigate === 'function') { + const kebab = gare ? String(gare).trim().replace(/\\s+/g, '-').replace(/\\/g, '/') : ''; + navigate(`${prefix}/select-afficheur?gare=${encodeURIComponent(kebab)}&mode=${mode}&type=${t.id}`); + } + }} + > + +
+ {t.icon} + {t.tag} +
+

{t.label}

+
{t.sublabel}
+

{t.desc}

+ + + Choisir ce style + +
+
+ ))} +
+ +
+ { if (typeof onBack === 'function') { onBack(); } else if (navigate) { navigate(`${prefix}/${mode}`); } - }} - label="← Changer de gare" - /> -
-
+ }}> + ← Changer de gare + +
+ +
); } - diff --git a/src/pages/SelectAfficheur.js b/src/pages/SelectAfficheur.js index 3f9237b..b0c0651 100644 --- a/src/pages/SelectAfficheur.js +++ b/src/pages/SelectAfficheur.js @@ -1,5 +1,5 @@ import React, { useEffect, useState } from 'react'; -import WcsButton from '../components/WcsButton'; +import { WcsCard, WcsCardBody, WcsButton, WcsBadge, WcsCheckbox, WcsSelect, WcsSelectOption, WcsInput, WcsHorizontalStepper } from 'wcs-react'; import { getSourceFromPath, getPlatformsForStation } from '../services/railwayService'; export default function SelectAfficheur({ onBack, navigate }) { @@ -16,7 +16,6 @@ export default function SelectAfficheur({ onBack, navigate }) { const [manualPlatform, setManualPlatform] = useState(''); const [loading, setLoading] = useState(true); - // État des pages sélectionnées pour les afficheurs AFL const [aflPages, setAflPages] = useState({ horaires: true, infos: false, @@ -25,8 +24,7 @@ export default function SelectAfficheur({ onBack, navigate }) { corresp: false }); - // Options spécifiques pour les afficheurs Classiques - const [extendedLines, setExtendedLines] = useState(0); // 0, 1, 2, 3 + const [extendedLines, setExtendedLines] = useState(0); const [showTime, setShowTime] = useState(false); const toggleAflPage = (key) => { @@ -43,9 +41,8 @@ export default function SelectAfficheur({ onBack, navigate }) { }); }; - // Decode and format station name for display const decodedGare = gareParam - ? decodeURIComponent(String(gareParam).replace(/\+/g, ' ')).replace(/-/g, ' ') + ? decodeURIComponent(String(gareParam).replace(/\\+/g, ' ')).replace(/-/g, ' ') : ''; useEffect(() => { @@ -129,398 +126,212 @@ export default function SelectAfficheur({ onBack, navigate }) { } }; + const steps = [ + { text: decodedGare || 'Gare', button: { kind: 'Icon', iconName: 'check' }, complete: true }, + { text: typeParam.toUpperCase(), button: { kind: 'Icon', iconName: 'check' }, complete: true }, + { text: 'Options & Affichage', button: { kind: 'Text', text: '3' }, complete: false } + ]; + return ( -
- {/* Stepper */} -
-
- ✓ - {decodedGare || 'Gare'} -
- › -
- ✓ - {typeParam.toUpperCase()} -
- › -
- 3 - Options & Affichage -
-
+
+ -
- {/* Header */} -
-
-

Configuration de l'afficheur

-

- Gare : {decodedGare} • Mode : {modeParam === 'arrivees' ? '🏁 Arrivées' : '🚆 Départs'} • Style : {typeParam.toUpperCase()} -

-
- - {source === 'supabase' ? '🗄️ BDD Ferrovia' : '🌐 SNCF GTFS'} - -
- - {/* Grille responsive 2 colonnes (1 col sur mobile) */} -
- {/* Option 1 : Afficheur Général */} -
+ + +
- 🖥️ - Écran Général -

Afficheur Général (Hall)

-

- Affiche la liste complète des circulations avec basculement automatique des pages. +

Configuration de l'afficheur

+

+ Gare : {decodedGare} • Mode : {modeParam === 'arrivees' ? '🏁 Arrivées' : '🚆 Départs'} • Style : {typeParam.toUpperCase()}

- - {typeParam === 'afl' && ( -
-
- - Pages incluses dans la boucle : - -
- - | - -
-
- -
- - - - - - - - - -
-
- )} - - {typeParam === 'classiques' && ( -
-
- - Options d'affichage Classiques : - -
- - {/* Choix du nombre de lignes étendues */} -
- -
- {[0, 1, 2, 3].map((num) => ( - - ))} -
-
- {extendedLines > 0 - ? `Les ${extendedLines} premier${extendedLines > 1 ? 's' : ''} train${extendedLines > 1 ? 's' : ''} s'afficheront sur 2 lignes réduites avec le défilement de toutes les gares.` - : 'Affichage classique compact sans défilement de gares.'} -
-
- - {/* Option Afficher l'heure */} -
- -
- Réserve la 10e ligne pour l'horloge numérique [ HH MM SS ] et un bandeau d'information défilant (horaires sur 9 lignes max). -
-
-
- )}
- - + + {source === 'supabase' ? '🗄️ BDD Ferrovia' : '🌐 SNCF GTFS'} +
- {/* Option 2 : Afficheur par Quai */} -
-
- 🚉 - Écran de Voie -

Afficheur par Quai

-

- Affiche le prochain train au départ/arrivée avec la liste déroulante des gares desservies sur la voie. -

+
+ + + +
+ 🖥️ + Écran Général +
+

Afficheur Général (Hall)

+

+ Affiche la liste complète des circulations avec basculement automatique des pages. +

-
- {loading ? ( -
⏳ Détection des voies réelles...
- ) : ( -
- {platforms.length > 0 ? ( -
- - + {typeParam === 'afl' && ( +
+
+ Pages incluses dans la boucle : +
+ selectAllAflPages(true)}>Tout cocher + selectAllAflPages(false)}>Horaires seuls
- ) : ( -
- ℹ️ Saisie manuelle de la voie ci-dessous. -
- )} - -
- - setManualPlatform(e.target.value)} - style={{ - width: '100%', - padding: '12px', - borderRadius: '8px', - border: '2px solid #e2ebf6', - fontSize: '15px', - boxSizing: 'border-box', - background: '#ffffff' - }} - /> +
+
+ toggleAflPage('horaires')}>Page 1 & 2 (Horaires) + toggleAflPage('infos')}>Informations (Trafic) + toggleAflPage('securite1')}>Sécurité 1 (Bagages) + toggleAflPage('securite2')}>Sécurité 2 (Vigipirate) + toggleAflPage('corresp')}>Correspondances
)} -
-
- + {typeParam === 'classiques' && ( +
+

Options d'affichage :

+
+ +
+ {[0, 1, 2, 3].map(num => ( + setExtendedLines(num)} + > + {num === 0 ? '0' : num} + + ))} +
+
+ setShowTime(e.detail.checked)}>Afficher l'heure & infos +
+ )} + + + Lancer l'Afficheur Général + + + + + + +
+ 🚉 + Écran de Voie +
+

Afficheur par Quai

+

+ Affiche le prochain train au départ/arrivée avec la liste déroulante des gares desservies sur la voie. +

+ +
+ {loading ? ( +

⏳ Détection des voies...

+ ) : ( + <> + {platforms.length > 0 && ( +
+ + { + setSelectedPlatform(e.detail.value); + setManualPlatform(''); + }} + > + {platforms.map(p => ( + Voie {p} + ))} + +
+ )} + +
+ + setManualPlatform(e.target.value)} + /> +
+ + )} +
+ + + Lancer l'Afficheur de Quai + +
+
+ + {typeParam === 'classiques' && ( + <> + + +
+ ⚡ + Flash Info Trafic +
+

Flash Information

+

+ Écran dédié aux perturbations de circulation en temps réel et travaux de maintenance sur le réseau. +

+ { + const kebab = gareParam ? String(gareParam).trim() : ''; + navigate(`${prefix}/afficheurs/classiques/flash-info?gare=${encodeURIComponent(kebab)}`); + }}> + Lancer le Flash Information + +
+
+ + + +
+ ℹ️ + Messages Gare +
+

Informations Voyageurs

+

+ Écran d'annonces et consignes dynamiques de la gare (Vigipirate, étiquetage des bagages, sécurité). +

+ { + const kebab = gareParam ? String(gareParam).trim() : ''; + navigate(`${prefix}/afficheurs/classiques/informations?gare=${encodeURIComponent(kebab)}`); + }}> + Lancer l'Afficheur Informations + +
+
+ + )} +
- {/* Options 3 & 4 pour le mode Classiques : Flash Info & Informations */} - {typeParam === 'classiques' && ( - <> - {/* Option 3 : Flash Information */} -
-
- ⚡ - - Flash Info Trafic - -

Flash Information

-

- Écran dédié aux perturbations de circulation en temps réel et travaux de maintenance sur le réseau. -

-
-
- ⚡ Conforme au design historique Flash Circulation avec fond ambre et bandeau bleu nuit. -
-
-
- - + {typeParam === 'afl' && ( +
+

Accès direct à une page fixe AFL :

+
+ handleSinglePage('1')}>Page 1 + handleSinglePage('2')}>Page 2 + handleSinglePage('infos')}>Informations + handleSinglePage('securite1')}>Sécurité (Bagages) + handleSinglePage('securite2')}>Sécurité (Vigipirate) + handleSinglePage('corresp')}>Correspondances
- - {/* Option 4 : Informations (Messages Dynamiques) */} -
-
- ℹ️ - - Messages Gare - -

Informations Voyageurs

-

- Écran d'annonces et consignes dynamiques de la gare (Vigipirate, étiquetage des bagages, sécurité en gare). -

-
-
- ℹ️ Conforme au design historique Information avec messages voyageurs de la gare de {decodedGare}. -
-
-
- - -
- +
)} -
- {/* Accès direct aux pages fixes AFL */} - {typeParam === 'afl' && ( -
- Accès direct à une page fixe AFL : -
- - - - - - -
-
- )} - - {/* Navigation retour */} -
- { +
+ { if (typeof onBack === 'function') { onBack(); } else if (typeof navigate === 'function') { navigate(`${prefix}/afficheurs?gare=${encodeURIComponent(gareParam)}&mode=${modeParam}`); } - }} - label="← Retour au choix du style" - /> -
-
+ }}> + ← Retour au choix du style + +
+
+
); } - - diff --git a/src/utils/trainLogoHelper.js b/src/utils/trainLogoHelper.js index d500652..3f2495f 100644 --- a/src/utils/trainLogoHelper.js +++ b/src/utils/trainLogoHelper.js @@ -11,14 +11,14 @@ const normalizeStr = (s) => { // Table des logos issue de public/type/data.json const LOGOS_DATA = [ { file: "logo-aleop.svg", slug: "aleop", name: "Aleop" }, - { file: "logo-auvergerhonealpes.svg", slug: "auvergerhonealpes", name: "Auvergerhonealpes" }, + { file: "sncf-voyageurs-logo.png", slug: "auvergerhonealpes", name: "TER AURA" }, { file: "logo-breizhgo.svg", slug: "breizhgo", name: "Breizhgo" }, { file: "logo-cfl.svg", slug: "cfl", name: "CFL" }, { file: "logo-db.svg", slug: "db", name: "DB" }, { file: "logo-eurostar.svg", slug: "eurostar", name: "Eurostar" }, { file: "logo-fluo.svg", slug: "fluo", name: "Fluo" }, { file: "logo-frecciarossa.svg", slug: "frecciarossa", name: "Frecciarossa" }, - { file: "logo-hautsdefrance.svg", slug: "hautsdefrance", name: "Hautsdefrance" }, + { file: "logo-hautsdefrance.svg", slug: "hautsdefrance", name: "TER HDF" }, { file: "logo-ice.svg", slug: "ice", name: "ICE" }, { file: "logo-intercites.svg", slug: "intercites", name: "Intercités" }, { file: "logo-ler.svg", slug: "ler", name: "Ler" }, @@ -43,7 +43,7 @@ const LOGOS_DATA = [ { file: "logo-sncf1985.svg", slug: "sncf1985", name: "Sncf1985" }, { file: "logo-sncf1992.svg", slug: "sncf1992", name: "Sncf1992" }, { file: "logo-teoz.svg", slug: "teoz", name: "Teoz" }, - { file: "logo-ter.svg", slug: "ter", name: "TER" }, + { file: "logo-ter-rhone-alpes.svg", slug: "ter-rhone-alpes", name: "TER Rhone-Alpes" }, { file: "logo-teralsace.svg", slug: "teralsace", name: "Ter Alsace" }, { file: "logo-teraquitaine.svg", slug: "teraquitaine", name: "Ter Aquitaine" }, @@ -64,6 +64,7 @@ const LOGOS_DATA = [ { file: "logo-tramtrain.svg", slug: "tramtrain", name: "Tramtrain" }, { file: "logo-trenitalia.svg", slug: "trenitalia", name: "Trenitalia" }, { file: "logo-zou.svg", slug: "zou", name: "Zou" } + ]; const logoLookup = new Map(); @@ -85,7 +86,7 @@ LOGOS_DATA.forEach((item) => { */ export function getTrainLogoAndMeta(horaire) { if (!horaire) { - return { logoSrc: '/type/logo-sncf.svg', typeLabel: 'TER', numTrain: '' }; + return { logoSrc: '/type/sncf-voyageurs-logo.png', typeLabel: 'TER', numTrain: '' }; } const opRaw = String( @@ -152,7 +153,7 @@ export function getTrainLogoAndMeta(horaire) { } else if (opNorm.includes('renfe') || opNorm.includes('ave')) { matchedLogo = logoLookup.get('renfeave'); } else if (opNorm.includes('car') || opNorm.includes('autocar') || opNorm.includes('bus')) { - matchedLogo = logoLookup.get('trackcar') || { file: 'track-car.svg', name: 'Car TER' }; + matchedLogo = logoLookup.get('trackcar') || { file: 'sncf-voyageurs-logo.png', name: 'Car TER' }; } } @@ -194,7 +195,7 @@ export function getTrainLogoAndMeta(horaire) { } else if (opNorm.includes('lyria')) { typeLabel = 'TGV Lyria'; } else if (opNorm.includes('car') || opNorm.includes('autocar') || opNorm.includes('bus')) { - typeLabel = 'AUTOCAR'; + typeLabel = 'Car TER'; } else if (opNorm.includes('ter')) { typeLabel = 'TER'; } @@ -222,11 +223,11 @@ export function getTrainLogoAndMeta(horaire) { } else if ((p3 >= 860 && p3 <= 862) || (p4 >= 1675 && p4 <= 1684)) { matchedBrandSlug = 'remi'; matchedBrandLabel = 'RÉMI'; } else if ((p3 >= 863 && p3 <= 869) || (p4 >= 1685 && p4 <= 1709)) { - matchedBrandSlug = 'teraquitaine'; matchedBrandLabel = 'TER NOUVELLE-AQUITAINE'; + matchedBrandSlug = 'teraquitaine'; matchedBrandLabel = 'TER NA'; } else if ((p3 >= 870 && p3 <= 872) || (p3 >= 876 && p3 <= 878) || (p4 >= 1710 && p4 <= 1719) || (p4 >= 1730 && p4 <= 1734)) { matchedBrandSlug = 'lio'; matchedBrandLabel = 'liO'; } else if ((p3 >= 873 && p3 <= 875) || (p3 >= 882 && p3 <= 890) || (p4 >= 1720 && p4 <= 1729) || (p4 >= 1750 && p4 <= 1774) || (p4 >= 1790 && p4 <= 1799)) { - matchedBrandSlug = 'ter-rhone-alpes'; matchedBrandLabel = 'TER AUVERGNE-RHÔNE-ALPES'; + matchedBrandSlug = 'ter-rhone-alpes'; matchedBrandLabel = 'TER AURA'; } else if ((p3 >= 879 && p3 <= 881) || (p4 >= 1735 && p4 <= 1749)) { matchedBrandSlug = 'zou'; matchedBrandLabel = 'ZOU !'; } else if ((p3 >= 891 && p3 <= 895) || (p4 >= 1775 && p4 <= 1789)) { @@ -235,13 +236,13 @@ export function getTrainLogoAndMeta(horaire) { if (matchedBrandSlug && matchedBrandLabel) { typeLabel = matchedBrandLabel; - if (!matchedLogo || matchedLogo.file === 'logo-ter.svg' || matchedLogo.file === 'logo-sncf.svg') { + if (!matchedLogo || matchedLogo.file === 'logo-sncf.svg' || matchedLogo.file === 'logo-sncf.svg') { matchedLogo = logoLookup.get(matchedBrandSlug) || matchedLogo; } } } } - const logoFile = (matchedLogo && matchedLogo.file) || 'logo-sncf.svg'; + const logoFile = (matchedLogo && matchedLogo.file) || 'sncf-voyageurs-logo.png'; const logoSrc = `/type/${logoFile}`; return { logoSrc, typeLabel, numTrain };