/* Me2You - Admin RBAC Panel: Dashboard, Users, Listings, Orders, Disputes */ /* global React, Icon, StatusTag, RoleTag, Price, panelStyle, btnPrimary, btnGhost, btnDanger, btnSmall, ADMIN_USERS, SAMPLE_ORDERS, PRODUCTS */ const { useState } = React; const ADMIN_STATS = [ { label:'Active users', value:'847', icon:'users', color:'var(--success)' }, { label:'Active sellers', value:'124', icon:'package', color:'var(--brand-orange)' }, { label:'Live listings', value:'312', icon:'tag', color:'var(--info)' }, { label:'Pending moderation', value:'8', icon:'clock', color:'var(--warning)' }, { label:'Orders today', value:'23', icon:'receipt', color:'var(--success)' }, { label:'30-day GMV', value:'R 184 200', icon:'wallet', color:'var(--brand-orange)' }, { label:'Open disputes', value:'3', icon:'triangle-alert', color:'var(--danger)' }, { label:'Logged in as', value:'Admin', icon:'shield-check', color:'var(--brand-plum)' }, ]; const ADMIN_LISTINGS = [ { id:1, title:'iPhone 11 64GB - Black', seller:'Thandi Q.', status:'pending', price:4500, date:'1 May 2026' }, { id:2, title:'Fake Gucci bag', seller:'Scammer X.', status:'pending', price:200, date:'1 May 2026' }, { id:3, title:'Nike Air Max - UK 9', seller:'Thandi Q.', status:'live', price:1200, date:'28 Apr 2026' }, { id:4, title:'Hisense 32" Smart TV', seller:'Sipho M.', status:'live', price:1850, date:'25 Apr 2026' }, { id:5, title:'Cast-iron pot, 4L', seller:'Mama K.', status:'live', price:380, date:'22 Apr 2026' }, ]; const ADMIN_ORDERS = [ { ref:'M2Y-2026-00248', buyer:'Nomsa M.', seller:'Sipho M.', status:'paid', total:1910, date:'28 Apr' }, { ref:'M2Y-2026-00247', buyer:'Thandi K.', seller:'Mama K.', status:'dispatched', total:440, date:'27 Apr' }, { ref:'M2Y-2026-00246', buyer:'James R.', seller:'Mandla K.', status:'completed', total:1460, date:'26 Apr' }, { ref:'M2Y-2026-00245', buyer:'Siya N.', seller:'Naledi S.', status:'received', total:240, date:'25 Apr' }, { ref:'M2Y-2026-00244', buyer:'Mbali D.', seller:'MaZulu S.', status:'disputed', total:155, date:'24 Apr' }, { ref:'M2Y-2026-00243', buyer:'Grace D.', seller:'Pieter V.', status:'completed', total:510, date:'23 Apr' }, ]; const ADMIN_DISPUTES = [ { id:1, ref:'M2Y-2026-00244', buyer:'Mbali D.', seller:'MaZulu S.', reason:'Item not as described - received wrong size', status:'open', date:'24 Apr 2026', amount:155 }, { id:2, ref:'M2Y-2026-00232', buyer:'David L.', seller:'Chris N.', reason:'Package arrived damaged, torn packaging', status:'open', date:'20 Apr 2026', amount:740 }, { id:3, ref:'M2Y-2026-00218', buyer:'Fatima A.', seller:'Hennie V.', reason:'Never received item, tracking shows delivered', status:'open', date:'15 Apr 2026', amount:820 }, ]; function AdminPanel() { const [tab, setTab] = useState('dashboard'); const tabs = [ { key:'dashboard', label:'Dashboard', icon:'bar-chart' }, { key:'users', label:'Users', icon:'users' }, { key:'listings', label:'Listings', icon:'package' }, { key:'orders', label:'Orders', icon:'receipt' }, { key:'disputes', label:'Disputes', icon:'triangle-alert' }, { key:'payouts', label:'Payouts', icon:'wallet' }, { key:'audit', label:'Audit log', icon:'shield-check' }, ]; return (
{/* Sidebar */} {/* Main */}
{tab === 'dashboard' && } {tab === 'users' && } {tab === 'listings' && } {tab === 'orders' && } {tab === 'disputes' && } {tab === 'payouts' && } {tab === 'audit' && }
); } function AdminDash() { return (

Dashboard

Live snapshot - m2y.online

{ADMIN_STATS.map(s => (
{s.label}
{s.value}
))}

Recent orders

}, { key:'total', label:'Total', align:'right', render: v => }, ]}/>
); } function AdminUsers() { const [search, setSearch] = useState(''); const filtered = ADMIN_USERS.filter(u => u.name.toLowerCase().includes(search.toLowerCase()) || u.email.toLowerCase().includes(search.toLowerCase())); return (

Users

setSearch(e.target.value)} placeholder="Search users..." style={{padding:'10px 14px',border:'1.5px solid var(--ink-200)',borderRadius:'var(--radius-sm)',fontFamily:'var(--font-body)',fontSize:14,width:240}}/>
(
{v.charAt(0)}
{v}
{r.email}
)}, { key:'role', label:'Role', render: v => }, { key:'status', label:'Status', render: v => }, { key:'joined', label:'Joined' }, { key:'listings', label:'Listings', align:'center' }, { key:'orders', label:'Orders', align:'center' }, { key:'_actions', label:'', render:(_,r) => (
{r.status === 'active' ? : }
)}, ]}/>
); } function AdminListings() { return (

Listing moderation

{['All','Pending','Live','Removed'].map(f => ( ))}
{v} }, { key:'seller', label:'Seller' }, { key:'price', label:'Price', render: v => }, { key:'status', label:'Status', render: v => }, { key:'date', label:'Date' }, { key:'_actions', label:'', render:(_,r) => (
{r.status === 'pending' && <> } {r.status === 'live' && }
)}, ]}/>
); } function AdminOrders() { return (

Orders

}, { key:'total', label:'Total', align:'right', render: v => }, { key:'date', label:'Date' }, { key:'_actions', label:'', render:() => }, ]}/>
); } function AdminDisputes() { return (

Disputes

Review buyer complaints and resolve escrow holds.

{ADMIN_DISPUTES.map(d => (
{d.ref}
{d.reason}
Buyer: {d.buyer} - Seller: {d.seller} - {d.date} -
))}
); } /* --- Reusable admin table --- */ function AdminTable({ data, columns }) { return (
{columns.map(c => ( ))} {data.map((row,i) => ( e.currentTarget.style.background='var(--ink-50)'} onMouseLeave={e => e.currentTarget.style.background='transparent'}> {columns.map(c => ( ))} ))}
{c.label}
{c.render ? c.render(row[c.key], row) : row[c.key]}
); } Object.assign(window, { AdminPanel });