RELEASE V5.6.0 : Voici les modifications apportées :
-> REFONTE TOTALE DE TOUS LES AFFICHEURS CLASSIQUES + QUAIS + OPTION TGV FONCTIONNALITÉS EN COURS DE DÉVELOPPEMENT : -> ADAPTABILITÉ EN FONCTION DES SITUATIONS
This commit is contained in:
1 parent
9c6ac798f1
commit
d8f8ceaa9f
18 files changed
+2324
-533
No files matched your search
@@ -6,11 +6,35 @@ import useAnnonceSonoreRealtime from '../../../../hooks/useAnnonceSonoreRealtime
|
||||
import useAutoAnnonce from '../../../../hooks/useAutoAnnonce';
|
||||
import { getSourceFromPath } from '../../../../services/railwayService';
|
||||
import { getSncfTimetable } from '../../../../services/sncfApi';
|
||||
import { matchStationNameStrict } from '../../../../services/gtfsStations';
|
||||
import GareVideoprotection from '../../../../components/afficheurs/GareVideoprotection';
|
||||
import AttentifsEnsemble from '../../../../components/afficheurs/AttentifsEnsemble';
|
||||
import DepartEnCoursClassique from '../../../../components/afficheurs/DepartEnCoursClassique';
|
||||
import ClassiquesInformations from '../ClassiquesInformations';
|
||||
import ClassiquesDeparts from '../ClassiquesDeparts';
|
||||
import TgvCompositionQuai from '../../../../components/afficheurs/TgvCompositionQuai';
|
||||
|
||||
function TgvServiceIcons() {
|
||||
return (
|
||||
<div className="aff-classique-quai-dep__services">
|
||||
{/* PMR / Fauteuil roulant */}
|
||||
<svg width="30" height="30" viewBox="0 0 24 24" fill="#7e859b">
|
||||
<path d="M12 2a2 2 0 100 4 2 2 0 000-4zm-2 6a1 1 0 00-1 1v6a1 1 0 001 1h4a1 1 0 001-1v-2a1 1 0 00-2 0v1h-2v-4h3a1 1 0 001-1V9a1 1 0 00-1-1H10zm-1 9a4 4 0 100 8 4 4 0 000-8zm0 2a2 2 0 110 4 2 2 0 010-4z"/>
|
||||
</svg>
|
||||
{/* Vélo */}
|
||||
<svg width="34" height="30" viewBox="0 0 24 24" fill="none" stroke="#7e859b" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
||||
<circle cx="5.5" cy="17.5" r="3.5"/>
|
||||
<circle cx="18.5" cy="17.5" r="3.5"/>
|
||||
<path d="M15 6a1 1 0 100-2 1 1 0 000 2zm-3 11.5L9 11.5l3-3.5h3.5m-6.5 7L12 8"/>
|
||||
</svg>
|
||||
{/* Bar / Verre */}
|
||||
<svg width="28" height="30" viewBox="0 0 24 24" fill="none" stroke="#7e859b" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
||||
<path d="M4 4L12 14L20 4H4Z" fill="#7e859b" />
|
||||
<path d="M12 14V21M8 21H16" />
|
||||
</svg>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function DigitalClock() {
|
||||
const [now, setNow] = useState(new Date());
|
||||
@@ -132,6 +156,7 @@ export default function ClassiquesDepartsQuais() {
|
||||
const [, setHoraireError] = useState(null);
|
||||
const [currentTime, setCurrentTime] = useState(new Date());
|
||||
const [idlePhase, setIdlePhase] = useState(0); // 0 = Attentifs (20s), 1 = Quai (20s), 2 = Information (10s)
|
||||
const [showStatusAlt, setShowStatusAlt] = useState(false);
|
||||
|
||||
const pageParam = (searchParams.get('page') || searchParams.get('mode') || '').toLowerCase();
|
||||
const isVideoprotection = pageParam === 'videoprotection' || searchParams.get('videoprotection') === 'true';
|
||||
@@ -147,6 +172,12 @@ export default function ClassiquesDepartsQuais() {
|
||||
return () => clearInterval(id);
|
||||
}, []);
|
||||
|
||||
// Alternance 3 secondes : Heure normale ↔ Statut (pour trains retardés ou supprimés)
|
||||
useEffect(() => {
|
||||
const id = setInterval(() => setShowStatusAlt(prev => !prev), 3000);
|
||||
return () => clearInterval(id);
|
||||
}, []);
|
||||
|
||||
// Alternance par défaut (20s Attentifs -> 20s Quai -> 10s Information) si aucun train n'est prévu sur le quai
|
||||
useEffect(() => {
|
||||
if (selectedHoraire) return;
|
||||
@@ -317,14 +348,29 @@ export default function ClassiquesDepartsQuais() {
|
||||
if (sncfData && sncfData.length > 0) {
|
||||
let matchingTrains = sncfData;
|
||||
if (targetQuaiClean) {
|
||||
matchingTrains = sncfData.filter(t => cleanPlatform(t.quai || t.voie || t.quai_reel || t._displayPlatform) === targetQuaiClean);
|
||||
matchingTrains = sncfData.filter(t => cleanPlatform(t._displayPlatform || t.quai || t.voie || t.quai_reel) === targetQuaiClean);
|
||||
}
|
||||
const train = matchingTrains[0];
|
||||
if (train) {
|
||||
const depHM = parseTimeHM(train.heure_depart || train.time || train.heure);
|
||||
const trainPlatform = train._displayPlatform || train.quai || train.voie || quaiParam || '';
|
||||
const trainNumClean = (train.numero_train || train.num || '').toString();
|
||||
|
||||
// Recherche d'une deuxième tranche / train couplé au même horaire
|
||||
const partner = matchingTrains.find(t => {
|
||||
if (!t || t === train) return false;
|
||||
const tNum = (t.numero_train || t.num || '').toString();
|
||||
const tHM = parseTimeHM(t.heure_depart || t.time || t.heure);
|
||||
return tNum !== trainNumClean && tHM === depHM;
|
||||
});
|
||||
|
||||
chosenTrain = {
|
||||
horaire: {
|
||||
...train,
|
||||
quai: trainPlatform,
|
||||
quai_reel: trainPlatform,
|
||||
voie: trainPlatform,
|
||||
_displayPlatform: trainPlatform,
|
||||
_status: train._status || {
|
||||
label: train.etat === 'supprime' ? 'supprimé' : (train.retard_minutes > 0 ? `retardé +${train.retard_minutes}min.` : "à l'heure"),
|
||||
detail: '',
|
||||
@@ -332,10 +378,11 @@ export default function ClassiquesDepartsQuais() {
|
||||
causeDetails: train.cause_retard || null
|
||||
}
|
||||
},
|
||||
partner: partner || null,
|
||||
stop: {
|
||||
gare_nom: train.gare_depart_nom || gareDisplay || gareParam,
|
||||
heure_depart: train.heure_depart || train.time || train.heure,
|
||||
quai: train.quai || train.voie || quaiParam
|
||||
quai: trainPlatform
|
||||
},
|
||||
depHM: depHM != null ? depHM : 0,
|
||||
rawTime: train.heure_depart || train.time || train.heure
|
||||
@@ -355,13 +402,14 @@ export default function ClassiquesDepartsQuais() {
|
||||
} else if (gareDisplay) {
|
||||
const { data: gdata } = await supabase.from('gares').select('id,nom').ilike('nom', `%${gareDisplay}%`);
|
||||
if (gdata && gdata.length) {
|
||||
setResolvedGareId(gdata[0].id);
|
||||
const exactMatch = gdata.find(g => matchStationNameStrict(g.nom, gareDisplay));
|
||||
const chosen = exactMatch || (gdata.length === 1 ? gdata[0] : null);
|
||||
if (chosen) setResolvedGareId(chosen.id);
|
||||
}
|
||||
}
|
||||
|
||||
const { data: all, error } = await fetchAllRows(supabase.from('horaires').select('*'));
|
||||
if (!error && Array.isArray(all) && all.length > 0) {
|
||||
const normalizedTarget = gareDisplay ? normalizeName(gareDisplay) : null;
|
||||
const now = new Date();
|
||||
const tomorrow = new Date(now);
|
||||
tomorrow.setDate(now.getDate() + 1);
|
||||
@@ -377,14 +425,14 @@ export default function ClassiquesDepartsQuais() {
|
||||
const stops = getStops(h);
|
||||
let stopMatch = null;
|
||||
|
||||
if (normalizedTarget) {
|
||||
const destNameNorm = normalizeName(h.gare_arrivee_nom || h.gare_arrivee || '');
|
||||
if (destNameNorm && destNameNorm === normalizedTarget) {
|
||||
if (gareDisplay) {
|
||||
const destName = (h.gare_arrivee_nom || h.gare_arrivee || '').toString();
|
||||
if (matchStationNameStrict(destName, gareDisplay)) {
|
||||
// Destination finale -> terminus ici, pas un départ
|
||||
continue;
|
||||
}
|
||||
const departName = normalizeName(h.gare_depart_nom || h.gare_depart || '');
|
||||
if (departName && departName === normalizedTarget) {
|
||||
const departName = (h.gare_depart_nom || h.gare_depart || '').toString();
|
||||
if (matchStationNameStrict(departName, gareDisplay)) {
|
||||
stopMatch = {
|
||||
heure_depart: h.heure_depart || h.time || h.heure,
|
||||
gare_nom: h.gare_depart_nom || h.gare_depart,
|
||||
@@ -393,8 +441,8 @@ export default function ClassiquesDepartsQuais() {
|
||||
}
|
||||
if (!stopMatch && Array.isArray(stops)) {
|
||||
for (const s of stops) {
|
||||
const sName = normalizeName(typeof s === 'string' ? s : (s.gare_nom || s.nom || s.name || s.stop_name || ''));
|
||||
if (sName === normalizedTarget) {
|
||||
const sName = (typeof s === 'string' ? s : (s.gare_nom || s.nom || s.name || s.stop_name || '')).toString();
|
||||
if (matchStationNameStrict(sName, gareDisplay)) {
|
||||
stopMatch = s;
|
||||
break;
|
||||
}
|
||||
@@ -410,7 +458,11 @@ export default function ClassiquesDepartsQuais() {
|
||||
|
||||
if (!stopMatch) continue;
|
||||
|
||||
const platform = (stopMatch && (stopMatch.quai_reel || stopMatch.quai || stopMatch.platform || stopMatch.voie)) || h.quai_reel || h.voie || h.platform || h.quai || '';
|
||||
const rawTime = (stopMatch && typeof stopMatch === 'object' && (stopMatch.heure_depart || stopMatch.heure || stopMatch.time || stopMatch.heure_passage)) || h.heure_depart || h.time || h.heure;
|
||||
const depHM = parseTimeHM(rawTime);
|
||||
if (depHM == null) continue;
|
||||
|
||||
let platform = (stopMatch && (stopMatch.quai_reel || stopMatch.quai || stopMatch.platform || stopMatch.voie)) || h.quai_reel || h.voie || h.platform || h.quai || '';
|
||||
const platClean = cleanPlatform(platform);
|
||||
|
||||
if (targetQuaiClean) {
|
||||
@@ -419,10 +471,6 @@ export default function ClassiquesDepartsQuais() {
|
||||
}
|
||||
}
|
||||
|
||||
const rawTime = (stopMatch && typeof stopMatch === 'object' && (stopMatch.heure_depart || stopMatch.heure || stopMatch.time || stopMatch.heure_passage)) || h.heure_depart || h.time || h.heure;
|
||||
const depHM = parseTimeHM(rawTime);
|
||||
if (depHM == null) continue;
|
||||
|
||||
candidates.push({
|
||||
horaire: h,
|
||||
stop: stopMatch,
|
||||
@@ -450,7 +498,16 @@ export default function ClassiquesDepartsQuais() {
|
||||
: (filteredCandidates.length > 0 ? filteredCandidates.sort((a, b) => a.depHM - b.depHM)[0] : null));
|
||||
|
||||
if (chosen) {
|
||||
chosenTrain = chosen;
|
||||
const partnerCand = filteredCandidates.find(c => {
|
||||
if (!c || c === chosen) return false;
|
||||
const cNum = (c.horaire.numero_train || c.horaire.num || '').toString();
|
||||
const chosenNum = (chosen.horaire.numero_train || chosen.horaire.num || '').toString();
|
||||
return cNum !== chosenNum && c.depHM === chosen.depHM;
|
||||
});
|
||||
chosenTrain = {
|
||||
...chosen,
|
||||
partner: partnerCand ? partnerCand.horaire : null
|
||||
};
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
@@ -503,8 +560,7 @@ export default function ClassiquesDepartsQuais() {
|
||||
|
||||
// Filtrer les arrêts à partir de la gare courante
|
||||
if (gareDisplay && stopsList.length > 0) {
|
||||
const normCur = normalizeName(gareDisplay);
|
||||
const foundIdx = stopsList.findIndex(s => normalizeName(s) === normCur);
|
||||
const foundIdx = stopsList.findIndex(s => matchStationNameStrict(s, gareDisplay));
|
||||
if (foundIdx >= 0 && foundIdx < stopsList.length - 1) {
|
||||
stopsList = stopsList.slice(foundIdx + 1);
|
||||
}
|
||||
@@ -512,9 +568,8 @@ export default function ClassiquesDepartsQuais() {
|
||||
|
||||
// Garantir que le terminus est présent en dernier
|
||||
if (destinationName) {
|
||||
const destNorm = normalizeName(destinationName);
|
||||
const lastNorm = stopsList.length > 0 ? normalizeName(stopsList[stopsList.length - 1]) : '';
|
||||
if (lastNorm !== destNorm) {
|
||||
const lastStop = stopsList.length > 0 ? stopsList[stopsList.length - 1] : '';
|
||||
if (!matchStationNameStrict(lastStop, destinationName)) {
|
||||
stopsList.push(destinationName);
|
||||
}
|
||||
}
|
||||
@@ -567,10 +622,64 @@ export default function ClassiquesDepartsQuais() {
|
||||
}
|
||||
}
|
||||
|
||||
const partner = selectedHoraire?.partner;
|
||||
const destinationName1 = destinationName;
|
||||
const destinationName2 = partner ? (partner.gare_arrivee_nom || partner.gare_arrivee || partner.destination || partner.dest || '') : (horaire?.second_destination || horaire?.dest2 || horaire?.destination2 || (horaire?.tranches && horaire?.tranches[1]?.destination) || '');
|
||||
|
||||
const trainType1 = trainType;
|
||||
const trainType2 = partner ? (partner.type_train || partner.train_type || partner.type || partner.op || 'TGV') : (horaire?.type_train2 || horaire?.train_type2 || (destinationName2 ? trainType : ''));
|
||||
|
||||
const trainNumber1 = trainNumber;
|
||||
const trainNumber2 = partner ? (partner.numero_train || partner.numero || partner.num || '') : (horaire?.numero_train2 || horaire?.num2 || (horaire?.tranches && horaire?.tranches[1]?.num) || '');
|
||||
|
||||
const isDifferentDest = Boolean(destinationName1 && destinationName2 && !matchStationNameStrict(destinationName1, destinationName2));
|
||||
|
||||
// Récupération des arrêts de la deuxième tranche
|
||||
let stopsList2 = [];
|
||||
if (partner) {
|
||||
const rawStops2 = getStops(partner);
|
||||
if (Array.isArray(rawStops2) && rawStops2.length > 0) {
|
||||
stopsList2 = rawStops2.map(s => (typeof s === 'string' ? s : (s.gare_nom || s.nom || s.name || s.stop_name || ''))).filter(Boolean);
|
||||
}
|
||||
if (gareDisplay && stopsList2.length > 0) {
|
||||
const fIdx = stopsList2.findIndex(s => matchStationNameStrict(s, gareDisplay));
|
||||
if (fIdx >= 0 && fIdx < stopsList2.length - 1) {
|
||||
stopsList2 = stopsList2.slice(fIdx + 1);
|
||||
}
|
||||
}
|
||||
if (destinationName2 && !matchStationNameStrict(stopsList2[stopsList2.length - 1] || '', destinationName2)) {
|
||||
stopsList2.push(destinationName2);
|
||||
}
|
||||
}
|
||||
|
||||
// Calcul du tronc commun et des branches de séparation (Fourche Image 2)
|
||||
let commonStops = [];
|
||||
let branch1Stops = [];
|
||||
let branch2Stops = [];
|
||||
|
||||
if (isDifferentDest && stopsList.length > 0 && stopsList2.length > 0) {
|
||||
let divIdx = 0;
|
||||
const minLen = Math.min(stopsList.length, stopsList2.length);
|
||||
while (divIdx < minLen && matchStationNameStrict(stopsList[divIdx], stopsList2[divIdx])) {
|
||||
commonStops.push(stopsList[divIdx]);
|
||||
divIdx++;
|
||||
}
|
||||
branch1Stops = stopsList.slice(divIdx);
|
||||
branch2Stops = stopsList2.slice(divIdx);
|
||||
}
|
||||
|
||||
const isTgv = Boolean(
|
||||
(trainType1 || '').toUpperCase().includes('TGV') ||
|
||||
(trainType2 || '').toUpperCase().includes('TGV') ||
|
||||
(operator || '').toUpperCase().includes('TGV') ||
|
||||
(brand && (brand.label || '').toUpperCase().includes('TGV')) ||
|
||||
(horaire && ((horaire.type_train || horaire.type || '').toUpperCase().includes('TGV') || (horaire.op || '').toUpperCase().includes('TGV')))
|
||||
);
|
||||
|
||||
return (
|
||||
<div className="aff-classique-quai-dep__container">
|
||||
{/* PANNEAU GAUCHE : BLANC (Conforme Image 1) */}
|
||||
<div className="aff-classique-quai-dep__left">
|
||||
{/* PANNEAU GAUCHE : BLANC (Conforme Image 1 & Image 2) */}
|
||||
<div className={`aff-classique-quai-dep__left ${isTgv ? 'aff-classique-quai-dep__left--tgv' : ''}`}>
|
||||
{/* Logo Couleur Dynamique */}
|
||||
<div className="aff-classique-quai-dep__brand">
|
||||
<img src={brand.logo} alt={brand.label} className="aff-classique-quai-dep__brand-logo" />
|
||||
@@ -581,68 +690,164 @@ export default function ClassiquesDepartsQuais() {
|
||||
|
||||
{/* Heure et Statut */}
|
||||
<div className="aff-classique-quai-dep__time-row">
|
||||
<span className={`aff-classique-quai-dep__time ${isSuppressed ? 'aff-classique-quai-dep__time--suppressed' : ''} ${isDelayed ? 'aff-classique-quai-dep__time--delayed' : ''}`}>
|
||||
{formattedTime || '--:--'}
|
||||
</span>
|
||||
<span className={`aff-classique-quai-dep__status ${isSuppressed ? 'aff-classique-quai-dep__status--suppressed' : ''} ${isDelayed ? 'aff-classique-quai-dep__status--delayed' : ''}`}>
|
||||
{displayStatusText}
|
||||
</span>
|
||||
{(isSuppressed || isDelayed) ? (
|
||||
showStatusAlt ? (
|
||||
<span className={`aff-classique-quai-dep__status-alt ${isSuppressed ? 'aff-classique-quai-dep__status--suppressed' : 'aff-classique-quai-dep__status--delayed'}`}>
|
||||
{displayStatusText}
|
||||
</span>
|
||||
) : (
|
||||
<span className="aff-classique-quai-dep__time">
|
||||
{formattedTime || '--:--'}
|
||||
</span>
|
||||
)
|
||||
) : (
|
||||
<>
|
||||
<span className="aff-classique-quai-dep__time">
|
||||
{formattedTime || '--:--'}
|
||||
</span>
|
||||
<span className="aff-classique-quai-dep__status">
|
||||
{displayStatusText}
|
||||
</span>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Destination Principale */}
|
||||
<div className="aff-classique-quai-dep__destination">
|
||||
{destinationName || 'Aucun départ prévu'}
|
||||
<div className={`aff-classique-quai-dep__destination ${isDifferentDest ? 'aff-classique-quai-dep__destination--multi' : ''}`}>
|
||||
{destinationName1 || 'Aucun départ prévu'}
|
||||
</div>
|
||||
|
||||
{/* Type de Train & Numéro */}
|
||||
{/* Type de Train & Numéro 1 */}
|
||||
<div className="aff-classique-quai-dep__train-info">
|
||||
{trainType && <span className="aff-classique-quai-dep__train-type">{trainType}</span>}
|
||||
{trainNumber && <span className="aff-classique-quai-dep__train-number">{trainNumber}</span>}
|
||||
{trainType1 && <span className="aff-classique-quai-dep__train-type">{trainType1}</span>}
|
||||
{trainNumber1 && <span className="aff-classique-quai-dep__train-number">{trainNumber1}</span>}
|
||||
</div>
|
||||
|
||||
{/* Destination 2 si multi-tranche / destinations différentes (ex: Nice-Ville ou Bruxelles Midi) */}
|
||||
{isDifferentDest && (
|
||||
<>
|
||||
<div className="aff-classique-quai-dep__destination aff-classique-quai-dep__destination--multi" style={{ marginTop: '16px' }}>
|
||||
{destinationName2}
|
||||
</div>
|
||||
<div className="aff-classique-quai-dep__train-info">
|
||||
{trainType2 && <span className="aff-classique-quai-dep__train-type">{trainType2}</span>}
|
||||
{trainNumber2 && <span className="aff-classique-quai-dep__train-number">{trainNumber2}</span>}
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
|
||||
{/* Si même destination mais 2 numéros couplés (ex: 2 TGV départ 16h17 vers Paris) */}
|
||||
{!isDifferentDest && trainNumber2 && trainNumber2 !== trainNumber1 && (
|
||||
<div className="aff-classique-quai-dep__train-info" style={{ marginTop: '6px' }}>
|
||||
{trainType2 && <span className="aff-classique-quai-dep__train-type">{trainType2}</span>}
|
||||
<span className="aff-classique-quai-dep__train-number">{trainNumber2}</span>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Pictogrammes de services pour TGV (PMR, Vélo, Bar) */}
|
||||
{isTgv && <TgvServiceIcons />}
|
||||
|
||||
{/* Filigrane Vertical "départ" géant (orienté bas vers haut) */}
|
||||
<div className="aff-classique-quai-dep__watermark" aria-hidden="true">
|
||||
<span>départ</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* PANNEAU DROIT : BLEU NUIT AVEC DESSERTE (Conforme Image 1) */}
|
||||
<div className="aff-classique-quai-dep__right">
|
||||
{/* PANNEAU DROIT : BLEU NUIT AVEC DESSERTE (Conforme Image 1 & Fourche Image 2) */}
|
||||
<div className={`aff-classique-quai-dep__right ${isTgv ? 'aff-classique-quai-dep__right--tgv' : ''}`}>
|
||||
<div className="aff-classique-quai-dep__stops-wrapper">
|
||||
{stopsList.length > 0 ? (
|
||||
<ul className="aff-classique-quai-dep__stops-list">
|
||||
{stopsList.map((stopName, idx) => {
|
||||
const isLast = idx === stopsList.length - 1;
|
||||
return (
|
||||
<li
|
||||
key={idx}
|
||||
className={`aff-classique-quai-dep__stop-item ${isLast ? 'aff-classique-quai-dep__stop-item--dest' : ''}`}
|
||||
>
|
||||
{isDifferentDest && commonStops.length > 0 ? (
|
||||
/* AFFICHAGE FOURCHE / BIFURCATION (Conforme Image 2) */
|
||||
<div className="aff-classique-quai-dep__fork-container">
|
||||
{/* Tronc commun */}
|
||||
<ul className="aff-classique-quai-dep__stops-list">
|
||||
{commonStops.map((stopName, idx) => (
|
||||
<li key={idx} className="aff-classique-quai-dep__stop-item">
|
||||
<span className="aff-classique-quai-dep__bullet" />
|
||||
<span className="aff-classique-quai-dep__stop-name">
|
||||
{stopName}
|
||||
</span>
|
||||
<span className="aff-classique-quai-dep__stop-name">{stopName}</span>
|
||||
</li>
|
||||
);
|
||||
})}
|
||||
</ul>
|
||||
) : (
|
||||
<div style={{ color: '#ffffff', fontSize: '38px', fontWeight: 600, padding: '40px' }}>
|
||||
Veuillez consulter les écrans du hall de la gare.
|
||||
))}
|
||||
</ul>
|
||||
|
||||
{/* Ligne d'embranchement avec courbe */}
|
||||
<div className="aff-classique-quai-dep__fork-split-row">
|
||||
<div className="aff-classique-quai-dep__fork-curve-rail" />
|
||||
<div className="aff-classique-quai-dep__fork-branch-right">
|
||||
<div className="aff-classique-quai-dep__fork-coaches-label">voitures 11 à 18</div>
|
||||
<div className="aff-classique-quai-dep__fork-terminus-box">
|
||||
<span className="aff-classique-quai-dep__bullet" style={{ position: 'static', margin: 0 }} />
|
||||
<span className="aff-classique-quai-dep__fork-terminus-name">
|
||||
{branch2Stops[branch2Stops.length - 1] || destinationName2}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Branche principale continuant vers terminus 1 */}
|
||||
{branch1Stops.length > 0 && (
|
||||
<ul className="aff-classique-quai-dep__stops-list" style={{ marginTop: '8px' }}>
|
||||
{branch1Stops.map((stopName, idx) => {
|
||||
const isLast = idx === branch1Stops.length - 1;
|
||||
return (
|
||||
<li
|
||||
key={idx}
|
||||
className={`aff-classique-quai-dep__stop-item ${isLast ? 'aff-classique-quai-dep__stop-item--dest' : ''}`}
|
||||
>
|
||||
<span className="aff-classique-quai-dep__bullet" />
|
||||
<span className="aff-classique-quai-dep__stop-name">{stopName}</span>
|
||||
</li>
|
||||
);
|
||||
})}
|
||||
</ul>
|
||||
)}
|
||||
</div>
|
||||
) : (
|
||||
/* AFFICHAGE STANDARD DESSERTE VERTICALE (Conforme Image 1) */
|
||||
stopsList.length > 0 ? (
|
||||
<ul className="aff-classique-quai-dep__stops-list">
|
||||
{stopsList.map((stopName, idx) => {
|
||||
const isLast = idx === stopsList.length - 1;
|
||||
return (
|
||||
<li
|
||||
key={idx}
|
||||
className={`aff-classique-quai-dep__stop-item ${isLast ? 'aff-classique-quai-dep__stop-item--dest' : ''}`}
|
||||
>
|
||||
<span className="aff-classique-quai-dep__bullet" />
|
||||
<span className="aff-classique-quai-dep__stop-name">
|
||||
{stopName}
|
||||
</span>
|
||||
</li>
|
||||
);
|
||||
})}
|
||||
</ul>
|
||||
) : (
|
||||
<div style={{ color: '#ffffff', fontSize: '38px', fontWeight: 600, padding: '40px' }}>
|
||||
Veuillez consulter les écrans du hall de la gare.
|
||||
</div>
|
||||
)
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* BANDEAU BAS : PLEINE LARGEUR & HORLOGE (Conforme Image 1) */}
|
||||
<div className="aff-classique-quai-dep__footer">
|
||||
<div className="aff-classique-quai-dep__footer-track">
|
||||
{quaiParam ? `Voie ${cleanPlatform(quaiParam).toUpperCase()}` : (horaire?.quai ? `Voie ${cleanPlatform(horaire.quai).toUpperCase()}` : '')}
|
||||
{/* BANDEAU BAS : TGV COMPOSITION OU BANDEAU STANDARD */}
|
||||
{isTgv ? (
|
||||
<TgvCompositionQuai
|
||||
platform={quaiParam || horaire?.quai || horaire?.quai_reel || horaire?.voie || horaire?._displayPlatform}
|
||||
destination={destinationName1}
|
||||
destination2={isDifferentDest ? destinationName2 : destinationName1}
|
||||
composition={horaire?.composition}
|
||||
marqueeMessage={horaire?._status?.causeDetails || horaire?.cause_retard || (isSuppressed ? `TRAIN SUPPRIMÉ - MERCI DE VOTRE COMPRÉHENSION` : (isDelayed ? `TRAIN RETARDÉ DE ${delayMinutes} MIN - MERCI DE VOTRE COMPRÉHENSION` : ''))}
|
||||
/>
|
||||
) : (
|
||||
<div className="aff-classique-quai-dep__footer">
|
||||
<div className="aff-classique-quai-dep__footer-track">
|
||||
{quaiParam ? `Voie ${cleanPlatform(quaiParam).toUpperCase()}` : (horaire?.quai || horaire?.voie || horaire?._displayPlatform ? `Voie ${cleanPlatform(horaire.quai || horaire.voie || horaire._displayPlatform).toUpperCase()}` : '')}
|
||||
</div>
|
||||
<div className="aff-classique-quai-dep__footer-clock">
|
||||
<DigitalClock />
|
||||
</div>
|
||||
</div>
|
||||
<div className="aff-classique-quai-dep__footer-clock">
|
||||
<DigitalClock />
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in new issue
Block a user