/* global React */ // ============================================================================ // Núcleo de Líderes — shared icons + components // Exports everything to window so other Babel scripts can use them. // ============================================================================ const Icon = ({ name, size = 18, stroke = 1.6, ...rest }) => { const paths = { home: <>, journey: <>, play: <>, file: <>, video: <>, chat: <>, users: <>, user: <>, settings: <>, logout: <>, check: <>, arrow: <>, chevronDown: <>, chevronRight: <>, download: <>, calendar: <>, plus: <>, search: <>, mail: <>, lock: <>, eye: <>, eyeOff: <>, trash: <>, edit: <>, copy: <>, sparkle: <>, book: <>, flame: <>, grid: <>, bell: <> }; return ( {paths[name] || null} ); }; const Avatar = ({ user, size = 'md', className = '' }) => { const isAdmin = user?.role === 'admin'; const sizes = { sm: '', md: '', lg: 'avatar-lg', xl: 'avatar-xl' }; return (
{user?.avatar || '·'}
); }; const ProgressRing = ({ value, size = 92, stroke = 6, color = 'var(--blue-bright)' }) => { const r = (size - stroke) / 2; const c = 2 * Math.PI * r; const offset = c - (value / 100) * c; return (
{value}%
); }; const ProgressBar = ({ value, gold = false }) => (
); // ----- relative date helper ----- function timeAgo(iso) { if (!iso) return ''; const d = new Date(iso); const s = Math.floor((Date.now() - d.getTime()) / 1000); if (s < 60) return 'agora'; if (s < 3600) return `${Math.floor(s/60)} min`; if (s < 86400) return `${Math.floor(s/3600)} h`; if (s < 86400 * 7) return `${Math.floor(s/86400)} d`; return d.toLocaleDateString('pt-BR', { day: '2-digit', month: 'short' }); } function formatDate(iso, opts) { if (!iso) return ''; return new Date(iso).toLocaleDateString('pt-BR', opts || { day:'2-digit', month:'short', year:'numeric' }); } function formatTime(iso) { if (!iso) return ''; return new Date(iso).toLocaleTimeString('pt-BR', { hour:'2-digit', minute:'2-digit' }); } // ----- modal ----- const Modal = ({ title, sub, onClose, children, actions }) => (
e.stopPropagation()}> {title &&

{title}

} {sub &&
{sub}
} {children} {actions &&
{actions}
}
); // ----- routing helper ----- function useHashRoute() { const [hash, setHash] = React.useState(() => window.location.hash.slice(1) || '/dashboard'); React.useEffect(() => { const onHash = () => setHash(window.location.hash.slice(1) || '/dashboard'); window.addEventListener('hashchange', onHash); return () => window.removeEventListener('hashchange', onHash); }, []); const nav = React.useCallback((path) => { window.location.hash = path; }, []); return { hash, nav }; } // re-render hook on DB change function useDB() { const [, setT] = React.useState(0); React.useEffect(() => DB.subscribe(() => setT(t => t + 1)), []); return DB; } Object.assign(window, { Icon, Avatar, ProgressRing, ProgressBar, Modal, timeAgo, formatDate, formatTime, useHashRoute, useDB });