/* global React */ // ---------- Icons (inline SVG) ---------- const Icon = ({ name, size = 24, stroke = 2 }) => { const paths = { building: <>, home: <>, sparkles: <>, broom: <>, shield: <>, window: <>, phone: <>, mail: <>, location: <>, clock: <>, check: <>, arrow: <>, star: <>, users: <>, award: <>, leaf: <>, heart: <>, zap: <>, chat: <>, menu: <>, close: <>, target: <>, spray: <>, facebook: <>, instagram: <>, google: <>, 'chevron-up': , }; return ( ); }; // ---------- SME Logo (real brand mark) ---------- const SMELogo = ({ size = 'md', light = false }) => { const iconW = size === 'xl' ? 100 : size === 'lg' ? 84 : size === 'sm' ? 52 : 72; const nameSize = size === 'xl' ? '1.35rem' : size === 'lg' ? '1.15rem' : size === 'sm' ? '0.85rem' : '1.05rem'; const tagSize = size === 'xl' ? '0.68rem' : size === 'lg' ? '0.62rem' : size === 'sm' ? '0.52rem' : '0.58rem'; const nameColor = light ? '#ffffff' : 'var(--sme-grey-900)'; const tagColor = light ? 'rgba(255,255,255,0.65)' : 'var(--sme-grey-400)'; const logoSrc = (typeof window !== 'undefined' && window.smeThemeUrl) ? window.smeThemeUrl + '/images/logo-sme.png?v=12' : '/wp-content/themes/sme-nettoyage-react/images/logo-sme.png?v=12'; return (
SME Nettoyage
NETTOYAGE La propreté, notre engagement
); }; // ---------- Scroll-triggered fade-in (rect-based for reliability) ---------- const Reveal = ({ children, delay = 0, y = 24, as: As = 'div', style = {}, ...rest }) => { const ref = React.useRef(null); const [visible, setVisible] = React.useState(false); React.useEffect(() => { const el = ref.current; if (!el) return; const check = () => { const rect = el.getBoundingClientRect(); return rect.top < window.innerHeight - 40 && rect.bottom > 0; }; if (check()) { setVisible(true); return; } const onScroll = () => { if (check()) { setVisible(true); cleanup(); } }; // Safety fallback: reveal anyway after 1.2s so content can never stay hidden. const fallback = setTimeout(() => { setVisible(true); cleanup(); }, 1200); const cleanup = () => { window.removeEventListener('scroll', onScroll); clearTimeout(fallback); }; window.addEventListener('scroll', onScroll, { passive: true }); return cleanup; }, []); return ( {children} ); }; // ---------- Animated counter (rect-based) ---------- const Counter = ({ end, suffix = '', prefix = '', duration = 1600 }) => { const ref = React.useRef(null); const [val, setVal] = React.useState(0); const startedRef = React.useRef(false); React.useEffect(() => { const el = ref.current; if (!el) return; let raf; const startAnim = () => { if (startedRef.current) return; startedRef.current = true; const start = performance.now(); const tick = (now) => { const t = Math.min(1, (now - start) / duration); const eased = 1 - Math.pow(1 - t, 3); setVal(Math.round(end * eased)); if (t < 1) raf = requestAnimationFrame(tick); }; raf = requestAnimationFrame(tick); }; const check = () => { const rect = el.getBoundingClientRect(); return rect.top < window.innerHeight - 40 && rect.bottom > 0; }; if (check()) { startAnim(); return () => cancelAnimationFrame(raf); } const onScroll = () => { if (check()) { startAnim(); cleanup(); } }; const fallback = setTimeout(startAnim, 1500); const cleanup = () => { window.removeEventListener('scroll', onScroll); clearTimeout(fallback); }; window.addEventListener('scroll', onScroll, { passive: true }); return () => { cleanup(); cancelAnimationFrame(raf); }; }, [end, duration]); return {prefix}{val.toLocaleString('fr-FR')}{suffix}; }; // ---------- Header (utility topbar + main bar with mega-menu) ---------- const SUB_SERVICES = [ { id: 'entreprises', label: "Nettoyage d'Entreprises", icon: 'building', desc: 'Bureaux, sièges, espaces de travail.' }, { id: 'batiments', label: 'Nettoyage de Bâtiments', icon: 'home', desc: 'Copropriétés, parties communes, halls.' }, { id: 'vitres', label: 'Nettoyage de Vitres', icon: 'window', desc: 'Vitrines, façades, baies vitrées.' }, { id: 'industriel', label: 'Nettoyage Industriel', icon: 'shield', desc: 'Sites de production, entrepôts, ateliers.' }, { id: 'jardins', label: 'Jardins & Parcs', icon: 'leaf', desc: 'Entretien d\'espaces verts et extérieurs.' }, ]; const Header = ({ currentPage, navigate }) => { const [scrolled, setScrolled] = React.useState(false); const [mobileOpen, setMobileOpen] = React.useState(false); const [megaOpen, setMegaOpen] = React.useState(false); const [mobileServicesOpen, setMobileServicesOpen] = React.useState(false); const closeTimer = React.useRef(null); React.useEffect(() => { const onScroll = () => setScrolled(window.scrollY > 12); window.addEventListener('scroll', onScroll); return () => window.removeEventListener('scroll', onScroll); }, []); // Close mega-menu on Escape React.useEffect(() => { const onKey = (e) => { if (e.key === 'Escape') setMegaOpen(false); }; window.addEventListener('keydown', onKey); return () => window.removeEventListener('keydown', onKey); }, []); const pages = [ { id: 'home', label: 'Accueil' }, { id: 'about', label: 'À propos' }, { id: 'services', label: 'Services', hasMega: true }, { id: 'faq', label: 'FAQ' }, { id: 'contact', label: 'Contact' }, ]; const openMega = () => { if (closeTimer.current) { clearTimeout(closeTimer.current); closeTimer.current = null; } setMegaOpen(true); }; const scheduleClose = () => { if (closeTimer.current) clearTimeout(closeTimer.current); closeTimer.current = setTimeout(() => setMegaOpen(false), 180); }; const goService = (subId) => { setMegaOpen(false); setMobileOpen(false); setMobileServicesOpen(false); navigate('service-' + subId); }; const navItem = (p) => { const active = currentPage === p.id; if (p.hasMega) { return (
); } return ( ); }; return ( <> {/* TOP UTILITY BAR */}
+590 590 81-9174 ste.sme@orange.fr Lun – Ven · 8h–14h30
Disponible — Devis 24h
{/* MAIN HEADER */}
{/* MEGA-MENU PANEL — full-width drop under the header */}
{/* Sub-services grid */}
Nos prestations
{SUB_SERVICES.map((s, i) => ( ))}
{/* Featured CTA card */}
{/* MOBILE PANEL */} {mobileOpen && (
{/* CTA header */}
{/* Nav links */}
{pages.map(p => { const active = currentPage === p.id; if (p.hasMega) { return (
{SUB_SERVICES.map(s => ( ))}
); } return ( ); })}
{/* Contact info block */}
+590 590 81-9174 ste.sme@orange.fr Lun–Ven · 8h–14h30
)}
); }; // ---------- Footer ---------- const Footer = ({ navigate }) => { return (

