diff --git a/src/hooks/useAnnonceSonoreRealtime.js b/src/hooks/useAnnonceSonoreRealtime.js index b49673d..db612a8 100644 --- a/src/hooks/useAnnonceSonoreRealtime.js +++ b/src/hooks/useAnnonceSonoreRealtime.js @@ -109,18 +109,16 @@ export default function useAnnonceSonoreRealtime(gareId, affType = null, quaiNam // Si c'est une annonce qu'on n'a pas encore vue if (latest.id !== lastAnnonceIdRef.current) { - const now = new Date(); - const createdAt = new Date(latest.created_at); - const diffSeconds = (now.getTime() - createdAt.getTime()) / 1000; - - // On ne joue l'annonce que si elle a été insérée il y a moins de 15 secondes - if (diffSeconds < 15) { + // S'il s'agit du premier chargement, on mémorise juste l'ID sans la jouer + // sauf si on veut vraiment utiliser diffSeconds, mais pour éviter les problèmes d'horloge + // on se fie au fait que lastAnnonceIdRef.current passe de null à l'ID. + if (lastAnnonceIdRef.current === null) { + lastAnnonceIdRef.current = latest.id; + } else { + // C'est une NOUVELLE annonce apparue pendant qu'on polle console.debug('[useAnnonceSonoreRealtime] Annonce spontanée détectée :', latest); lastAnnonceIdRef.current = latest.id; playAnnonce(latest); - } else { - // Si elle est trop vieille, on l'ignore silencieusement - lastAnnonceIdRef.current = latest.id; } } } diff --git a/src/pages/afficheurs/afl/AFLArrivees.js b/src/pages/afficheurs/afl/AFLArrivees.js index ff3135a..e1a8a19 100644 --- a/src/pages/afficheurs/afl/AFLArrivees.js +++ b/src/pages/afficheurs/afl/AFLArrivees.js @@ -738,80 +738,31 @@ export default function AFLArrivees(){ tomorrow.setDate(today.getDate()+1); const tomorrowStr = localDateStr(tomorrow); - const weekdayIndex = (d) => d.getDay(); // 0 dimanche .. 6 samedi - const weekdayNameForColumn = (d) => { - const i = weekdayIndex(d); - switch(i) { - case 1: return 'circule_lundi'; - case 2: return 'circule_mardi'; - case 3: return 'circule_mercredi'; - case 4: return 'circule_jeudi'; - case 5: return 'circule_vendredi'; - case 6: return 'circule_samedi'; - case 0: return 'circule_dimanche'; - default: return null; - } - }; - - const isPublicHoliday = (d) => { - const y = d.getFullYear(); - const m = d.getMonth() + 1; - const day = d.getDate(); - const s = `${y}-${String(m).padStart(2, '0')}-${String(day).padStart(2, '0')}`; - const holidays = [ - `${y}-01-01`, // Jour de l'an - `${y}-05-01`, // Fête du Travail - `${y}-05-08`, // Victoire 1945 - `${y}-07-14`, // Fête nationale - `${y}-08-15`, // Assomption - `${y}-11-01`, // Toussaint - `${y}-11-11`, // Armistice 1918 - `${y}-12-25`, // Noël - ]; - // Dates variables pour 2026 - if (y === 2026) { - holidays.push('2026-04-06'); // Lundi de Pâques - holidays.push('2026-05-14'); // Ascension - holidays.push('2026-05-25'); // Lundi de Pentecôte - } - return holidays.includes(s); - }; - - const parseCirculationFlag = (value, defaultValue) => { - if (value === null || typeof value === 'undefined') { - return defaultValue; - } - if (typeof value === 'boolean') { - return value; - } - if (typeof value === 'number') { - return value === 1; - } - if (typeof value === 'string') { - const s = value.trim().toLowerCase(); - if (['true', '1', 't', 'y', 'yes', 'oui'].includes(s)) { - return true; - } - if (['false', '0', 'f', 'n', 'no', 'non'].includes(s)) { - return false; - } - } - return defaultValue; - }; - const circulatesOn = (h, d) => { - if (isPublicHoliday(d)) { - // On public holidays, circulation is determined SOLELY by `circule_jours_feries`. - // If the flag is true, it runs. Otherwise, it doesn't. - return parseCirculationFlag(h['circule_jours_feries'], false); + const pad = (n) => String(n).padStart(2, '0'); + const targetDateStr = `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}`; + + const customDaysRaw = h.jours_personnalises; + if (!customDaysRaw) return false; + + let customDays = []; + if (Array.isArray(customDaysRaw)) { + customDays = customDaysRaw; + } else if (typeof customDaysRaw === 'string') { + try { + customDays = JSON.parse(customDaysRaw); + } catch (e) { + return false; + } } - - // On a regular day, check the corresponding weekday column. - const col = weekdayNameForColumn(d); - if (!col) return true; // Should not happen, but permissive. - - // For regular weekdays, the default is to run unless specified otherwise. - return parseCirculationFlag(h[col], true); + + if (Array.isArray(customDays)) { + const match = customDays.find(item => item.date === targetDateStr); + if (match) { + return Boolean(match.circule); + } + } + return false; }; // Construire listes pour aujourd'hui et demain en tenant compte des colonnes circule_* diff --git a/src/pages/afficheurs/afl/AFLArriveesQuais.js b/src/pages/afficheurs/afl/AFLArriveesQuais.js index c3f4166..7efe4af 100644 --- a/src/pages/afficheurs/afl/AFLArriveesQuais.js +++ b/src/pages/afficheurs/afl/AFLArriveesQuais.js @@ -487,53 +487,31 @@ const AFLArriveesQuais = () => { tomorrow.setDate(today.getDate() + 1); const tomorrowStr = localDateStr(tomorrow); - const weekdayIndex = (d) => d.getDay(); - const weekdayNameForColumn = (d) => { - const i = weekdayIndex(d); - switch (i) { - case 1: return 'circule_lundi'; - case 2: return 'circule_mardi'; - case 3: return 'circule_mercredi'; - case 4: return 'circule_jeudi'; - case 5: return 'circule_vendredi'; - case 6: return 'circule_samedi'; - case 0: return 'circule_dimanche'; - default: return null; - } - }; - - const isPublicHoliday = (d) => { - const y = d.getFullYear(); - const m = d.getMonth() + 1; - const day = d.getDate(); - const s = `${y}-${String(m).padStart(2, '0')}-${String(day).padStart(2, '0')}`; - const holidays = [ - `${y}-01-01`, `${y}-05-01`, `${y}-05-08`, `${y}-07-14`, `${y}-08-15`, `${y}-11-01`, `${y}-11-11`, `${y}-12-25` - ]; - if (y === 2026) { - holidays.push('2026-04-06'); - holidays.push('2026-05-14'); - holidays.push('2026-05-25'); - } - return holidays.includes(s); - }; - - const parseCirculationFlag = (val, defaultVal) => { - if (val == null) return defaultVal; - if (typeof val === 'boolean') return val; - const s = String(val).trim().toLowerCase(); - if (['true', '1', 't', 'y', 'yes', 'oui'].includes(s)) return true; - if (['false', '0', 'f', 'n', 'no', 'non'].includes(s)) return false; - return defaultVal; - }; - const circulatesOn = (h, d) => { - if (isPublicHoliday(d)) { - return parseCirculationFlag(h['circule_jours_feries'], false); + const pad = (n) => String(n).padStart(2, '0'); + const targetDateStr = `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}`; + + const customDaysRaw = h.jours_personnalises; + if (!customDaysRaw) return false; + + let customDays = []; + if (Array.isArray(customDaysRaw)) { + customDays = customDaysRaw; + } else if (typeof customDaysRaw === 'string') { + try { + customDays = JSON.parse(customDaysRaw); + } catch (e) { + return false; + } } - const col = weekdayNameForColumn(d); - if (!col) return true; - return parseCirculationFlag(h[col], true); + + if (Array.isArray(customDays)) { + const match = customDays.find(item => item.date === targetDateStr); + if (match) { + return Boolean(match.circule); + } + } + return false; }; const parseDateOnly = (v) => { diff --git a/src/pages/afficheurs/afl/AFLDeparts.js b/src/pages/afficheurs/afl/AFLDeparts.js index c71b27b..a587eb0 100644 --- a/src/pages/afficheurs/afl/AFLDeparts.js +++ b/src/pages/afficheurs/afl/AFLDeparts.js @@ -753,80 +753,31 @@ export default function AFLDeparts(){ tomorrow.setDate(today.getDate()+1); const tomorrowStr = localDateStr(tomorrow); - const weekdayIndex = (d) => d.getDay(); // 0 dimanche .. 6 samedi - const weekdayNameForColumn = (d) => { - const i = weekdayIndex(d); - switch(i) { - case 1: return 'circule_lundi'; - case 2: return 'circule_mardi'; - case 3: return 'circule_mercredi'; - case 4: return 'circule_jeudi'; - case 5: return 'circule_vendredi'; - case 6: return 'circule_samedi'; - case 0: return 'circule_dimanche'; - default: return null; - } - }; - - const isPublicHoliday = (d) => { - const y = d.getFullYear(); - const m = d.getMonth() + 1; - const day = d.getDate(); - const s = `${y}-${String(m).padStart(2, '0')}-${String(day).padStart(2, '0')}`; - const holidays = [ - `${y}-01-01`, // Jour de l'an - `${y}-05-01`, // Fête du Travail - `${y}-05-08`, // Victoire 1945 - `${y}-07-14`, // Fête nationale - `${y}-08-15`, // Assomption - `${y}-11-01`, // Toussaint - `${y}-11-11`, // Armistice 1918 - `${y}-12-25`, // Noël - ]; - // Dates variables pour 2026 - if (y === 2026) { - holidays.push('2026-04-06'); // Lundi de Pâques - holidays.push('2026-05-14'); // Ascension - holidays.push('2026-05-25'); // Lundi de Pentecôte - } - return holidays.includes(s); - }; - - const parseCirculationFlag = (value, defaultValue) => { - if (value === null || typeof value === 'undefined') { - return defaultValue; - } - if (typeof value === 'boolean') { - return value; - } - if (typeof value === 'number') { - return value === 1; - } - if (typeof value === 'string') { - const s = value.trim().toLowerCase(); - if (['true', '1', 't', 'y', 'yes', 'oui'].includes(s)) { - return true; - } - if (['false', '0', 'f', 'n', 'no', 'non'].includes(s)) { - return false; - } - } - return defaultValue; - }; - const circulatesOn = (h, d) => { - if (isPublicHoliday(d)) { - // On public holidays, circulation is determined SOLELY by `circule_jours_feries`. - // If the flag is true, it runs. Otherwise, it doesn't. - return parseCirculationFlag(h['circule_jours_feries'], false); + const pad = (n) => String(n).padStart(2, '0'); + const targetDateStr = `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}`; + + const customDaysRaw = h.jours_personnalises; + if (!customDaysRaw) return false; + + let customDays = []; + if (Array.isArray(customDaysRaw)) { + customDays = customDaysRaw; + } else if (typeof customDaysRaw === 'string') { + try { + customDays = JSON.parse(customDaysRaw); + } catch (e) { + return false; + } } - - // On a regular day, check the corresponding weekday column. - const col = weekdayNameForColumn(d); - if (!col) return true; // Should not happen, but permissive. - - // For regular weekdays, the default is to run unless specified otherwise. - return parseCirculationFlag(h[col], true); + + if (Array.isArray(customDays)) { + const match = customDays.find(item => item.date === targetDateStr); + if (match) { + return Boolean(match.circule); + } + } + return false; }; // Construire listes pour aujourd'hui et demain en tenant compte des colonnes circule_* diff --git a/src/pages/afficheurs/afl/AFLDepartsQuais.js b/src/pages/afficheurs/afl/AFLDepartsQuais.js index a3f2ac1..9b69bc8 100644 --- a/src/pages/afficheurs/afl/AFLDepartsQuais.js +++ b/src/pages/afficheurs/afl/AFLDepartsQuais.js @@ -488,53 +488,31 @@ const AFLDepartsQuais = () => { tomorrow.setDate(today.getDate() + 1); const tomorrowStr = localDateStr(tomorrow); - const weekdayIndex = (d) => d.getDay(); - const weekdayNameForColumn = (d) => { - const i = weekdayIndex(d); - switch (i) { - case 1: return 'circule_lundi'; - case 2: return 'circule_mardi'; - case 3: return 'circule_mercredi'; - case 4: return 'circule_jeudi'; - case 5: return 'circule_vendredi'; - case 6: return 'circule_samedi'; - case 0: return 'circule_dimanche'; - default: return null; - } - }; - - const isPublicHoliday = (d) => { - const y = d.getFullYear(); - const m = d.getMonth() + 1; - const day = d.getDate(); - const s = `${y}-${String(m).padStart(2, '0')}-${String(day).padStart(2, '0')}`; - const holidays = [ - `${y}-01-01`, `${y}-05-01`, `${y}-05-08`, `${y}-07-14`, `${y}-08-15`, `${y}-11-01`, `${y}-11-11`, `${y}-12-25` - ]; - if (y === 2026) { - holidays.push('2026-04-06'); - holidays.push('2026-05-14'); - holidays.push('2026-05-25'); - } - return holidays.includes(s); - }; - - const parseCirculationFlag = (val, defaultVal) => { - if (val == null) return defaultVal; - if (typeof val === 'boolean') return val; - const s = String(val).trim().toLowerCase(); - if (['true', '1', 't', 'y', 'yes', 'oui'].includes(s)) return true; - if (['false', '0', 'f', 'n', 'no', 'non'].includes(s)) return false; - return defaultVal; - }; - const circulatesOn = (h, d) => { - if (isPublicHoliday(d)) { - return parseCirculationFlag(h['circule_jours_feries'], false); + const pad = (n) => String(n).padStart(2, '0'); + const targetDateStr = `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}`; + + const customDaysRaw = h.jours_personnalises; + if (!customDaysRaw) return false; + + let customDays = []; + if (Array.isArray(customDaysRaw)) { + customDays = customDaysRaw; + } else if (typeof customDaysRaw === 'string') { + try { + customDays = JSON.parse(customDaysRaw); + } catch (e) { + return false; + } } - const col = weekdayNameForColumn(d); - if (!col) return true; - return parseCirculationFlag(h[col], true); + + if (Array.isArray(customDays)) { + const match = customDays.find(item => item.date === targetDateStr); + if (match) { + return Boolean(match.circule); + } + } + return false; }; const parseDateOnly = (v) => { diff --git a/src/pages/afficheurs/classiques/ClassiquesArrivees.js b/src/pages/afficheurs/classiques/ClassiquesArrivees.js index 53ff8c2..3a110bf 100644 --- a/src/pages/afficheurs/classiques/ClassiquesArrivees.js +++ b/src/pages/afficheurs/classiques/ClassiquesArrivees.js @@ -793,80 +793,31 @@ export default function ClassiquesArrivees(){ tomorrow.setDate(today.getDate()+1); const tomorrowStr = localDateStr(tomorrow); - const weekdayIndex = (d) => d.getDay(); // 0 dimanche .. 6 samedi - const weekdayNameForColumn = (d) => { - const i = weekdayIndex(d); - switch(i) { - case 1: return 'circule_lundi'; - case 2: return 'circule_mardi'; - case 3: return 'circule_mercredi'; - case 4: return 'circule_jeudi'; - case 5: return 'circule_vendredi'; - case 6: return 'circule_samedi'; - case 0: return 'circule_dimanche'; - default: return null; - } - }; - - const isPublicHoliday = (d) => { - const y = d.getFullYear(); - const m = d.getMonth() + 1; - const day = d.getDate(); - const s = `${y}-${String(m).padStart(2, '0')}-${String(day).padStart(2, '0')}`; - const holidays = [ - `${y}-01-01`, // Jour de l'an - `${y}-05-01`, // Fête du Travail - `${y}-05-08`, // Victoire 1945 - `${y}-07-14`, // Fête nationale - `${y}-08-15`, // Assomption - `${y}-11-01`, // Toussaint - `${y}-11-11`, // Armistice 1918 - `${y}-12-25`, // Noël - ]; - // Dates variables pour 2026 - if (y === 2026) { - holidays.push('2026-04-06'); // Lundi de Pâques - holidays.push('2026-05-14'); // Ascension - holidays.push('2026-05-25'); // Lundi de Pentecôte - } - return holidays.includes(s); - }; - - const parseCirculationFlag = (value, defaultValue) => { - if (value === null || typeof value === 'undefined') { - return defaultValue; - } - if (typeof value === 'boolean') { - return value; - } - if (typeof value === 'number') { - return value === 1; - } - if (typeof value === 'string') { - const s = value.trim().toLowerCase(); - if (['true', '1', 't', 'y', 'yes', 'oui'].includes(s)) { - return true; - } - if (['false', '0', 'f', 'n', 'no', 'non'].includes(s)) { - return false; - } - } - return defaultValue; - }; - const circulatesOn = (h, d) => { - if (isPublicHoliday(d)) { - // On public holidays, circulation is determined SOLELY by `circule_jours_feries`. - // If the flag is true, it runs. Otherwise, it doesn't. - return parseCirculationFlag(h['circule_jours_feries'], false); + const pad = (n) => String(n).padStart(2, '0'); + const targetDateStr = `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}`; + + const customDaysRaw = h.jours_personnalises; + if (!customDaysRaw) return false; + + let customDays = []; + if (Array.isArray(customDaysRaw)) { + customDays = customDaysRaw; + } else if (typeof customDaysRaw === 'string') { + try { + customDays = JSON.parse(customDaysRaw); + } catch (e) { + return false; + } } - - // On a regular day, check the corresponding weekday column. - const col = weekdayNameForColumn(d); - if (!col) return true; // Should not happen, but permissive. - - // For regular weekdays, the default is to run unless specified otherwise. - return parseCirculationFlag(h[col], true); + + if (Array.isArray(customDays)) { + const match = customDays.find(item => item.date === targetDateStr); + if (match) { + return Boolean(match.circule); + } + } + return false; }; // Construire listes pour aujourd'hui et demain en tenant compte des colonnes circule_* diff --git a/src/pages/afficheurs/classiques/ClassiquesDeparts.js b/src/pages/afficheurs/classiques/ClassiquesDeparts.js index 41f8cf5..a5c1554 100644 --- a/src/pages/afficheurs/classiques/ClassiquesDeparts.js +++ b/src/pages/afficheurs/classiques/ClassiquesDeparts.js @@ -793,80 +793,31 @@ export default function ClassiquesDeparts(){ tomorrow.setDate(today.getDate()+1); const tomorrowStr = localDateStr(tomorrow); - const weekdayIndex = (d) => d.getDay(); // 0 dimanche .. 6 samedi - const weekdayNameForColumn = (d) => { - const i = weekdayIndex(d); - switch(i) { - case 1: return 'circule_lundi'; - case 2: return 'circule_mardi'; - case 3: return 'circule_mercredi'; - case 4: return 'circule_jeudi'; - case 5: return 'circule_vendredi'; - case 6: return 'circule_samedi'; - case 0: return 'circule_dimanche'; - default: return null; - } - }; - - const isPublicHoliday = (d) => { - const y = d.getFullYear(); - const m = d.getMonth() + 1; - const day = d.getDate(); - const s = `${y}-${String(m).padStart(2, '0')}-${String(day).padStart(2, '0')}`; - const holidays = [ - `${y}-01-01`, // Jour de l'an - `${y}-05-01`, // Fête du Travail - `${y}-05-08`, // Victoire 1945 - `${y}-07-14`, // Fête nationale - `${y}-08-15`, // Assomption - `${y}-11-01`, // Toussaint - `${y}-11-11`, // Armistice 1918 - `${y}-12-25`, // Noël - ]; - // Dates variables pour 2026 - if (y === 2026) { - holidays.push('2026-04-06'); // Lundi de Pâques - holidays.push('2026-05-14'); // Ascension - holidays.push('2026-05-25'); // Lundi de Pentecôte - } - return holidays.includes(s); - }; - - const parseCirculationFlag = (value, defaultValue) => { - if (value === null || typeof value === 'undefined') { - return defaultValue; - } - if (typeof value === 'boolean') { - return value; - } - if (typeof value === 'number') { - return value === 1; - } - if (typeof value === 'string') { - const s = value.trim().toLowerCase(); - if (['true', '1', 't', 'y', 'yes', 'oui'].includes(s)) { - return true; - } - if (['false', '0', 'f', 'n', 'no', 'non'].includes(s)) { - return false; - } - } - return defaultValue; - }; - const circulatesOn = (h, d) => { - if (isPublicHoliday(d)) { - // On public holidays, circulation is determined SOLELY by `circule_jours_feries`. - // If the flag is true, it runs. Otherwise, it doesn't. - return parseCirculationFlag(h['circule_jours_feries'], false); + const pad = (n) => String(n).padStart(2, '0'); + const targetDateStr = `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}`; + + const customDaysRaw = h.jours_personnalises; + if (!customDaysRaw) return false; + + let customDays = []; + if (Array.isArray(customDaysRaw)) { + customDays = customDaysRaw; + } else if (typeof customDaysRaw === 'string') { + try { + customDays = JSON.parse(customDaysRaw); + } catch (e) { + return false; + } } - - // On a regular day, check the corresponding weekday column. - const col = weekdayNameForColumn(d); - if (!col) return true; // Should not happen, but permissive. - - // For regular weekdays, the default is to run unless specified otherwise. - return parseCirculationFlag(h[col], true); + + if (Array.isArray(customDays)) { + const match = customDays.find(item => item.date === targetDateStr); + if (match) { + return Boolean(match.circule); + } + } + return false; }; // Construire listes pour aujourd'hui et demain en tenant compte des colonnes circule_* diff --git a/src/pages/afficheurs/classiques/quais/ClassiquesArriveesQuais.js b/src/pages/afficheurs/classiques/quais/ClassiquesArriveesQuais.js index f6f9474..110cb82 100644 --- a/src/pages/afficheurs/classiques/quais/ClassiquesArriveesQuais.js +++ b/src/pages/afficheurs/classiques/quais/ClassiquesArriveesQuais.js @@ -76,65 +76,32 @@ export default function ClassiquesArriveesQuais() { const [perturbations, setPerturbations] = useState([]); const [, setTravaux] = useState([]); - const weekdayNameForColumn = useCallback((d) => { - const i = d.getDay(); - switch(i) { - case 1: return 'circule_lundi'; - case 2: return 'circule_mardi'; - case 3: return 'circule_mercredi'; - case 4: return 'circule_jeudi'; - case 5: return 'circule_vendredi'; - case 6: return 'circule_samedi'; - case 0: return 'circule_dimanche'; - default: return null; - } - }, []); - - const isPublicHoliday = useCallback((d) => { - const y = d.getFullYear(); - const m = d.getMonth() + 1; - const day = d.getDate(); - const s = `${y}-${String(m).padStart(2, '0')}-${String(day).padStart(2, '0')}`; - const holidays = [ - `${y}-01-01`, - `${y}-05-01`, - `${y}-05-08`, - `${y}-07-14`, - `${y}-08-15`, - `${y}-11-01`, - `${y}-11-11`, - `${y}-12-25`, - ]; - if (y === 2026) { - holidays.push('2026-04-06'); - holidays.push('2026-05-14'); - holidays.push('2026-05-25'); - } - return holidays.includes(s); - }, []); - const circulatesOn = useCallback((h, d) => { - if (isPublicHoliday(d)) { - const v = h['circule_jours_feries']; - if (typeof v === 'boolean') return v; - if (typeof v === 'number') return v === 1; - if (typeof v === 'string') { - const s = v.trim().toLowerCase(); - return s === 'true' || s === '1' || s === 't' || s === 'y' || s === 'yes'; + const pad = (n) => String(n).padStart(2, '0'); + const targetDateStr = `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}`; + + const customDaysRaw = h.jours_personnalises; + if (!customDaysRaw) return false; + + let customDays = []; + if (Array.isArray(customDaysRaw)) { + customDays = customDaysRaw; + } else if (typeof customDaysRaw === 'string') { + try { + customDays = JSON.parse(customDaysRaw); + } catch (e) { + return false; } - return (typeof v === 'undefined' || v === null) ? false : Boolean(v); } - const col = weekdayNameForColumn(d); - if (!col) return true; - const v = h[col]; - if (typeof v === 'boolean') return v; - if (typeof v === 'number') return v === 1; - if (typeof v === 'string') { - const s = v.trim().toLowerCase(); - return s === 'true' || s === '1' || s === 't' || s === 'y' || s === 'yes'; + + if (Array.isArray(customDays)) { + const match = customDays.find(item => item.date === targetDateStr); + if (match) { + return Boolean(match.circule); + } } - return (typeof v === 'undefined' || v === null) ? true : Boolean(v); - }, [isPublicHoliday, weekdayNameForColumn]); + return false; + }, []); const normalizeName = useCallback((s) => { if (!s) return ''; diff --git a/src/pages/afficheurs/classiques/quais/ClassiquesDepartsQuais.js b/src/pages/afficheurs/classiques/quais/ClassiquesDepartsQuais.js index 54c0348..4230373 100644 --- a/src/pages/afficheurs/classiques/quais/ClassiquesDepartsQuais.js +++ b/src/pages/afficheurs/classiques/quais/ClassiquesDepartsQuais.js @@ -76,65 +76,32 @@ export default function ClassiquesDepartsQuais() { const [perturbations, setPerturbations] = useState([]); const [, setTravaux] = useState([]); - const weekdayNameForColumn = useCallback((d) => { - const i = d.getDay(); - switch(i) { - case 1: return 'circule_lundi'; - case 2: return 'circule_mardi'; - case 3: return 'circule_mercredi'; - case 4: return 'circule_jeudi'; - case 5: return 'circule_vendredi'; - case 6: return 'circule_samedi'; - case 0: return 'circule_dimanche'; - default: return null; - } - }, []); - - const isPublicHoliday = useCallback((d) => { - const y = d.getFullYear(); - const m = d.getMonth() + 1; - const day = d.getDate(); - const s = `${y}-${String(m).padStart(2, '0')}-${String(day).padStart(2, '0')}`; - const holidays = [ - `${y}-01-01`, - `${y}-05-01`, - `${y}-05-08`, - `${y}-07-14`, - `${y}-08-15`, - `${y}-11-01`, - `${y}-11-11`, - `${y}-12-25`, - ]; - if (y === 2026) { - holidays.push('2026-04-06'); - holidays.push('2026-05-14'); - holidays.push('2026-05-25'); - } - return holidays.includes(s); - }, []); - const circulatesOn = useCallback((h, d) => { - if (isPublicHoliday(d)) { - const v = h['circule_jours_feries']; - if (typeof v === 'boolean') return v; - if (typeof v === 'number') return v === 1; - if (typeof v === 'string') { - const s = v.trim().toLowerCase(); - return s === 'true' || s === '1' || s === 't' || s === 'y' || s === 'yes'; + const pad = (n) => String(n).padStart(2, '0'); + const targetDateStr = `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}`; + + const customDaysRaw = h.jours_personnalises; + if (!customDaysRaw) return false; + + let customDays = []; + if (Array.isArray(customDaysRaw)) { + customDays = customDaysRaw; + } else if (typeof customDaysRaw === 'string') { + try { + customDays = JSON.parse(customDaysRaw); + } catch (e) { + return false; } - return (typeof v === 'undefined' || v === null) ? false : Boolean(v); } - const col = weekdayNameForColumn(d); - if (!col) return true; - const v = h[col]; - if (typeof v === 'boolean') return v; - if (typeof v === 'number') return v === 1; - if (typeof v === 'string') { - const s = v.trim().toLowerCase(); - return s === 'true' || s === '1' || s === 't' || s === 'y' || s === 'yes'; + + if (Array.isArray(customDays)) { + const match = customDays.find(item => item.date === targetDateStr); + if (match) { + return Boolean(match.circule); + } } - return (typeof v === 'undefined' || v === null) ? true : Boolean(v); - }, [isPublicHoliday, weekdayNameForColumn]); + return false; + }, []); const normalizeName = useCallback((s) => { if (!s) return '';