Clean up revenue, AOV, brands & categories dialogs

This commit is contained in:
2024-12-23 14:14:16 -05:00
parent 8a8589e951
commit fd0e6d1789
2 changed files with 69 additions and 161 deletions

View File

@@ -1,19 +0,0 @@
{
"folders": [
{
"path": "."
}
],
"settings": {
"folder-color.pathColors": [
{
"folderPath": "Dev/dashboard/",
"badge": "🔵"
},
{
"folderPath": "Dev/dashboard-server/",
"badge": "🟣"
}
]
}
}

View File

@@ -159,7 +159,7 @@ const DetailDialog = ({
children children
}) => ( }) => (
<Dialog open={open} onOpenChange={onOpenChange}> <Dialog open={open} onOpenChange={onOpenChange}>
<DialogContent className="max-w-2xl max-h-[80vh] overflow-auto"> <DialogContent className="max-w-2xl max-h-[80vh] overflow-hidden">
<DialogHeader> <DialogHeader>
<DialogTitle>{title}</DialogTitle> <DialogTitle>{title}</DialogTitle>
</DialogHeader> </DialogHeader>
@@ -180,14 +180,7 @@ const RevenueDetails = ({ data }) => {
date: DateTime.fromISO(day.timestamp).toFormat('LLL d') date: DateTime.fromISO(day.timestamp).toFormat('LLL d')
})).sort((a, b) => DateTime.fromISO(a.timestamp) - DateTime.fromISO(b.timestamp)); })).sort((a, b) => DateTime.fromISO(a.timestamp) - DateTime.fromISO(b.timestamp));
// Calculate summary statistics
const totalRevenue = chartData.reduce((sum, day) => sum + day.revenue, 0);
const averageDailyRevenue = totalRevenue / chartData.length;
const maxRevenue = Math.max(...chartData.map(day => day.revenue));
const minRevenue = Math.min(...chartData.map(day => day.revenue));
return ( return (
<div className="space-y-8">
<TimeSeriesChart <TimeSeriesChart
data={chartData} data={chartData}
dataKey="revenue" dataKey="revenue"
@@ -196,38 +189,6 @@ const RevenueDetails = ({ data }) => {
valueFormatter={(value) => formatCurrency(value)} valueFormatter={(value) => formatCurrency(value)}
height={400} height={400}
/> />
<div className="grid grid-cols-2 gap-4">
<StatCard
title="Total Revenue"
value={formatCurrency(totalRevenue)}
description={`${chartData.length} days`}
colorClass="text-green-600 dark:text-green-400"
icon={DollarSign}
/>
<StatCard
title="Average Daily Revenue"
value={formatCurrency(averageDailyRevenue)}
description="per day"
colorClass="text-green-600 dark:text-green-400"
icon={TrendingUp}
/>
<StatCard
title="Highest Day"
value={formatCurrency(maxRevenue)}
description={chartData.find(d => d.revenue === maxRevenue)?.date}
colorClass="text-green-600 dark:text-green-400"
icon={ArrowUp}
/>
<StatCard
title="Lowest Day"
value={formatCurrency(minRevenue)}
description={chartData.find(d => d.revenue === minRevenue)?.date}
colorClass="text-green-600 dark:text-green-400"
icon={ArrowDown}
/>
</div>
</div>
); );
}; };
@@ -300,7 +261,6 @@ const AverageOrderDetails = ({ data, orderCount }) => {
if (!data?.length) return <div className="text-muted-foreground">No data available for the selected time range.</div>; if (!data?.length) return <div className="text-muted-foreground">No data available for the selected time range.</div>;
return ( return (
<>
<TimeSeriesChart <TimeSeriesChart
data={data} data={data}
dataKey="averageOrderValue" dataKey="averageOrderValue"
@@ -308,23 +268,6 @@ const AverageOrderDetails = ({ data, orderCount }) => {
color="hsl(262.1 83.3% 57.8%)" color="hsl(262.1 83.3% 57.8%)"
valueFormatter={(value) => formatCurrency(value)} valueFormatter={(value) => formatCurrency(value)}
/> />
<div className="mt-8">
<StatGrid
stats={[
{
label: "Average Items per Order",
value: data[0]?.averageItemsPerOrder?.toFixed(1) || "0",
description: "items"
},
{
label: "Total Orders",
value: orderCount?.toLocaleString() || "0",
description: "orders"
}
]}
/>
</div>
</>
); );
}; };
@@ -419,81 +362,65 @@ const CancellationsDetails = ({ data }) => {
const BrandsCategoriesDetails = ({ data }) => { const BrandsCategoriesDetails = ({ data }) => {
if (!data?.length) return <div className="text-muted-foreground">No data available for the selected time range.</div>; if (!data?.length) return <div className="text-muted-foreground">No data available for the selected time range.</div>;
const brandData = data[0]?.brands?.list?.map(brand => ({ const stats = data[0];
name: brand.name, const brandsList = stats?.brands?.list || [];
count: brand.count, const categoriesList = stats?.categories?.list || [];
revenue: brand.revenue,
percentage: (brand.count / data[0]?.itemCount * 100) || 0
}))?.sort((a, b) => b.count - a.count) || [];
const categoryData = data[0]?.categories?.list?.map(category => ({
name: category.name,
count: category.count,
revenue: category.revenue,
percentage: (category.count / data[0]?.itemCount * 100) || 0
}))?.sort((a, b) => b.count - a.count) || [];
if (!brandData.length && !categoryData.length) {
return <div className="text-muted-foreground">No brands or categories data available.</div>;
}
return ( return (
<div className="space-y-8"> <div className="grid grid-cols-1 md:grid-cols-2 gap-8">
{brandData.length > 0 && ( <div className="flex flex-col h-[30vh] sm:h-[60vh]">
<div> <h3 className="text-md font-medium mb-4 flex items-center gap-2">
<h3 className="text-lg font-medium mb-4">All Brands</h3> <Star className="h-5 w-5 text-yellow-500" />
<div className="rounded-lg border bg-card max-h-[400px] overflow-auto"> Brands ({stats?.brands?.total || 0})
</h3>
<div className="rounded-md border overflow-auto">
<Table> <Table>
<TableHeader className="sticky top-0 bg-background z-10"> <TableHeader className="sticky top-0 bg-background z-10">
<TableRow> <TableRow>
<TableHead>Brand</TableHead> <TableHead>Brand</TableHead>
<TableHead className="text-right">Items</TableHead> <TableHead className="text-right">Items</TableHead>
<TableHead className="text-right">Revenue</TableHead> <TableHead className="text-right">Revenue</TableHead>
<TableHead className="text-right">% of Total</TableHead>
</TableRow> </TableRow>
</TableHeader> </TableHeader>
<TableBody> <TableBody>
{brandData.map((brand, index) => ( {brandsList.map((brand) => (
<TableRow key={index}> <TableRow key={brand.name}>
<TableCell className="font-medium">{brand.name}</TableCell> <TableCell className="font-medium">{brand.name}</TableCell>
<TableCell className="text-right">{brand.count.toLocaleString()}</TableCell> <TableCell className="text-right">{brand.count?.toLocaleString()}</TableCell>
<TableCell className="text-right">{formatCurrency(brand.revenue)}</TableCell> <TableCell className="text-right">${brand.revenue?.toFixed(2)}</TableCell>
<TableCell className="text-right">{brand.percentage.toFixed(1)}%</TableCell>
</TableRow> </TableRow>
))} ))}
</TableBody> </TableBody>
</Table> </Table>
</div> </div>
</div> </div>
)}
{categoryData.length > 0 && ( <div className="flex flex-col h-[30vh] md:h-[60vh]">
<div> <h3 className="text-md font-medium mb-4 flex items-center gap-2">
<h3 className="text-lg font-medium mb-4">All Categories</h3> <Tags className="h-5 w-5 text-indigo-500" />
<div className="rounded-lg border bg-card max-h-[400px] overflow-auto"> Categories ({stats?.categories?.total || 0})
</h3>
<div className="rounded-md border overflow-auto">
<Table> <Table>
<TableHeader className="sticky top-0 bg-background z-10"> <TableHeader className="sticky top-0 bg-background z-10">
<TableRow> <TableRow>
<TableHead>Category</TableHead> <TableHead>Category</TableHead>
<TableHead className="text-right">Items</TableHead> <TableHead className="text-right">Items</TableHead>
<TableHead className="text-right">Revenue</TableHead> <TableHead className="text-right">Revenue</TableHead>
<TableHead className="text-right">% of Total</TableHead>
</TableRow> </TableRow>
</TableHeader> </TableHeader>
<TableBody> <TableBody>
{categoryData.map((category, index) => ( {categoriesList.map((category) => (
<TableRow key={index}> <TableRow key={category.name}>
<TableCell className="font-medium">{category.name}</TableCell> <TableCell className="font-medium">{category.name}</TableCell>
<TableCell className="text-right">{category.count.toLocaleString()}</TableCell> <TableCell className="text-right">{category.count?.toLocaleString()}</TableCell>
<TableCell className="text-right">{formatCurrency(category.revenue)}</TableCell> <TableCell className="text-right">${category.revenue?.toFixed(2)}</TableCell>
<TableCell className="text-right">{category.percentage.toFixed(1)}%</TableCell>
</TableRow> </TableRow>
))} ))}
</TableBody> </TableBody>
</Table> </Table>
</div> </div>
</div> </div>
)}
</div> </div>
); );
}; };