RELEASE V5.0.0 : Voici les modifications apportées :

-> IMPLÉMENTATION DONNÉES GTFS / GTFS-RT / SIRI LTE SNCF
-> RESTRUCTURATION DE L'APP.

FONCTIONNALITÉS EN COURS DE DÉVELOPPEMENT :

-> REFONTE DU DESIGN DES AFFICHEURS CLASSIQUES
-> AMÉLIORATION DES
This commit is contained in:
mathis committed 2026-08-30 01:58:16 +02:00
1 parent 0e0d8c435f
commit 72de543dc6
18 files changed
+1550 -544

No files matched your search

+49 -10
View File
@@ -4,19 +4,22 @@ import { fetchAllRows } from '../../../lib/fetchAllRows';
import './AFLDepartsQuais.css';
import useAnnonceSonoreRealtime from '../../../hooks/useAnnonceSonoreRealtime';
import Logo from '../../../components/Logo';
import { getSourceFromPath } from '../../../services/railwayService';
import { getSncfTimetable } from '../../../services/sncfApi';
// Helper utilitaire : format HH:MM sans secondes (ex: 15:57)
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 hh = String(tryDate.getHours() % 24).padStart(2, '0');
const mm = String(tryDate.getMinutes()).padStart(2, '0');
return `${hh}:${mm}`;
}
const parts = String(v).split(':');
if (parts.length >= 2) {
return `${parts[0].padStart(2, '0')}:${parts[1].padStart(2, '0')}`;
const m = String(v).match(/(\d{1,2})[:h](\d{2})/i);
if (m) {
const h = parseInt(m[1], 10) % 24;
return `${String(h).padStart(2, '0')}:${m[2]}`;
}
return v;
};
@@ -185,9 +188,12 @@ const AFLDepartsQuais = () => {
const parseTimeHM = useCallback((s) => {
if (!s) return null;
if (typeof s === 'number') return s;
const m = String(s).match(/(\d{1,2})[h:](\d{2})/);
if (m) return parseInt(m[1], 10) * 60 + parseInt(m[2], 10);
if (typeof s === 'number') return s % 1440;
const m = String(s).match(/(\d{1,2})[h:](\d{2})/i);
if (m) {
const h = parseInt(m[1], 10) % 24;
return h * 60 + parseInt(m[2], 10);
}
const d = new Date(s);
if (!isNaN(d.getTime())) return d.getHours() * 60 + d.getMinutes();
return null;
@@ -421,6 +427,39 @@ const AFLDepartsQuais = () => {
const fetchData = useCallback(async () => {
try {
const source = getSourceFromPath(window.location.pathname);
if (source === 'sncf') {
const { data: sncfData } = await getSncfTimetable({
gareName: gareDisplay || gareParam,
mode: 'departs',
quai: quaiParam
});
if (sncfData && sncfData.length > 0) {
const train = sncfData[0];
const enriched = {
...train,
_rawTime: train.heure_depart,
_displayTime: formatTimeNoSeconds(train.heure_depart),
_status: {
label: train.etat === 'supprime' ? 'supprimé' : (train.retard_minutes > 0 ? `retardé +${train.retard_minutes}min.` : "à l'heure"),
detail: '',
delayMinutes: train.retard_minutes || null
},
_nextStationStatus: {
label: train.etat === 'supprime' ? 'supprimé' : (train.retard_minutes > 0 ? `retardé +${train.retard_minutes}min.` : "à l'heure")
},
_isToday: true
};
setNextDeparture(enriched);
} else {
setNextDeparture(null);
}
setLoading(false);
return;
}
if (!supabase) return;
const [{ data: horairesData }, { data: subData }, { data: perturbData }, { data: travauxData }] = await Promise.all([
fetchAllRows(supabase.from('horaires').select('*')),
supabase.from('travaux_substitutions').select('*'),
@@ -689,7 +728,7 @@ const AFLDepartsQuais = () => {
console.error(err);
setLoading(false);
}
}, [applyPerturbationsToHoraires, buildPerturbMap, gareDisplay, getPerturbationJours, getStops, normalizeName, parseTimeHM, quaiParam]);
}, [applyPerturbationsToHoraires, buildPerturbMap, gareDisplay, gareParam, getPerturbationJours, getStops, normalizeName, parseTimeHM, quaiParam]);
useEffect(() => {
fetchData();
@@ -780,7 +819,7 @@ const AFLDepartsQuais = () => {
if (gareDisplay && Array.isArray(stopsList)) {
stopForStation = stopsList.find(s => normalizeName((s.gare_nom || s.nom || s.name || '').toString()) === normalizeName(gareDisplay));
}
const platformStr = ((stopForStation && (stopForStation.quai_reel || stopForStation.quai || stopForStation.platform || stopForStation.quay)) || trainData.quai_reel || trainData.voie || trainData.quai || quaiParam || '').toString().trim();
const platformStr = ((stopForStation && (stopForStation.quai_reel || stopForStation.quai || stopForStation.platform || stopForStation.quay)) || trainData.quai_reel || trainData.voie || trainData.quai || trainData._displayPlatform || quaiParam || '').toString().trim() || quaiParam || '1';
// Extraction des destinations (prise en compte des trains multi-branches / tranches)
let destinations = [];
@@ -839,7 +878,7 @@ const AFLDepartsQuais = () => {
return sName && (sName === normCurrent || sName.includes(normCurrent) || normCurrent.includes(sName));
});
const rawDownstream = startIdx !== -1 ? stopsList.slice(startIdx + 1) : stopsList.slice(1);
const rawDownstream = startIdx !== -1 ? stopsList.slice(startIdx + 1) : stopsList;
const seen = new Set();
rawDownstream.forEach(s => {