/** * Sales Analytics Dashboard * Complete sales dashboard with revenue KPIs, product charts, and customer tables */ import React, { useState, useEffect, useContext } from 'react'; import { Card, Grid, Title, Text, Metric, BadgeDelta, AreaChart, BarChart, DonutChart, Table, TableHead, TableRow, TableHeaderCell, TableBody, TableCell, DateRangePicker, Select, SelectItem, MultiSelect, MultiSelectItem } from '@tremor/react'; // Dashboard Context for Global Filters const DashboardContext = React.createContext({ filters: { dateRange: { start: new Date(), end: new Date() }, regions: [], products: [], salesReps: [] }, setFilters: () => {}, refreshInterval: 30000 }); // Main Sales Dashboard Component export function SalesDashboard() { const [filters, setFilters] = useState({ dateRange: { start: new Date(Date.now() - 30 * 24 * 60 * 60 * 1000), end: new Date() }, regions: [], products: [], salesReps: [] }); const [dashboardData, setDashboardData] = useState(null); const [loading, setLoading] = useState(true); // Fetch dashboard data based on filters useEffect(() => { fetchDashboardData(filters).then(data => { setDashboardData(data); setLoading(false); }); }, [filters]); if (loading) { return ; } return (
{/* Dashboard Header */}
Sales Analytics Dashboard Track revenue, products, and customer metrics
{/* Global Filters */}
setFilters({ ...filters, dateRange: value })} className="max-w-xs" /> setFilters({ ...filters, regions: value })} > North South East West setFilters({ ...filters, products: value })} > Product A Product B Product C
{/* KPI Cards */} {/* Charts Row */} {/* Sales by Region and Top Products */} {/* Recent Transactions Table */} Recent Transactions
); } // KPI Components function RevenueKPI({ data }) { return ( Total Revenue ${data.value.toLocaleString()}
0 ? 'increase' : 'decrease'}> {data.trend > 0 ? '+' : ''}{data.trend}% vs last period
); } function OrdersKPI({ data }) { return ( Total Orders {data.value.toLocaleString()}
0 ? 'increase' : 'decrease'}> {data.trend > 0 ? '+' : ''}{data.trend}% vs last period
); } function CustomersKPI({ data }) { return ( New Customers {data.value.toLocaleString()}
0 ? 'increase' : 'decrease'}> {data.trend > 0 ? '+' : ''}{data.trend}% vs last period
); } function ConversionKPI({ data }) { return ( Conversion Rate {data.value}%
0 ? 'increase' : 'decrease'}> {data.trend > 0 ? '+' : ''}{data.trend} pp vs last period
); } // Chart Components function RevenueChart({ data }) { const { filters } = useContext(DashboardContext); return ( Revenue Trend Daily revenue over selected period `$${(value / 1000).toFixed(1)}k`} showLegend showGridLines showAnimation /> ); } function ProductPerformance({ data }) { return ( Product Performance Revenue by product category `$${(value / 1000).toFixed(1)}k`} showLegend stack={false} /> ); } function RegionalSales({ data }) { return ( Sales by Region `$${(value / 1000).toFixed(0)}k`} colors={["blue", "cyan", "indigo", "violet"]} showLabel showAnimation />
{data.map((item) => (
{item.region} ${(item.sales / 1000).toFixed(0)}k
))}
); } function TopProducts({ data }) { return ( Top Products Product Revenue Growth {data.slice(0, 5).map((item) => ( {item.name} ${(item.revenue / 1000).toFixed(1)}k 0 ? 'increase' : 'decrease'}> {item.growth}% ))}
); } function SalesTeamPerformance({ data }) { return ( Sales Team Performance
{data.slice(0, 5).map((rep) => (
{rep.name} ${(rep.sales / 1000).toFixed(0)}k
{((rep.sales / rep.target) * 100).toFixed(0)}% of target
))}
); } // Transactions Table function TransactionsTable({ data }) { const [page, setPage] = useState(0); const pageSize = 10; const paginatedData = data.slice(page * pageSize, (page + 1) * pageSize); return ( <> Transaction ID Date Customer Product Amount Status {paginatedData.map((transaction) => ( {transaction.id} {new Date(transaction.date).toLocaleDateString()} {transaction.customer} {transaction.product} ${transaction.amount.toLocaleString()} {transaction.status} ))}
{/* Pagination */}
Showing {page * pageSize + 1} to {Math.min((page + 1) * pageSize, data.length)} of {data.length}
); } // Loading Skeleton function DashboardSkeleton() { return (
{[1, 2, 3, 4].map((i) => (
))}
); } // Sparkline Component function Sparkline({ data, className = '' }) { const max = Math.max(...data); const min = Math.min(...data); const range = max - min || 1; const points = data.map((value, index) => { const x = (index / (data.length - 1)) * 100; const y = 100 - ((value - min) / range) * 100; return `${x},${y}`; }).join(' '); return ( ); } // Badge Component function Badge({ children, color = 'gray' }) { const colors = { green: 'bg-green-100 text-green-800', yellow: 'bg-yellow-100 text-yellow-800', red: 'bg-red-100 text-red-800', gray: 'bg-gray-100 text-gray-800' }; return ( {children} ); } // Progress Bar Component function ProgressBar({ value, color = 'blue', className = '' }) { return (
); } // Mock data fetching function async function fetchDashboardData(filters) { // Simulate API call await new Promise(resolve => setTimeout(resolve, 1000)); return { revenue: { value: 1245832, trend: 15.3, sparkline: [100, 120, 115, 140, 155, 145, 160, 180, 175, 190, 210, 205] }, orders: { value: 3421, trend: 8.7 }, customers: { value: 892, trend: -2.3 }, conversion: { value: 3.8, trend: 0.5 }, revenueHistory: generateRevenueHistory(), products: generateProductData(), regions: generateRegionalData(), topProducts: generateTopProducts(), salesTeam: generateSalesTeamData(), transactions: generateTransactions() }; } // Data generation helpers function generateRevenueHistory() { const data = []; const now = new Date(); for (let i = 30; i >= 0; i--) { const date = new Date(now); date.setDate(date.getDate() - i); data.push({ date: date.toISOString().split('T')[0], revenue: Math.floor(Math.random() * 50000) + 30000, target: 40000 }); } return data; } function generateProductData() { return [ { product: 'Product A', revenue: 125000, units: 1250 }, { product: 'Product B', revenue: 98000, units: 890 }, { product: 'Product C', revenue: 87000, units: 1100 }, { product: 'Product D', revenue: 65000, units: 450 } ]; } function generateRegionalData() { return [ { region: 'North', sales: 425000 }, { region: 'South', sales: 380000 }, { region: 'East', sales: 290000 }, { region: 'West', sales: 150832 } ]; } function generateTopProducts() { return [ { id: 1, name: 'Premium Widget', revenue: 234000, growth: 23.5 }, { id: 2, name: 'Standard Widget', revenue: 189000, growth: 15.2 }, { id: 3, name: 'Basic Widget', revenue: 145000, growth: 8.7 }, { id: 4, name: 'Deluxe Widget', revenue: 98000, growth: -5.3 }, { id: 5, name: 'Compact Widget', revenue: 87000, growth: 12.1 } ]; } function generateSalesTeamData() { return [ { id: 1, name: 'John Smith', sales: 145000, target: 150000 }, { id: 2, name: 'Jane Doe', sales: 132000, target: 140000 }, { id: 3, name: 'Mike Johnson', sales: 118000, target: 130000 }, { id: 4, name: 'Sarah Williams', sales: 105000, target: 120000 }, { id: 5, name: 'Tom Brown', sales: 95000, target: 110000 } ]; } function generateTransactions() { const transactions = []; const products = ['Widget A', 'Widget B', 'Widget C', 'Widget D']; const customers = ['Acme Corp', 'GlobalTech', 'MegaCorp', 'TechStart', 'Enterprise Inc']; const statuses = ['completed', 'pending', 'completed', 'completed']; for (let i = 0; i < 50; i++) { transactions.push({ id: `TRX-${1000 + i}`, date: new Date(Date.now() - Math.random() * 30 * 24 * 60 * 60 * 1000), customer: customers[Math.floor(Math.random() * customers.length)], product: products[Math.floor(Math.random() * products.length)], amount: Math.floor(Math.random() * 5000) + 500, status: statuses[Math.floor(Math.random() * statuses.length)] }); } return transactions.sort((a, b) => b.date - a.date); } export default SalesDashboard;