/* JRN — Componentes compartilhados */ const { useState, useEffect, useRef, useMemo } = React; /* ---------- Logo da empresa em "chip" ---------- */ function CompanyMark({ company, size = 44, ring = false }) { return (
{company.nome}
); } /* ---------- Badge de status ---------- */ function StatusBadge({ status }) { const map = { ativo: ['badge-ok', 'Ativo'], inativo: ['badge-neutral', 'Inativo'], manutencao: ['badge-warn', 'Manutenção'], online: ['badge-ok', 'Online'], }; const [cls, label] = map[status] || ['badge-neutral', status]; return {label}; } /* ---------- Botão com ícone ---------- */ function Btn({ icon, children, variant = 'primary', sm, ...rest }) { const I = icon ? Icons[icon] : null; return ( ); } /* ---------- Campo de texto ---------- */ function Field({ label, hint, children, full }) { return (
{label && } {children} {hint && {hint}}
); } function TextInput(props) { return ; } function Select({ children, ...rest }) { return (
); } /* ---------- Toggle / switch ---------- */ function Switch({ on, onChange, accent = 'var(--navy-800)' }) { return ( ); } /* ---------- Checkbox ---------- */ function Check({ on, onChange, accent = 'var(--navy-800)', size = 19 }) { return ( ); } /* ---------- Modal ---------- */ function Modal({ title, sub, onClose, children, footer, width = 560 }) { useEffect(() => { const h = (e) => e.key === 'Escape' && onClose(); window.addEventListener('keydown', h); return () => window.removeEventListener('keydown', h); }, [onClose]); return (
e.stopPropagation()} className="fade-in" style={{ background: '#fff', borderRadius: 'var(--r-lg)', width: '100%', maxWidth: width, boxShadow: 'var(--sh-lg)', }}>

{title}

{sub &&

{sub}

}
{children}
{footer &&
{footer}
}
); } /* ---------- Toast ---------- */ function useToast() { const [toast, setToast] = useState(null); const show = (msg, kind = 'ok') => { setToast({ msg, kind }); setTimeout(() => setToast(null), 2800); }; const node = toast ? (
{toast.msg}
) : null; return [node, show]; } /* ---------- Page header ---------- */ function PageHead({ kicker, title, sub, actions }) { return (
{kicker &&
{kicker}
}

{title}

{sub &&

{sub}

}
{actions &&
{actions}
}
); } /* ---------- Empty state ---------- */ function Empty({ icon = 'search', title, sub }) { const I = Icons[icon]; return (
{title}
{sub &&
{sub}
}
); } Object.assign(window, { CompanyMark, StatusBadge, Btn, Field, TextInput, Select, Switch, Check, Modal, useToast, PageHead, Empty, });