1import {Suspense} from 'react';2import StatsGrid from './StatsGrid';3import TableRow from './TableRow';4import TableHeader from './TableHeader';5import Pagination from './Pagination';6import ActivityItem from './ActivityItem';7import ChartPanel from './ChartPanel';8import Skeleton from './Skeleton';9import {generateProducts, generateActivities, generateStats} from './data';1011function fetchData(generator, ...args) {12 return new Promise(resolve => {13 setTimeout(() => resolve(generator(...args)), 1);14 });15}1617function fetchDelayed(value, delayMs) {18 return new Promise(resolve => {19 setTimeout(() => resolve(value), delayMs);20 });21}2223async function AsyncStatsSection() {24 const stats = await fetchData(generateStats);25 return <StatsGrid stats={stats} />;26}2728const productColumns = [29 {key: 'name', label: 'Product'},30 {key: 'sku', label: 'SKU'},31 {key: 'category', label: 'Category'},32 {key: 'price', label: 'Price'},33 {key: 'stock', label: 'Stock'},34 {key: 'status', label: 'Status'},35 {key: 'rating', label: 'Rating'},36];3738async function AsyncProductRow({product, delay}) {39 const resolved = await fetchDelayed(product, delay);40 return <TableRow product={resolved} columns={productColumns} />;41}4243async function AsyncProductSection({itemCount}) {44 const products = await fetchData(generateProducts, itemCount);45 return (46 <div className="product-table-container">47 <div className="table-toolbar">48 <h2>Products</h2>49 <span className="table-count">{products.length} items</span>50 </div>51 <table className="product-table">52 <thead>53 <tr>54 {productColumns.map(col => (55 <TableHeader key={col.key} column={col} />56 ))}57 </tr>58 </thead>59 <tbody>60 {products.map((product, i) => (61 <Suspense62 key={product.id}63 fallback={64 <tr>65 <td colSpan={7}>Loading...</td>66 </tr>67 }>68 <AsyncProductRow product={product} delay={1 + (i % 5)} />69 </Suspense>70 ))}71 </tbody>72 </table>73 <Pagination total={products.length} pageSize={20} />74 </div>75 );76}7778async function AsyncChartSection() {79 const stats = await fetchData(generateStats);80 return <ChartPanel title="Revenue" data={stats.revenueByMonth} type="bar" />;81}8283async function AsyncActivityItem({activity, delay}) {84 const resolved = await fetchDelayed(activity, delay);85 return (86 <ActivityItem87 type={resolved.type}88 user={resolved.user}89 message={resolved.message}90 timestamp={resolved.timestamp}91 details={resolved.details}92 />93 );94}9596async function AsyncActivitySection({itemCount}) {97 const activities = await fetchData(98 generateActivities,99 Math.min(itemCount, 50)100 );101 return (102 <div className="activity-feed">103 <h3>Recent Activity</h3>104 <ul className="activity-list">105 {activities.map((activity, i) => (106 <Suspense key={activity.id} fallback={<li>Loading...</li>}>107 <AsyncActivityItem activity={activity} delay={1 + (i % 5)} />108 </Suspense>109 ))}110 </ul>111 </div>112 );113}114115export default function DashboardAsync({itemCount}) {116 return (117 <main className="dashboard">118 <div className="dashboard-header">119 <h1>Dashboard Overview</h1>120 <p className="dashboard-subtitle">121 Welcome back. Here is what is happening with your store today.122 </p>123 </div>124 <Suspense fallback={<Skeleton type="stats" />}>125 <AsyncStatsSection />126 </Suspense>127 <div className="dashboard-grid">128 <div className="dashboard-main">129 <Suspense fallback={<Skeleton type="table" />}>130 <AsyncProductSection itemCount={itemCount} />131 </Suspense>132 </div>133 <div className="dashboard-aside">134 <Suspense fallback={<Skeleton type="chart" />}>135 <AsyncChartSection />136 </Suspense>137 <Suspense fallback={<Skeleton type="feed" />}>138 <AsyncActivitySection itemCount={itemCount} />139 </Suspense>140 </div>141 </div>142 </main>143 );144}
Findings
✓ No findings reported for this file.