/* ============================================================
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' && setAddOpen(true)}> Add employee }
{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
Order Employee Date Points
{ADMIN_ORDERS.slice(0, 5).map(o => (
{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}
Resolve
))}
setTab('overages')}>Review all overages
);
}
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 (
Employee Role Department Points used Status
{list.map(e => {
const over = e.used > e.total;
const pct = Math.min(100, e.used / e.total * 100);
return (
{e.name.split(' ').map(n => n[0]).join('')}
{e.role === 'HR Admin' ? HR Admin : Employee }
{e.dept}
{e.status === 'Active' ? Active : Invited }
);
})}
);
}
/* ---------- Orders ---------- */
function AdminOrders() {
return (
Order Employee Date Items Points Status
{ADMIN_ORDERS.map(o => (
{o.id}
{o.emp}
{o.date}
{o.items}
{o.points} pts
{o.over ? Overage : Within allowance }
View
))}
);
}
/* ---------- 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.
Employee Department Allowance Used Owes
{overages.map(e => (
{e.name}
{e.email}
{e.dept}
{e.total} pts
{e.used} pts
${e.used - e.total}
Mark billed Adjust
))}
);
}
/* ---------- 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.
Cancel
Add & send invite
);
}
Object.assign(window, { AdminScreen, AdminOverview, StatCard, AdminEmployees, AdminOrders, AdminOverages, AdminPlaceholder, AddEmployeeModal });