/* ============================================================ HR / Admin Dashboard — Evans Web Store ============================================================ */ function AdminScreen() { const { navigate, user } = useContext(AppCtx); const [tab, setTab] = useState('overview'); const [addOpen, setAddOpen] = useState(false); const nav = [ ['overview', 'grid', 'Overview'], ['employees', 'users', 'Employees'], ['orders', 'receipt', 'Orders'], ['overages', 'alert', 'Overages'], ['products', 'box', 'Products'], ['settings', 'settings', 'Settings'], ]; const overageCount = ADMIN_EMPLOYEES.filter(e => e.used > e.total).length; return (
{/* Sidebar */} {/* Main */}

{nav.find(n => n[0] === tab)[2]}

Evans Equipment & Environmental · Employee web store

{tab === 'employees' && }
{tab === 'overview' && } {tab === 'employees' && } {tab === 'orders' && } {tab === 'overages' && } {(tab === 'products' || tab === 'settings') && }
{addOpen && setAddOpen(false)} />}
); } /* ---------- Overview ---------- */ function AdminOverview({ setTab }) { const totalEmp = ADMIN_EMPLOYEES.filter(e => e.status === 'Active').length; const issued = ADMIN_EMPLOYEES.reduce((n, e) => n + e.total, 0); const spent = ADMIN_EMPLOYEES.reduce((n, e) => n + Math.min(e.used, e.total), 0); const overages = ADMIN_EMPLOYEES.filter(e => e.used > e.total); const overTotal = overages.reduce((n, e) => n + (e.used - e.total), 0); return (
{/* Recent orders */}

Recent orders

setTab('orders')}>View all
{ADMIN_ORDERS.slice(0, 5).map(o => ( ))}
OrderEmployeeDatePoints
{o.id} {o.emp} {o.date} {o.points} {o.over ? Over : OK}
{/* Overage alerts */}

Needs attention

{overages.length}
{overages.map(e => (
{e.name}
Owes ${e.used - e.total} · {e.dept}
))}
); } function StatCard({ icon, label, value, sub, tone }) { const bg = tone === 'teal' ? 'var(--teal-600)' : tone === 'amber' ? 'var(--amber)' : 'var(--surface-2)'; const fg = tone ? '#fff' : 'var(--muted)'; return (
{value}
{label}{sub && · {sub}}
); } /* ---------- Employees ---------- */ function AdminEmployees() { const [q, setQ] = useState(''); const list = ADMIN_EMPLOYEES.filter(e => e.name.toLowerCase().includes(q.toLowerCase()) || e.email.toLowerCase().includes(q.toLowerCase())); return (
setQ(e.target.value)} placeholder="Search employees…" style={{ border: 'none', background: 'transparent', outline: 'none', width: '100%', fontSize: 14, fontFamily: 'inherit' }} />
{list.length} of {ADMIN_EMPLOYEES.length}
{list.map(e => { const over = e.used > e.total; const pct = Math.min(100, e.used / e.total * 100); return ( ); })}
EmployeeRoleDepartmentPoints usedStatus
{e.name.split(' ').map(n => n[0]).join('')}
{e.name}
{e.email}
{e.role === 'HR Admin' ? HR Admin : Employee} {e.dept}
{e.used}/{e.total}
{e.status === 'Active' ? Active : Invited}
); } /* ---------- Orders ---------- */ function AdminOrders() { return (
{ADMIN_ORDERS.map(o => ( ))}
OrderEmployeeDateItemsPointsStatus
{o.id} {o.emp} {o.date} {o.items} {o.points} pts {o.over ? Overage : Within allowance}
); } /* ---------- Overages ---------- */ function AdminOverages() { const overages = ADMIN_EMPLOYEES.filter(e => e.used > e.total); return (
{overages.length} employees have exceeded their allowance. Total outstanding: ${overages.reduce((n, e) => n + (e.used - e.total), 0)}. These should be billed to the company or the employee.
{overages.map(e => ( ))}
EmployeeDepartmentAllowanceUsedOwes
{e.name}
{e.email}
{e.dept} {e.total} pts {e.used} pts ${e.used - e.total}
); } /* ---------- Placeholder tabs ---------- */ function AdminPlaceholder({ tab }) { const copy = tab === 'products' ? { icon: 'box', title: 'Product management', desc: 'Add, edit, and remove catalog items, manage colors and sizes, and assign products to Men\u2019s, Women\u2019s, or Technician categories. Imported from the existing store during setup.' } : { icon: 'settings', title: 'Store settings', desc: 'Configure the annual point allowance, reset schedule, delivery locations, overage rules, and HR notification recipients. Super Admin access required.' }; return (

{copy.title}

{copy.desc}

Wired up during backend handoff
); } /* ---------- Add employee modal ---------- */ function AddEmployeeModal({ onClose }) { return (
e.stopPropagation()}>

Add employee

They'll receive an email invite to set their password. The annual allowance is applied automatically.

); } Object.assign(window, { AdminScreen, AdminOverview, StatCard, AdminEmployees, AdminOrders, AdminOverages, AdminPlaceholder, AddEmployeeModal });