This commit is contained in:
NotII
2025-07-01 01:49:49 +01:00
parent 20ae136e37
commit 18e87721e2
8 changed files with 458 additions and 110 deletions

View File

@@ -25,6 +25,7 @@ import OrderAnalyticsChart from "./OrderAnalyticsChart";
import MetricsCard from "./MetricsCard";
import { getAnalyticsOverviewWithStore, type AnalyticsOverview } from "@/lib/services/analytics-service";
import { formatGBP } from "@/utils/format";
import { MetricsCardSkeleton } from './SkeletonLoaders';
interface AnalyticsDashboardProps {
initialData: AnalyticsOverview;
@@ -95,9 +96,15 @@ export default function AnalyticsDashboard({ initialData }: AnalyticsDashboardPr
<div className="space-y-6">
{/* Key Metrics Cards */}
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6">
{metrics.map((metric) => (
<MetricsCard key={metric.title} {...metric} />
))}
{isLoading ? (
[...Array(4)].map((_, i) => (
<MetricsCardSkeleton key={i} />
))
) : (
metrics.map((metric) => (
<MetricsCard key={metric.title} {...metric} />
))
)}
</div>
{/* Completion Rate Card */}
@@ -112,25 +119,55 @@ export default function AnalyticsDashboard({ initialData }: AnalyticsDashboardPr
</CardDescription>
</CardHeader>
<CardContent>
<div className="flex items-center gap-4">
<div className="text-3xl font-bold">
{data.orders.completionRate}%
</div>
<div className="flex-1">
<div className="w-full bg-secondary rounded-full h-2">
<div
className="bg-primary h-2 rounded-full transition-all duration-300"
style={{ width: `${data.orders.completionRate}%` }}
/>
{isLoading ? (
<div className="flex items-center gap-4">
<div className="h-12 w-16 bg-muted/20 rounded animate-pulse" />
<div className="flex-1">
<div className="w-full bg-muted/20 rounded-full h-2 animate-pulse" />
</div>
<div className="h-6 w-16 bg-muted/20 rounded animate-pulse" />
</div>
<Badge variant="secondary">
{data.orders.completed} / {data.orders.total}
</Badge>
</div>
) : (
<div className="flex items-center gap-4">
<div className="text-3xl font-bold">
{data.orders.completionRate}%
</div>
<div className="flex-1">
<div className="w-full bg-secondary rounded-full h-2">
<div
className="bg-primary h-2 rounded-full transition-all duration-300"
style={{ width: `${data.orders.completionRate}%` }}
/>
</div>
</div>
<Badge variant="secondary">
{data.orders.completed} / {data.orders.total}
</Badge>
</div>
)}
</CardContent>
</Card>
{/* Time Period Selector */}
<div className="flex flex-col sm:flex-row gap-4 sm:items-center sm:justify-between">
<div>
<h3 className="text-lg font-semibold">Time period:</h3>
<p className="text-sm text-muted-foreground">
Revenue and Orders tabs use time filtering. Products and Customers show all-time data.
</p>
</div>
<Select value={timeRange} onValueChange={setTimeRange}>
<SelectTrigger className="w-32">
<SelectValue />
</SelectTrigger>
<SelectContent>
<SelectItem value="7">Last 7 days</SelectItem>
<SelectItem value="30">Last 30 days</SelectItem>
<SelectItem value="90">Last 90 days</SelectItem>
</SelectContent>
</Select>
</div>
{/* Analytics Tabs */}
<div className="space-y-6">
<Tabs defaultValue="revenue" className="space-y-6">