/* ============================================================ UNIQUE Customer App — simulated data + shared UI helpers Exposes to window: U_DATA, Icon, Ring, MiniBars, money, Sheet ============================================================ */ const U_DATA = { user: { name: 'Awa', full: 'Awa Ceesay', initials: 'AC', area: 'Serrekunda', acct: 'UQ-204-8817' }, plan: { name: 'Surge', speed: 75, price: '2,800', renews: '5 Jun 2026' }, line: { status: 'Connected', down: 73.4, up: 41.2, ping: 12, ssid: 'Unique-Ceesay' }, balance: { amount: '0.00', due: '2,800.00', dueDate: '5 Jun', autopay: true }, usage: { monthGB: 184.6, projGB: 241, days: 24, daily: [6.2,8.1,5.4,9.6,7.2,11.4,13.1,7.8,6.0,8.9,10.2,12.6,9.1,7.4,8.0,11.9,13.4,9.7,6.6,8.3,10.0,12.1,9.4,7.9], cats: [ { name: 'Video & streaming', gb: 92.4, pct: 50, color: 'var(--red)' }, { name: 'Social & messaging', gb: 38.7, pct: 21, color: 'var(--blue)' }, { name: 'Work & cloud', gb: 29.5, pct: 16, color: 'var(--green)' }, { name: 'Downloads & other', gb: 24.0, pct: 13, color: 'var(--gold)' }, ], devices: [ { name: 'Awa\u2019s iPhone', gb: 64.2, on: true }, { name: 'Living room TV', gb: 71.8, on: true }, { name: 'MacBook Air', gb: 33.1, on: true }, { name: 'Kids\u2019 iPad', gb: 15.5, on: false }, ], }, invoices: [ { id: 'INV-2026-051', month: 'May 2026', amount: '2,800.00', status: 'Paid', date: '5 May' }, { id: 'INV-2026-041', month: 'Apr 2026', amount: '2,800.00', status: 'Paid', date: '5 Apr' }, { id: 'INV-2026-031', month: 'Mar 2026', amount: '2,800.00', status: 'Paid', date: '5 Mar' }, { id: 'INV-2026-021', month: 'Feb 2026', amount: '2,800.00', status: 'Paid', date: '5 Feb' }, ], methods: [ { id: 'wave', label: 'Wave', detail: '•••• 4471', kind: 'wave' }, { id: 'qmoney', label: 'QMoney', detail: '+220 ••• 8821', kind: 'momo' }, { id: 'card', label: 'Visa', detail: '•••• 2043', kind: 'card' }, ], plans: [ { name: 'Spark', speed: 30, price: '1,500', tag: 'Browse & stream' }, { name: 'Surge', speed: 75, price: '2,800', tag: 'Families', current: true }, { name: 'Apex', speed: 200, price: '4,900', tag: 'Work & creators' }, ], }; // ── Icons ────────────────────────────────────────────── const ICONS = { home: 'M3 11.5 12 4l9 7.5M5.5 9.7V20h13V9.7', usage: 'M4 20V10M9 20V4M14 20v-7M19 20v-11', pay: 'M3 7h18v11H3zM3 10h18M7 15h4', account: 'M12 12a4 4 0 1 0 0-8 4 4 0 0 0 0 8ZM5 21v-1a6 6 0 0 1 12 0v1', plus: 'M12 5v14M5 12h14', pause: 'M9 5v14M15 5v14', gauge: 'M12 14 16 9M3.5 17a9 9 0 1 1 17 0', bolt: 'M13 2 4 14h7l-1 8 9-12h-7l1-8z', chevron: 'M9 6l6 6-6 6', check: 'M5 12l5 5 9-10', wifi: 'M5 12.5a10 10 0 0 1 14 0M8 15.5a6 6 0 0 1 8 0M12 18.5h0', download: 'M12 4v10m0 0 4-4m-4 4-4-4M5 20h14', shield: 'M12 3l8 3v6c0 5-3.5 8-8 10-4.5-2-8-5-8-10V6l8-3z', clock: 'M12 7v5l3 2M12 21a9 9 0 1 0 0-18 9 9 0 0 0 0 18Z', arrow: 'M5 12h14M13 6l6 6-6 6', refer: 'M16 11a4 4 0 1 0 0-8 4 4 0 0 0 0 8ZM8 11a4 4 0 1 0 0-8M2 21v-1a6 6 0 0 1 9-5.2M14 21v-1a6 6 0 0 1 8-5.6', bell: 'M18 8a6 6 0 1 0-12 0c0 7-3 9-3 9h18s-3-2-3-9M13.7 21a2 2 0 0 1-3.4 0', headset: 'M4 14v-2a8 8 0 0 1 16 0v2M4 14a2 2 0 0 0 2 2h1v-4H6a2 2 0 0 0-2 2Zm16 0a2 2 0 0 0-2-2h-1v4h1a2 2 0 0 0 2-2Zm-2 4a4 4 0 0 1-4 3', send: 'M4 12 20 4l-5 16-3-7-7-1z', spark: 'M12 3l1.8 5.2L19 10l-5.2 1.8L12 17l-1.8-5.2L5 10l5.2-1.8L12 3z', }; function Icon({ name, size = 22, color = 'currentColor', sw = 2, fill = 'none', style }) { return ( ); } // ── Circular progress ring ───────────────────────────── function Ring({ pct, size = 132, sw = 13, color = 'var(--red)', track = 'var(--paper-3)', children }) { const r = (size - sw) / 2, c = 2 * Math.PI * r, off = c * (1 - pct / 100); return (
{children}
); } // ── Mini bar chart ───────────────────────────────────── function MiniBars({ data, height = 90, accentIdx, color = 'var(--navy)', accent = 'var(--red)', gap = 4 }) { const max = Math.max(...data); return (
{data.map((v, i) => (
))}
); } function money(v) { return 'D\u00A0' + v; } // ── Bottom sheet / modal ─────────────────────────────── function Sheet({ open, onClose, children, title }) { if (!open) return null; return (
e.stopPropagation()} style={{ width: '100%', background: 'var(--paper)', borderRadius: '26px 26px 0 0', padding: '10px 20px 30px', boxShadow: '0 -20px 50px rgba(6,23,38,.25)', animation: 'u-slideup .3s cubic-bezier(.2,.8,.2,1)', maxHeight: '88%', overflow: 'auto', }}>
{title &&

{title}

} {children}
); } Object.assign(window, { U_DATA, Icon, Ring, MiniBars, money, Sheet });