/* eslint-disable react/prop-types */ /** * NotificationBar · Barra de anuncio global * * Se renderiza arriba del Header (dentro del mismo contenedor sticky). * Lee su configuración de `window.SITE_CONFIG.notificationBar`, que es * cargada por `home/data/site-config-loader.js` desde * `conocimiento/data/cms/site-config.json`. * * Soporta: * - enabled (admin toggle) * - dismissible (botón × y persistencia en localStorage por sesión) * - tone: navy | copper | cream * - badge + message + link * * El espacio para un futuro live-ticker está reservado en la estructura, * pero se activa con `marketTicker.enabled` (off por ahora). */ const { useState: uS_Nb, useEffect: uE_Nb } = React; function NotificationBar() { // Estado reactivo a la config (puede llegar después por fetch) const [cfg, setCfg] = uS_Nb(() => window.SITE_CONFIG?.notificationBar || null); uE_Nb(() => { const onCfgLoaded = (e) => setCfg(e.detail?.notificationBar || null); window.addEventListener('cms:config-loaded', onCfgLoaded); return () => window.removeEventListener('cms:config-loaded', onCfgLoaded); }, []); // Persistencia del dismiss: si el usuario cerró la barra con esta versión // del mensaje, no la mostramos hasta que cambie el mensaje (hash sencillo). const msgHash = cfg ? simpleHash(cfg.message || '') : ''; const dismissKey = `nb:dismiss:${msgHash}`; const [dismissed, setDismissed] = uS_Nb(() => { try { return !!localStorage.getItem(dismissKey); } catch (_) { return false; } }); uE_Nb(() => { // Cuando cambia el mensaje, volvemos a evaluar try { setDismissed(!!localStorage.getItem(dismissKey)); } catch (_) {} }, [dismissKey]); if (!cfg || !cfg.enabled || dismissed) return null; const tones = { navy: { bg: 'var(--color-navy-deep)', fg: '#fff', acc: 'var(--color-copper-fallback)', soft: 'rgba(255,255,255,0.7)' }, copper: { bg: 'var(--color-copper-fallback)', fg: '#fff', acc: '#fff', soft: 'rgba(255,255,255,0.85)' }, cream: { bg: 'var(--color-cream-soft, #F2F0E8)', fg: 'var(--color-navy-deep)', acc: 'var(--color-copper-fallback)', soft: 'rgba(33,52,64,0.7)' }, }; const t = tones[cfg.tone] || tones.navy; const onDismiss = () => { try { localStorage.setItem(dismissKey, '1'); } catch (_) {} setDismissed(true); }; // Espacio reservado para un futuro ticker (cfg.ticker), por ahora sólo anuncio. return (