// Copy to src/pages/MockCustomersPage.tsx in the React edition. // Register the route as explained in routing.html. Start mock-server.cjs first. import { useEffect, useState } from 'react'; import { Card } from '../components/Card'; import { ResourceTable, type ResourceColumn } from '../features/business/ResourceTable'; type Customer = { id: string; name: string; email: string; plan: string; status: string }; const columns: ResourceColumn[] = [ { key: 'name', label: 'Name' }, { key: 'email', label: 'Email' }, { key: 'plan', label: 'Plan' }, { key: 'status', label: 'Status' }, ]; const base = import.meta.env.VITE_DEMO_API_URL || 'http://127.0.0.1:5188/api'; export default function MockCustomersPage() { const [rows, setRows] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(''); const [retry, setRetry] = useState(0); useEffect(() => { const controller = new AbortController(); async function load() { setLoading(true); setError(''); try { const response = await fetch(`${base.replace(/\/$/, '')}/customers`, { signal: controller.signal }); const body = await response.json(); if (!response.ok) throw Error(body.error || 'Unable to load customers.'); if (!Array.isArray(body.items) || !body.items.every((row: Customer) => row && ['id','name','email','plan','status'].every(key => typeof row[key as keyof Customer] === 'string'))) throw Error('Unexpected API response.'); if (!controller.signal.aborted) setRows(body.items); } catch (failure) { if (!controller.signal.aborted) setError(failure instanceof Error ? failure.message : 'Request failed.'); } finally { if (!controller.signal.aborted) setLoading(false); } } void load(); return () => controller.abort(); }, [retry]); return {loading ?

Loading customers…

: error ?

{error}

: }
; }