142 lines
4.0 KiB
TypeScript
142 lines
4.0 KiB
TypeScript
import React, { useState } from 'react';
|
|
|
|
export default function AnalyticsDashboard() {
|
|
const [stats] = useState({
|
|
revenue: { current: 45678, previous: 39234, growth: 16.4 },
|
|
orders: { current: 342, previous: 298, growth: 14.8 },
|
|
customers: { current: 156, previous: 142, growth: 9.9 },
|
|
avgOrder: { current: 133.56, previous: 131.63, growth: 1.5 },
|
|
});
|
|
|
|
const [topProducts] = useState([
|
|
{ name: 'Widget Pro', sales: 1234, revenue: 6170 },
|
|
{ name: 'Gadget Plus', sales: 987, revenue: 7896 },
|
|
{ name: 'Tool Set', sales: 654, revenue: 6540 },
|
|
]);
|
|
|
|
return (
|
|
<div style={styles.container}>
|
|
<h1 style={styles.title}>Analytics Dashboard</h1>
|
|
|
|
<div style={styles.statsGrid}>
|
|
<div style={styles.statCard}>
|
|
<div style={styles.statLabel}>Total Revenue</div>
|
|
<div style={styles.statValue}>${stats.revenue.current.toLocaleString()}</div>
|
|
<div style={{ ...styles.growth, color: '#10b981' }}>↑ {stats.revenue.growth}%</div>
|
|
</div>
|
|
<div style={styles.statCard}>
|
|
<div style={styles.statLabel}>Orders</div>
|
|
<div style={styles.statValue}>{stats.orders.current}</div>
|
|
<div style={{ ...styles.growth, color: '#10b981' }}>↑ {stats.orders.growth}%</div>
|
|
</div>
|
|
<div style={styles.statCard}>
|
|
<div style={styles.statLabel}>Customers</div>
|
|
<div style={styles.statValue}>{stats.customers.current}</div>
|
|
<div style={{ ...styles.growth, color: '#10b981' }}>↑ {stats.customers.growth}%</div>
|
|
</div>
|
|
<div style={styles.statCard}>
|
|
<div style={styles.statLabel}>Avg Order Value</div>
|
|
<div style={styles.statValue}>${stats.avgOrder.current.toFixed(2)}</div>
|
|
<div style={{ ...styles.growth, color: '#10b981' }}>↑ {stats.avgOrder.growth}%</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div style={styles.section}>
|
|
<h2 style={styles.sectionTitle}>Top Products</h2>
|
|
<table style={styles.table}>
|
|
<thead>
|
|
<tr>
|
|
<th style={styles.th}>Product</th>
|
|
<th style={styles.th}>Sales</th>
|
|
<th style={styles.th}>Revenue</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{topProducts.map((product, i) => (
|
|
<tr key={i} style={styles.tr}>
|
|
<td style={styles.td}>{product.name}</td>
|
|
<td style={styles.td}>{product.sales}</td>
|
|
<td style={styles.td}>${product.revenue.toLocaleString()}</td>
|
|
</tr>
|
|
))}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
const styles: Record<string, React.CSSProperties> = {
|
|
container: {
|
|
padding: '2rem',
|
|
backgroundColor: '#111827',
|
|
minHeight: '100vh',
|
|
color: '#f9fafb',
|
|
fontFamily: 'system-ui, -apple-system, sans-serif',
|
|
},
|
|
title: {
|
|
fontSize: '2rem',
|
|
fontWeight: 'bold',
|
|
marginBottom: '2rem',
|
|
color: '#f9fafb',
|
|
},
|
|
statsGrid: {
|
|
display: 'grid',
|
|
gridTemplateColumns: 'repeat(auto-fit, minmax(200px, 1fr))',
|
|
gap: '1rem',
|
|
marginBottom: '2rem',
|
|
},
|
|
statCard: {
|
|
backgroundColor: '#1f2937',
|
|
padding: '1.5rem',
|
|
borderRadius: '0.5rem',
|
|
border: '1px solid #374151',
|
|
},
|
|
statLabel: {
|
|
fontSize: '0.875rem',
|
|
color: '#9ca3af',
|
|
marginBottom: '0.5rem',
|
|
},
|
|
statValue: {
|
|
fontSize: '2rem',
|
|
fontWeight: 'bold',
|
|
color: '#3b82f6',
|
|
marginBottom: '0.5rem',
|
|
},
|
|
growth: {
|
|
fontSize: '0.875rem',
|
|
fontWeight: '500',
|
|
},
|
|
section: {
|
|
backgroundColor: '#1f2937',
|
|
padding: '1.5rem',
|
|
borderRadius: '0.5rem',
|
|
border: '1px solid #374151',
|
|
},
|
|
sectionTitle: {
|
|
fontSize: '1.25rem',
|
|
fontWeight: '600',
|
|
marginBottom: '1rem',
|
|
color: '#f9fafb',
|
|
},
|
|
table: {
|
|
width: '100%',
|
|
borderCollapse: 'collapse',
|
|
},
|
|
th: {
|
|
padding: '0.75rem',
|
|
textAlign: 'left',
|
|
backgroundColor: '#374151',
|
|
color: '#f9fafb',
|
|
fontWeight: '600',
|
|
fontSize: '0.875rem',
|
|
},
|
|
tr: {
|
|
borderBottom: '1px solid #374151',
|
|
},
|
|
td: {
|
|
padding: '0.75rem',
|
|
color: '#d1d5db',
|
|
},
|
|
};
|