Patch Build App
This commit is contained in:
1 parent
79842b8c44
commit
e42f6c01ec
3 files changed
+8
-35
No files matched your search
Generated
-27
@@ -20,33 +20,6 @@
|
|||||||
</PendingDiffInfo>
|
</PendingDiffInfo>
|
||||||
</value>
|
</value>
|
||||||
</entry>
|
</entry>
|
||||||
<entry key="$PROJECT_DIR$/src/pages/afficheurs/classiques/ClassiquesDeparts.js">
|
|
||||||
<value>
|
|
||||||
<PendingDiffInfo>
|
|
||||||
<option name="filePath" value="$PROJECT_DIR$/src/pages/afficheurs/classiques/ClassiquesDeparts.js" />
|
|
||||||
<option name="originalContent" value="import React, { useEffect, useState, useCallback } from 'react'; import './ClassiquesDeparts.css'; import supabase from '../../../lib/supabase'; // Helper utilitaire : format HHhMM sans secondes (ex: 06h44) const formatTimeNoSeconds = (v) => { if (v == null) return ''; const tryDate = new Date(v); if (!isNaN(tryDate.getTime())) { 	const hh = String(tryDate.getHours()).padStart(2, '0'); 	const mm = String(tryDate.getMinutes()).padStart(2, '0'); 	return `${hh}h${mm}`; } if (typeof v === 'string') { 	const m = v.match(/(\d{1,2}):(\d{2})(?::\d{2})?/); 	if (m) return `${String(m[1]).padStart(2,'0')}h${m[2]}`; 	const m2 = v.match(/T(\d{2}):(\d{2})/); 	if (m2) return `${m2[1]}h${m2[2]}`; 	return v.slice(0,5).replace(':','h'); } return String(v).slice(0,5).replace(':','h'); }; // Données proviennent exclusivement de la table `horaires`. function Logo({op}){ // Tente de charger un logo SVG depuis /type/ en fonction de l'opérateur. // mapping pour opérateurs connus -> noms de fichiers dans public/type const mapping = { 	'TGV inOUI': 'logo-inoui.svg', 	'TGV inOUI ': 'logo-inoui.svg', 	'TGV': 'logo-tgv.svg', 	'TER': 'sncf-voyageurs-logo.png', 	'MOBIGO': 'logo-mobigo.svg', 	'TGV Lyria': 'logo-lyria.svg', 	'TGV Lyria ': 'logo-lyria.svg', }; const defaultFileFromOp = (name) => { 	if (!name) return null; 	// nettoyer et fabriquer un nom plausible : "logo-<slug>.svg" 	const slug = name.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-|-$/g, ''); 	return `logo-${slug}.svg`; }; const fileName = mapping[op] || mapping[op.split(' ')[0]] || defaultFileFromOp(op); const [hasImg, setHasImg] = React.useState(true); return ( 	<div className="aff-classiques-departs__logo-box" aria-hidden> 	 {hasImg && fileName ? ( 		<img 		 src={`/type/${fileName}`} 		 alt={op} 		 className="aff-classiques-departs__op-logo" 		 onError={()=> setHasImg(false)} 		/> 	 ) : ( 		<div className="aff-classiques-departs__logo-text" aria-hidden>{op.split(' ')[0]}</div> 	 )} 	</div> ); } // (La fonction TrainType a été retirée car la colonne affiche désormais directement les // informations via .train-meta dans la colonne .col-train-type) function Clock(){ const [now, setNow] = useState(new Date()); useEffect(() => { 	const id = setInterval(() => setNow(new Date()), 1000); 	return () => clearInterval(id); }, []); const hh = String(now.getHours()).padStart(2, '0'); const mm = String(now.getMinutes()).padStart(2, '0'); const ss = String(now.getSeconds()).padStart(2, '0'); return ( 	<div className="aff-classiques-departs__clock-container" aria-hidden> 	 <div className="aff-classiques-departs__clock-box"> 		<div className="aff-classiques-departs__clock-main">{hh}:{mm}</div> 		<div className="aff-classiques-departs__clock-seconds">{ss}</div> 	 </div> 	</div> ); } export default function ClassiquesDeparts(){ // lire le paramètre de requête ?gare=Nom-de-la-gare const params = new URLSearchParams(window.location.search); const gareParam = params.get('gare'); // support pour ?gare_id=123 ou ?gareId=123 const gareIdParam = params.get('gare_id') || params.get('gareId'); // gérer les +, décoder et remplacer les tirets par des espaces const gareDisplay = gareParam ? decodeURIComponent(String(gareParam).replace(/\+/g, ' ')).replace(/-/g, ' ') : null; // debug flag activable via ?debug=1 or ?debug=true const debugEnabled = (params.get('debug') === '1' || String(params.get('debug')).toLowerCase() === 'true'); const debug = useCallback((...args) => { if (debugEnabled) console.debug(...args); }, [debugEnabled]); // État pour alterner l'affichage toutes les 3 secondes const [showStatus, setShowStatus] = useState(false); // Données depuis Supabase const [horaires, setHoraires] = useState([]); const [allHoraires, setAllHoraires] = useState([]); const [perturbations, setPerturbations] = useState([]); // type de la gare affichée (valeurs attendues: 'interurbaine', 'ville', ...) const [stationType, setStationType] = useState(null); const [, setTravaux] = useState([]); const [, setLoading] = useState(false); const [, setError] = uLine truncated
|
|
||||||
<option name="updatedContent" value="import React, { useEffect, useState, useCallback } from 'react'; import './ClassiquesDeparts.css'; import supabase from '../../../lib/supabase'; // Helper utilitaire : format HHhMM sans secondes (ex: 06h44) const formatTimeNoSeconds = (v) => { if (v == null) return ''; const tryDate = new Date(v); if (!isNaN(tryDate.getTime())) { 	const hh = String(tryDate.getHours()).padStart(2, '0'); 	const mm = String(tryDate.getMinutes()).padStart(2, '0'); 	return `${hh}h${mm}`; } if (typeof v === 'string') { 	const m = v.match(/(\d{1,2}):(\d{2})(?::\d{2})?/); 	if (m) return `${String(m[1]).padStart(2,'0')}h${m[2]}`; 	const m2 = v.match(/T(\d{2}):(\d{2})/); 	if (m2) return `${m2[1]}h${m2[2]}`; 	return v.slice(0,5).replace(':','h'); } return String(v).slice(0,5).replace(':','h'); }; // Données proviennent exclusivement de la table `horaires`. function Logo({op}){ // Tente de charger un logo SVG depuis /type/ en fonction de l'opérateur. // mapping pour opérateurs connus -> noms de fichiers dans public/type const mapping = { 	'TGV inOUI': 'logo-inoui.svg', 	'TGV inOUI ': 'logo-inoui.svg', 	'TGV': 'logo-tgv.svg', 	'TER': 'sncf-voyageurs-logo.png', 	'MOBIGO': 'logo-mobigo.svg', 	'TGV Lyria': 'logo-lyria.svg', 	'TGV Lyria ': 'logo-lyria.svg', }; const defaultFileFromOp = (name) => { 	if (!name) return null; 	// nettoyer et fabriquer un nom plausible : "logo-<slug>.svg" 	const slug = name.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-|-$/g, ''); 	return `logo-${slug}.svg`; }; const fileName = mapping[op] || mapping[op.split(' ')[0]] || defaultFileFromOp(op); const [hasImg, setHasImg] = React.useState(true); return ( 	<div className="aff-classiques-departs__logo-box" aria-hidden> 	 {hasImg && fileName ? ( 		<img 		 src={`/type/${fileName}`} 		 alt={op} 		 className="aff-classiques-departs__op-logo" 		 onError={()=> setHasImg(false)} 		/> 	 ) : ( 		<div className="aff-classiques-departs__logo-text" aria-hidden>{op.split(' ')[0]}</div> 	 )} 	</div> ); } // (La fonction TrainType a été retirée car la colonne affiche désormais directement les // informations via .train-meta dans la colonne .col-train-type) function Clock(){ const [now, setNow] = useState(new Date()); useEffect(() => { 	const id = setInterval(() => setNow(new Date()), 1000); 	return () => clearInterval(id); }, []); const hh = String(now.getHours()).padStart(2, '0'); const mm = String(now.getMinutes()).padStart(2, '0'); const ss = String(now.getSeconds()).padStart(2, '0'); return ( 	<div className="aff-classiques-departs__clock-container" aria-hidden> 	 <div className="aff-classiques-departs__clock-box"> 		<div className="aff-classiques-departs__clock-main">{hh}:{mm}</div> 		<div className="aff-classiques-departs__clock-seconds">{ss}</div> 	 </div> 	</div> ); } export default function ClassiquesDeparts(){ // lire le paramètre de requête ?gare=Nom-de-la-gare const params = new URLSearchParams(window.location.search); const gareParam = params.get('gare'); // support pour ?gare_id=123 ou ?gareId=123 const gareIdParam = params.get('gare_id') || params.get('gareId'); // gérer les +, décoder et remplacer les tirets par des espaces const gareDisplay = gareParam ? decodeURIComponent(String(gareParam).replace(/\+/g, ' ')).replace(/-/g, ' ') : null; // debug flag activable via ?debug=1 or ?debug=true const debugEnabled = (params.get('debug') === '1' || String(params.get('debug')).toLowerCase() === 'true'); const debug = useCallback((...args) => { if (debugEnabled) console.debug(...args); }, [debugEnabled]); // État pour alterner l'affichage toutes les 3 secondes const [showStatus, setShowStatus] = useState(false); // Données depuis Supabase const [horaires, setHoraires] = useState([]); const [allHoraires, setAllHoraires] = useState([]); const [perturbations, setPerturbations] = useState([]); // type de la gare affichée (valeurs attendues: 'interurbaine', 'ville', ...) const [stationType, setStationType] = useState(null); const [, setTravaux] = useState([]); const [, setLoading] = useState(false); const [, setError] = usLine truncated
|
|
||||||
</PendingDiffInfo>
|
|
||||||
</value>
|
|
||||||
</entry>
|
|
||||||
<entry key="$PROJECT_DIR$/src/pages/afficheurs/classiques/quais/ClassiquesArriveesQuais.js">
|
|
||||||
<value>
|
|
||||||
<PendingDiffInfo>
|
|
||||||
<option name="filePath" value="$PROJECT_DIR$/src/pages/afficheurs/classiques/quais/ClassiquesArriveesQuais.js" />
|
|
||||||
<option name="originalContent" value="import React, { useEffect, useState, useRef, useCallback } from 'react'; import './ClassiquesArriveesQuais.css'; import '../ClassiquesArrivees.css'; /* ClassiquesArriveesQuais.js Variante "Arrivées - quais" du composant quais. Différences principales avec la version départs: - utilise `heure_arrivee` / `gare_arrivee_*` lorsque disponible pour afficher l'heure et la destination - watermark affiché: "arrivée" - styles importés depuis `ClassiquesArriveesQuais.css` qui reprend la palette de `ClassiquesArrivees.css` Champs utilisés pour le calcul/affichage: - horaire.heure_arrivee, horaire.time, horaire.heure - horaire.gare_arrivee_nom, horaire.gare_arrivee - stop.heure_arrivee, stop.gare_nom, stop.gare_id - perturbations: mêmes clés que pour les départs (retard, retard_minutes, perturbations_arrets, etc.) */ import supabase from '../../../../lib/supabase'; // Hook pour récupérer la map des logos depuis /type/data.json function useTypeLogos(){ const [map, setMap] = useState({ default: '/type/quais/logo-sncf-color.svg' }); useEffect(() => { let mounted = true; const load = async () => { const candidates = ['/type/quais/data-color.json', '/type/data.json']; for(const url of candidates){ try{ const res = await fetch(url); if(!res.ok) continue; const data = await res.json(); if(!mounted) return; const logos = {}; if(Array.isArray(data.logos)){ data.logos.forEach(item => { // item.file is expected (ex: logo-tgv.svg). If absent, try to extract from path let file = item.file; if(!file && item.path){ const parts = String(item.path).split('/'); file = parts[parts.length-1]; } if(!file) return; const basename = file.replace(/\.[^/.]+$/, ''); const semantic = basename.replace(/^logo-/, ''); const key = semantic.toUpperCase().replace(/[^A-Z0-9]+/g, '-'); // Prefer color logos in the 'quais' subfolder if data came from the quais file if(url.includes('/quais/')){ logos[key] = `/type/quais/${file}`; } else { logos[key] = `/type/${file}`; } }); } logos.default = logos['SNCF-VOYAGEURS-LOGO'] || logos['SNFC-VOYAGEURS-LOGO'] || logos['SNCF'] || '/type/sncf-voyageurs-logo.png'; setMap(logos); return; }catch(e){ // try next candidate (ignore error and continue loop) } } // no candidate succeeded — keep fallback }; load(); return () => { mounted = false; }; }, []); return map; } function getTypeLogo(type, TYPE_LOGOS_MAP){ const map = TYPE_LOGOS_MAP || { default: '/type/sncf-voyageurs-logo.png' }; if(!type) return map.default; const norm = String(type).toUpperCase().replace(/[^A-Z0-9]+/g, '-'); if(map[norm]) return map[norm]; const keys = Object.keys(map).filter(k => k !== 'default'); for(const k of keys){ if(k.includes(norm) || norm.includes(k)) return map[k]; } return map.default; } function Clock() { const [now, setNow] = useState(new Date()); useEffect(() => { const id = setInterval(() => setNow(new Date()), 1000); return () => clearInterval(id); }, []); const hh = String(now.getHours()).padStart(2,'0'); const mm = String(now.getMinutes()).padStart(2,'0'); const ss = String(now.getSeconds()).padStart(2,'0'); return ( <div className="aff-quais__clock"> <div className="aff-quais__clock-box"><span className="aff-quais__clock-main">{hh}:{mm}:{ss}</span></div> </div> ); } export default function ClassiquesArriveesQuais(){ const typeLogos = useTypeLogos(); const rightRef = useRef(null); const stopsListRef = useRef(null);Line truncated
|
|
||||||
<option name="updatedContent" value="import React, { useEffect, useState, useRef, useCallback } from 'react'; import './ClassiquesArriveesQuais.css'; import '../ClassiquesArrivees.css'; /* ClassiquesArriveesQuais.js Variante "Arrivées - quais" du composant quais. Différences principales avec la version départs: - utilise `heure_arrivee` / `gare_arrivee_*` lorsque disponible pour afficher l'heure et la destination - watermark affiché: "arrivée" - styles importés depuis `ClassiquesArriveesQuais.css` qui reprend la palette de `ClassiquesArrivees.css` Champs utilisés pour le calcul/affichage: - horaire.heure_arrivee, horaire.time, horaire.heure - horaire.gare_arrivee_nom, horaire.gare_arrivee - stop.heure_arrivee, stop.gare_nom, stop.gare_id - perturbations: mêmes clés que pour les départs (retard, retard_minutes, perturbations_arrets, etc.) */ import supabase from '../../../../lib/supabase'; // Hook pour récupérer la map des logos depuis /type/data.json function useTypeLogos(){ const [map, setMap] = useState({ default: '/type/quais/logo-sncf-color.svg' }); useEffect(() => { let mounted = true; const load = async () => { const candidates = ['/type/quais/data-color.json', '/type/data.json']; for(const url of candidates){ try{ const res = await fetch(url); if(!res.ok) continue; const data = await res.json(); if(!mounted) return; const logos = {}; if(Array.isArray(data.logos)){ data.logos.forEach(item => { // item.file is expected (ex: logo-tgv.svg). If absent, try to extract from path let file = item.file; if(!file && item.path){ const parts = String(item.path).split('/'); file = parts[parts.length-1]; } if(!file) return; const basename = file.replace(/\.[^/.]+$/, ''); const semantic = basename.replace(/^logo-/, ''); const key = semantic.toUpperCase().replace(/[^A-Z0-9]+/g, '-'); // Prefer color logos in the 'quais' subfolder if data came from the quais file if(url.includes('/quais/')){ logos[key] = `/type/quais/${file}`; } else { logos[key] = `/type/${file}`; } }); } logos.default = logos['SNCF-VOYAGEURS-LOGO'] || logos['SNFC-VOYAGEURS-LOGO'] || logos['SNCF'] || '/type/sncf-voyageurs-logo.png'; setMap(logos); return; }catch(e){ // try next candidate (ignore error and continue loop) } } // no candidate succeeded — keep fallback }; load(); return () => { mounted = false; }; }, []); return map; } function getTypeLogo(type, TYPE_LOGOS_MAP){ const map = TYPE_LOGOS_MAP || { default: '/type/sncf-voyageurs-logo.png' }; if(!type) return map.default; const norm = String(type).toUpperCase().replace(/[^A-Z0-9]+/g, '-'); if(map[norm]) return map[norm]; const keys = Object.keys(map).filter(k => k !== 'default'); for(const k of keys){ if(k.includes(norm) || norm.includes(k)) return map[k]; } return map.default; } function Clock() { const [now, setNow] = useState(new Date()); useEffect(() => { const id = setInterval(() => setNow(new Date()), 1000); return () => clearInterval(id); }, []); const hh = String(now.getHours()).padStart(2,'0'); const mm = String(now.getMinutes()).padStart(2,'0'); const ss = String(now.getSeconds()).padStart(2,'0'); return ( <div className="aff-quais__clock"> <div className="aff-quais__clock-box"><span className="aff-quais__clock-main">{hh}:{mm}:{ss}</span></div> </div> ); } export default function ClassiquesArriveesQuais(){ const typeLogos = useTypeLogos(); const rightRef = useRef(null); const stopsListRef = useRef(null);
Line truncated
|
|
||||||
</PendingDiffInfo>
|
|
||||||
</value>
|
|
||||||
</entry>
|
|
||||||
<entry key="$PROJECT_DIR$/src/pages/afficheurs/classiques/quais/ClassiquesDepartsQuais.js">
|
|
||||||
<value>
|
|
||||||
<PendingDiffInfo>
|
|
||||||
<option name="filePath" value="$PROJECT_DIR$/src/pages/afficheurs/classiques/quais/ClassiquesDepartsQuais.js" />
|
|
||||||
<option name="originalContent" value="import React, { useEffect, useState, useRef, useCallback } from 'react'; import './ClassiquesDepartsQuais.css'; import supabase from '../../../../lib/supabase'; // Hook pour récupérer la map des logos depuis /type/data.json function useTypeLogos(){ const [map, setMap] = useState({ default: '/type/quais/logo-sncf-color.svg' }); useEffect(() => { let mounted = true; const load = async () => { const candidates = ['/type/quais/data-color.json', '/type/data.json']; for(const url of candidates){ try{ const res = await fetch(url); if(!res.ok) continue; const data = await res.json(); if(!mounted) return; const logos = {}; if(Array.isArray(data.logos)){ data.logos.forEach(item => { // item.file is expected (ex: logo-tgv.svg). If absent, try to extract from path let file = item.file; if(!file && item.path){ const parts = String(item.path).split('/'); file = parts[parts.length-1]; } if(!file) return; const basename = file.replace(/\.[^/.]+$/, ''); const semantic = basename.replace(/^logo-/, ''); const key = semantic.toUpperCase().replace(/[^A-Z0-9]+/g, '-'); // Prefer color logos in the 'quais' subfolder if data came from the quais file if(url.includes('/quais/')){ logos[key] = `/type/quais/${file}`; } else { logos[key] = `/type/${file}`; } }); } logos.default = logos['SNCF-VOYAGEURS-LOGO'] || logos['SNFC-VOYAGEURS-LOGO'] || logos['SNCF'] || '/type/sncf-voyageurs-logo.png'; setMap(logos); return; }catch(e){ // try next candidate (ignore error and continue loop) } } // no candidate succeeded — keep fallback }; load(); return () => { mounted = false; }; }, []); return map; } function getTypeLogo(type, TYPE_LOGOS_MAP){ const map = TYPE_LOGOS_MAP || { default: '/type/sncf-voyageurs-logo.png' }; if(!type) return map.default; const norm = String(type).toUpperCase().replace(/[^A-Z0-9]+/g, '-'); if(map[norm]) return map[norm]; const keys = Object.keys(map).filter(k => k !== 'default'); for(const k of keys){ if(k.includes(norm) || norm.includes(k)) return map[k]; } return map.default; } function Clock() { const [now, setNow] = useState(new Date()); useEffect(() => { const id = setInterval(() => setNow(new Date()), 1000); return () => clearInterval(id); }, []); const hh = String(now.getHours()).padStart(2,'0'); const mm = String(now.getMinutes()).padStart(2,'0'); const ss = String(now.getSeconds()).padStart(2,'0'); return ( <div className="aff-quais__clock"> <div className="aff-quais__clock-box"><span className="aff-quais__clock-main">{hh}:{mm}:{ss}</span></div> </div> ); } export default function ClassiquesDepartsQuais(){ const typeLogos = useTypeLogos(); const rightRef = useRef(null); const stopsListRef = useRef(null); const railRef = useRef(null); // fallback mock strict (utilisé uniquement si aucune donnée réelle n'est trouvée) const mock = { time: '16h44', status: "à l'heure", trainType: 'Fluo', trainNumber: '891811', destinationBig: 'Seurre', destinationStation: '', stops: [ 'Ouges','Saulon','Longecourt','Aiserey','Brazey-en-Plaine','Saint-Jean-de-Losne','Chaugey','Pagny','Seurre','Mervans','Louhans','Saint-Amour','Bourg-en-Bresse' ], }; // état pour l'horaire sélectionné const [selectedHoraire, setSelectedHoraire] = useState(null); const [loadingHoraire, setLoadingHoraire] = useState(false); const [horaireError, setHoraireError] = useState(null); const [candidatesCount, setCandidatesCount] = useState(0); // perturbations/travaux (récupérées depuis Supabase) const [perturbations, setPerturbations] = useState([]); const [, setTravaux] = useState([]); // helpers locaux (simples) — similaires à ceux du composant principal const normalizeName = useCallback((s) => { if (!s) return ''; try { return String(s).normalize('NFD').replace(/\p{M}/gu,'').toLowerCase().trim().replace(/[-_]+/g,' ').replace(/\s+/g,' '); } catch (eLine truncated
|
|
||||||
<option name="updatedContent" value="import React, { useEffect, useState, useRef, useCallback } from 'react'; import './ClassiquesDepartsQuais.css'; import supabase from '../../../../lib/supabase'; // Hook pour récupérer la map des logos depuis /type/data.json function useTypeLogos(){ const [map, setMap] = useState({ default: '/type/quais/logo-sncf-color.svg' }); useEffect(() => { let mounted = true; const load = async () => { const candidates = ['/type/quais/data-color.json', '/type/data.json']; for(const url of candidates){ try{ const res = await fetch(url); if(!res.ok) continue; const data = await res.json(); if(!mounted) return; const logos = {}; if(Array.isArray(data.logos)){ data.logos.forEach(item => { // item.file is expected (ex: logo-tgv.svg). If absent, try to extract from path let file = item.file; if(!file && item.path){ const parts = String(item.path).split('/'); file = parts[parts.length-1]; } if(!file) return; const basename = file.replace(/\.[^/.]+$/, ''); const semantic = basename.replace(/^logo-/, ''); const key = semantic.toUpperCase().replace(/[^A-Z0-9]+/g, '-'); // Prefer color logos in the 'quais' subfolder if data came from the quais file if(url.includes('/quais/')){ logos[key] = `/type/quais/${file}`; } else { logos[key] = `/type/${file}`; } }); } logos.default = logos['SNCF-VOYAGEURS-LOGO'] || logos['SNFC-VOYAGEURS-LOGO'] || logos['SNCF'] || '/type/sncf-voyageurs-logo.png'; setMap(logos); return; }catch(e){ // try next candidate (ignore error and continue loop) } } // no candidate succeeded — keep fallback }; load(); return () => { mounted = false; }; }, []); return map; } function getTypeLogo(type, TYPE_LOGOS_MAP){ const map = TYPE_LOGOS_MAP || { default: '/type/sncf-voyageurs-logo.png' }; if(!type) return map.default; const norm = String(type).toUpperCase().replace(/[^A-Z0-9]+/g, '-'); if(map[norm]) return map[norm]; const keys = Object.keys(map).filter(k => k !== 'default'); for(const k of keys){ if(k.includes(norm) || norm.includes(k)) return map[k]; } return map.default; } function Clock() { const [now, setNow] = useState(new Date()); useEffect(() => { const id = setInterval(() => setNow(new Date()), 1000); return () => clearInterval(id); }, []); const hh = String(now.getHours()).padStart(2,'0'); const mm = String(now.getMinutes()).padStart(2,'0'); const ss = String(now.getSeconds()).padStart(2,'0'); return ( <div className="aff-quais__clock"> <div className="aff-quais__clock-box"><span className="aff-quais__clock-main">{hh}:{mm}:{ss}</span></div> </div> ); } export default function ClassiquesDepartsQuais(){ const typeLogos = useTypeLogos(); const rightRef = useRef(null); const stopsListRef = useRef(null); const railRef = useRef(null); // fallback mock strict (utilisé uniquement si aucune donnée réelle n'est trouvée) const mock = { time: '16h44', status: "à l'heure", trainType: 'Fluo', trainNumber: '891811', destinationBig: 'Seurre', destinationStation: '', stops: [ 'Ouges','Saulon','Longecourt','Aiserey','Brazey-en-Plaine','Saint-Jean-de-Losne','Chaugey','Pagny','Seurre','Mervans','Louhans','Saint-Amour','Bourg-en-Bresse' ], }; // état pour l'horaire sélectionné const [selectedHoraire, setSelectedHoraire] = useState(null); const [loadingHoraire, setLoadingHoraire] = useState(false); const [horaireError, setHoraireError] = useState(null); const [candidatesCount, setCandidatesCount] = useState(0); // perturbations/travaux (récupérées depuis Supabase) const [perturbations, setPerturbations] = useState([]); const [, setTravaux] = useState([]); // helpers locaux (simples) — similaires à ceux du composant principal const normalizeName = useCallback((s) => { if (!s) return ''; try { return String(s).normalize('NFD').replace(/\p{M}/gu,'').toLowerCase().trim().replace(/[-_]+/g,' ').replace(/\s+/g,' '); } catch (e)Line truncated
|
|
||||||
</PendingDiffInfo>
|
|
||||||
</value>
|
|
||||||
</entry>
|
|
||||||
</map>
|
</map>
|
||||||
</option>
|
</option>
|
||||||
</component>
|
</component>
|
||||||
|
|||||||
@@ -260,7 +260,7 @@ export default function ClassiquesArriveesQuais(){
|
|||||||
return result.size ? result : null;
|
return result.size ? result : null;
|
||||||
}, [parsePerturbArretsObject]);
|
}, [parsePerturbArretsObject]);
|
||||||
|
|
||||||
const parseDelayMinutesFromArret = (arret) => {
|
const parseDelayMinutesFromArret = useCallback((arret) => {
|
||||||
if (!arret) return null;
|
if (!arret) return null;
|
||||||
const keys = ['retard_minutes','retard','delay_minutes','delay','retard_min'];
|
const keys = ['retard_minutes','retard','delay_minutes','delay','retard_min'];
|
||||||
for (const k of keys) {
|
for (const k of keys) {
|
||||||
@@ -269,7 +269,7 @@ export default function ClassiquesArriveesQuais(){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
};
|
}, []);
|
||||||
|
|
||||||
const buildPerturbMap = useCallback((list = []) => {
|
const buildPerturbMap = useCallback((list = []) => {
|
||||||
const idx = { byHoraire: {}, byNumber: {}, byStopId: {}, byStopName: {}, global: [] };
|
const idx = { byHoraire: {}, byNumber: {}, byStopId: {}, byStopName: {}, global: [] };
|
||||||
@@ -292,7 +292,7 @@ export default function ClassiquesArriveesQuais(){
|
|||||||
return idx;
|
return idx;
|
||||||
}, [normalizeName]);
|
}, [normalizeName]);
|
||||||
|
|
||||||
const findPerturbsForHoraireAndStop = (horaire, stationId, stationName, idx) => {
|
const findPerturbsForHoraireAndStop = useCallback((horaire, stationId, stationName, idx) => {
|
||||||
const res = [];
|
const res = [];
|
||||||
const map = idx || buildPerturbMap(perturbations || []);
|
const map = idx || buildPerturbMap(perturbations || []);
|
||||||
const hId = horaire && (horaire.id || horaire.horaire_id || horaire.numero || horaire.numero_train);
|
const hId = horaire && (horaire.id || horaire.horaire_id || horaire.numero || horaire.numero_train);
|
||||||
@@ -312,7 +312,7 @@ export default function ClassiquesArriveesQuais(){
|
|||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
}
|
}
|
||||||
return Array.from(new Set(res));
|
return Array.from(new Set(res));
|
||||||
};
|
}, [buildPerturbMap, perturbations, normalizeName]);
|
||||||
|
|
||||||
const computeStatusForHoraireAtStop = useCallback((horaire, stationId, stationName, idx, serviceDate = null) => {
|
const computeStatusForHoraireAtStop = useCallback((horaire, stationId, stationName, idx, serviceDate = null) => {
|
||||||
const found = findPerturbsForHoraireAndStop(horaire, stationId, stationName, idx) || [];
|
const found = findPerturbsForHoraireAndStop(horaire, stationId, stationName, idx) || [];
|
||||||
|
|||||||
@@ -243,7 +243,7 @@ export default function ClassiquesDepartsQuais(){
|
|||||||
return result.size ? result : null;
|
return result.size ? result : null;
|
||||||
}, [parsePerturbArretsObject]);
|
}, [parsePerturbArretsObject]);
|
||||||
|
|
||||||
const parseDelayMinutesFromArret = (arret) => {
|
const parseDelayMinutesFromArret = useCallback((arret) => {
|
||||||
if (!arret) return null;
|
if (!arret) return null;
|
||||||
const keys = ['retard_minutes','retard','delay_minutes','delay','retard_min'];
|
const keys = ['retard_minutes','retard','delay_minutes','delay','retard_min'];
|
||||||
for (const k of keys) {
|
for (const k of keys) {
|
||||||
@@ -252,7 +252,7 @@ export default function ClassiquesDepartsQuais(){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
};
|
}, []);
|
||||||
|
|
||||||
const buildPerturbMap = useCallback((list = []) => {
|
const buildPerturbMap = useCallback((list = []) => {
|
||||||
const idx = { byHoraire: {}, byNumber: {}, byStopId: {}, byStopName: {}, global: [] };
|
const idx = { byHoraire: {}, byNumber: {}, byStopId: {}, byStopName: {}, global: [] };
|
||||||
@@ -275,7 +275,7 @@ export default function ClassiquesDepartsQuais(){
|
|||||||
return idx;
|
return idx;
|
||||||
}, [normalizeName]);
|
}, [normalizeName]);
|
||||||
|
|
||||||
const findPerturbsForHoraireAndStop = (horaire, stationId, stationName, idx) => {
|
const findPerturbsForHoraireAndStop = useCallback((horaire, stationId, stationName, idx) => {
|
||||||
const res = [];
|
const res = [];
|
||||||
const map = idx || buildPerturbMap(perturbations || []);
|
const map = idx || buildPerturbMap(perturbations || []);
|
||||||
const hId = horaire && (horaire.id || horaire.horaire_id || horaire.numero || horaire.numero_train);
|
const hId = horaire && (horaire.id || horaire.horaire_id || horaire.numero || horaire.numero_train);
|
||||||
@@ -295,7 +295,7 @@ export default function ClassiquesDepartsQuais(){
|
|||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
}
|
}
|
||||||
return Array.from(new Set(res));
|
return Array.from(new Set(res));
|
||||||
};
|
}, [buildPerturbMap, perturbations, normalizeName]);
|
||||||
|
|
||||||
const computeStatusForHoraireAtStop = useCallback((horaire, stationId, stationName, idx, serviceDate = null) => {
|
const computeStatusForHoraireAtStop = useCallback((horaire, stationId, stationName, idx, serviceDate = null) => {
|
||||||
const found = findPerturbsForHoraireAndStop(horaire, stationId, stationName, idx) || [];
|
const found = findPerturbsForHoraireAndStop(horaire, stationId, stationName, idx) || [];
|
||||||
|
|||||||
Reference in new issue
Block a user