/* Santos OS — shared primitives. Exposes components on window. */
const { useState } = React;
const T = window.T;
// ── Santos wordmark — orange "o" with a white Farmacia cross (brand mark) ─────
function Wordmark({ size = 22, color = '#fff', sub }) {
const d = size*0.62;
const disc = {
display:'inline-flex', alignItems:'center', justifyContent:'center',
background:T.secondary, borderRadius:'50%',
width:d, height:d, margin:'0 0.5px', transform:`translateY(${size*0.04}px)`,
};
return (
);
}
// ── Tier badge ────────────────────────────────────────────────────────────────
function TierBadge({ tier, size = 'md', showLabel = true }) {
const c = T.tiers[tier];
const fs = size==='sm'?10:size==='lg'?14:12;
const ic = size==='sm'?13:size==='lg'?19:15;
const ph = size==='sm'?8:size==='lg'?13:10;
const pv = size==='sm'?3:size==='lg'?5:4;
return (
{c.icon}
{showLabel && {tier}}
);
}
// ── Pill ──────────────────────────────────────────────────────────────────────
function Pill({ children, color = T.primary, bg, style }) {
return {children};
}
// ── Button ────────────────────────────────────────────────────────────────────
function Btn({ children, variant='primary', onClick, style, full }) {
const base = {fontFamily:T.font, fontSize:14, fontWeight:700, borderRadius:12, padding:'13px 18px', border:'none', cursor:'pointer', display:'inline-flex', alignItems:'center', justifyContent:'center', gap:7, width:full?'100%':undefined, transition:'filter .12s, opacity .12s'};
const v = {
primary:{background:T.primary, color:'#fff', boxShadow:'0 3px 8px rgba(8,54,47,0.25)'},
secondary:{background:T.secondary, color:'#fff'},
outline:{background:'transparent', color:T.fg2, border:`1.5px solid ${T.border}`},
ghost:{background:'rgba(74,124,114,0.12)', color:T.primary},
danger:{background:'transparent', color:T.danger, border:`1.5px solid ${T.danger}`},
success:{background:'#25D366', color:'#fff'},
}[variant];
return ;
}
// ── Section label ─────────────────────────────────────────────────────────────
function SectionLabel({ children, style }) {
return {children}
;
}
// ── Card ──────────────────────────────────────────────────────────────────────
function Card({ children, style, onClick }) {
return {children}
;
}
// ── Phone shell ───────────────────────────────────────────────────────────────
function Phone({ children }) {
return (
{/* status bar */}
{children}
);
}
// ── Tab bar ───────────────────────────────────────────────────────────────────
const TABS = [
{key:'inicio', icon:'⌂', label:'Inicio'},
{key:'alertas', icon:'◉', label:'Alertas', badge:3},
{key:'clientes', icon:'★', label:'Clientes', badge:2},
{key:'almacen', icon:'▢', label:'Almacén'},
{key:'analitica', icon:'↗', label:'Analítica'},
];
function TabBar({ active, onChange, perms }) {
const visible = TABS.filter(t => {
if (t.key==='alertas') return perms.alerts;
if (t.key==='clientes') return perms.customers;
if (t.key==='analitica') return perms.analytics;
return true;
});
return (
{visible.map(t => {
const on = active===t.key;
return (
);
})}
);
}
// ── Green app header (used across tabs) ───────────────────────────────────────
function AppHeader({ user, onLogout }) {
const greet = (() => { const h=new Date().getHours(); return h<12?'Buenos días':h<18?'Buenas tardes':'Buenas noches'; })();
const initials = user.name.split(' ').map(w=>w[0]).slice(0,2).join('');
return (
{greet}, {user.name.split(' ')[0]}
{user.sucursal.split('—')[0].trim()}
);
}
Object.assign(window, { Wordmark, TierBadge, Pill, Btn, SectionLabel, Card, Phone, TabBar, AppHeader });