Navigation

    {['home', 'about', 'services', 'faq', 'contact'].map((p, i) => (
  • ))}

Services

    {[ { id: 'service-entreprises', label: "Nettoyage d'Entreprises" }, { id: 'service-batiments', label: 'Nettoyage de Bâtiments' }, { id: 'service-vitres', label: 'Nettoyage de Vitres' }, { id: 'service-industriel', label: 'Nettoyage Industriel' }, { id: 'service-jardins', label: 'Jardins & Parcs' }, ].map(s => (
  • ))}
© 2026 SME Nettoyage — Tous droits réservés. Site réalisé par{' '} Digital Média Mobile
); }; // ---------- Reusable: section header ---------- const SectionHeader = ({ eyebrow, title, intro, center = false, eyebrowGreen = false }) => (
{eyebrow}

{title}

{intro &&

{intro}

}
); // ---------- Back to top button ---------- const BackToTop = () => { const [visible, setVisible] = React.useState(false); React.useEffect(() => { const onScroll = () => setVisible(window.scrollY > 400); window.addEventListener('scroll', onScroll, { passive: true }); return () => window.removeEventListener('scroll', onScroll); }, []); if (!visible) return null; return ( <> ); }; // ---------- Cookie consent banner ---------- const CookieConsent = ({ navigate }) => { const STORAGE_KEY = 'sme_cookie_consent'; const [visible, setVisible] = React.useState(false); React.useEffect(() => { if (!localStorage.getItem(STORAGE_KEY)) setVisible(true); }, []); const accept = () => { localStorage.setItem(STORAGE_KEY, 'accepted'); setVisible(false); }; const refuse = () => { localStorage.setItem(STORAGE_KEY, 'refused'); setVisible(false); }; if (!visible) return null; return ( <>

🍪 Ce site utilise des cookies

Nous utilisons des cookies techniques essentiels au bon fonctionnement du site. Aucun cookie publicitaire n'est déposé sans votre accord.{' '} {navigate && ( )}

); }; // Export to window for cross-file babel script access Object.assign(window, { Icon, SMELogo, Header, Footer, SectionHeader, Reveal, Counter, BackToTop, CookieConsent });