V2.0.0 : VOICI LES MODIFICATIONS MAJEURS APPRTÉES DANS CETTE VERSION :
-> REFONTE DU DESIGN DES AFFICHEURS CLASSIQUES (GÉNÉRAL + QUAIS) -> IMPLÉMENTATION DU DESIGN AFL : GÉNÉRAL ET QUAIS -> CHOIX DE LA SÉLECTION DES TYPES D'AFFICHEURS (GÉNÉRAL / QUAIS) UNE FOIS LE TYPE D'AFFICHEUR SÉLECTIONNÉS EN COURS DE DÉVELOPPEMENT : -> IMPLÉMENTATION DES PERTURBATION DU LANDEMAIN POUR LES HORAIRES DU LANDEMAIN AFFICHÉS AVANT MINUIT. -> IMPLÉMENTATION DES AFFICHEURS D'INFORMATIONS / INFOS TRAVAUX, etc... (AFFICHEURS AFL)
This commit is contained in:
1 parent
f0d9ed9ee7
commit
f06ebbaf48
43 files changed
+10519
-3813
No files matched your search
@@ -0,0 +1,44 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import useTypeLogos from '../hooks/useTypeLogos';
|
||||
|
||||
function getTypeLogo(type, map) {
|
||||
if (!type) return map.default;
|
||||
const norm = String(type).toUpperCase().replace(/[^A-Z0-9]+/g, '-').replace(/-$/, '');
|
||||
if (map[norm]) return map[norm];
|
||||
|
||||
// Also try to match the first word
|
||||
const firstWord = norm.split('-')[0];
|
||||
if (firstWord && map[firstWord]) return map[firstWord];
|
||||
|
||||
const keys = Object.keys(map).filter(k => k !== 'default');
|
||||
for (const k of keys) {
|
||||
if (k === norm || k.includes(norm) || norm.includes(k)) return map[k];
|
||||
}
|
||||
return map.default;
|
||||
}
|
||||
|
||||
export default function Logo({ op, classNameBox = '', classNameImg = '', classNameText = '' }) {
|
||||
const typeLogos = useTypeLogos();
|
||||
const [hasImg, setHasImg] = useState(true);
|
||||
|
||||
const src = getTypeLogo(op, typeLogos);
|
||||
|
||||
useEffect(() => {
|
||||
setHasImg(true); // Reset when op or typeLogos changes
|
||||
}, [src]);
|
||||
|
||||
return (
|
||||
<div className={classNameBox} aria-hidden>
|
||||
{hasImg && src ? (
|
||||
<img
|
||||
src={src}
|
||||
alt={op}
|
||||
className={classNameImg}
|
||||
onError={() => setHasImg(false)}
|
||||
/>
|
||||
) : (
|
||||
<div className={classNameText} aria-hidden>{(op || '').split(' ')[0]}</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
@keyframes marquee-scroll {
|
||||
0% { transform: translateX(0); }
|
||||
100% { transform: translateX(-100%); }
|
||||
}
|
||||
|
||||
.marquee-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
import React, { useRef, useState, useEffect } from 'react';
|
||||
import './MarqueeText.css';
|
||||
|
||||
const MarqueeText = ({ text, className }) => {
|
||||
const containerRef = useRef(null);
|
||||
const textRef = useRef(null);
|
||||
const [isOverflowing, setIsOverflowing] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
const checkOverflow = () => {
|
||||
if (containerRef.current && textRef.current) {
|
||||
setIsOverflowing(textRef.current.scrollWidth > containerRef.current.clientWidth);
|
||||
}
|
||||
};
|
||||
checkOverflow();
|
||||
window.addEventListener('resize', checkOverflow);
|
||||
return () => window.removeEventListener('resize', checkOverflow);
|
||||
}, [text]);
|
||||
|
||||
return (
|
||||
<div className={`marquee-container ${className || ''}`} ref={containerRef} style={{ overflow: 'hidden', whiteSpace: 'nowrap', width: '100%', flex: '1 1 0' }}>
|
||||
<div
|
||||
ref={textRef}
|
||||
style={{
|
||||
display: 'inline-block',
|
||||
animation: isOverflowing ? 'marquee-scroll 10s linear infinite' : 'none',
|
||||
paddingLeft: isOverflowing ? '100%' : '0'
|
||||
}}
|
||||
>
|
||||
{text}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default MarqueeText;
|
||||
Reference in new issue
Block a user