From 356da4606d037fc2e9ea1b0d36af0be8f27cbf6b Mon Sep 17 00:00:00 2001 From: NotII <46204250+NotII@users.noreply.github.com> Date: Mon, 30 Jun 2025 14:54:13 +0100 Subject: [PATCH] uwu --- .../analytics/CustomerInsightsChart.tsx | 2 +- components/analytics/RevenueChart.tsx | 106 +++++++++++++----- lib/services/analytics-service.ts | 2 + package-lock.json | 6 +- package.json | 2 +- 5 files changed, 82 insertions(+), 36 deletions(-) diff --git a/components/analytics/CustomerInsightsChart.tsx b/components/analytics/CustomerInsightsChart.tsx index 19dea43..e7c22e5 100644 --- a/components/analytics/CustomerInsightsChart.tsx +++ b/components/analytics/CustomerInsightsChart.tsx @@ -225,7 +225,7 @@ export default function CustomerInsightsChart() { {index + 1}
-
Customer #{customer._id.slice(-6)}
+
{customer.displayName || `Customer #${customer._id.slice(-6)}`}
{customer.orderCount} orders
diff --git a/components/analytics/RevenueChart.tsx b/components/analytics/RevenueChart.tsx index cf4d60f..ef8c9be 100644 --- a/components/analytics/RevenueChart.tsx +++ b/components/analytics/RevenueChart.tsx @@ -7,11 +7,19 @@ import { Skeleton } from "@/components/ui/skeleton"; import { TrendingUp, DollarSign } from "lucide-react"; import { getRevenueTrendsWithStore, type RevenueData } from "@/lib/services/analytics-service"; import { formatGBP } from "@/utils/format"; +import { LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer, BarChart, Bar } from 'recharts'; interface RevenueChartProps { timeRange: string; } +interface ChartDataPoint { + date: string; + revenue: number; + orders: number; + formattedDate: string; +} + export default function RevenueChart({ timeRange }: RevenueChartProps) { const [data, setData] = useState([]); const [isLoading, setIsLoading] = useState(true); @@ -24,10 +32,12 @@ export default function RevenueChart({ timeRange }: RevenueChartProps) { setIsLoading(true); setError(null); const response = await getRevenueTrendsWithStore(timeRange); - setData(response); + console.log('Revenue trends response:', response); + setData(Array.isArray(response) ? response : []); } catch (err) { console.error('Error fetching revenue data:', err); setError('Failed to load revenue data'); + setData([]); toast({ title: "Error", description: "Failed to load revenue trends data.", @@ -41,16 +51,43 @@ export default function RevenueChart({ timeRange }: RevenueChartProps) { fetchRevenueData(); }, [timeRange, toast]); - const totalRevenue = data.reduce((sum, item) => sum + item.revenue, 0); - const totalOrders = data.reduce((sum, item) => sum + item.orders, 0); - const averageRevenue = data.length > 0 ? totalRevenue / data.length : 0; - - const formatDate = (item: RevenueData) => { + // Transform data for Recharts + const chartData: ChartDataPoint[] = data.map(item => { const date = new Date(item._id.year, item._id.month - 1, item._id.day); - return date.toLocaleDateString('en-GB', { - month: 'short', - day: 'numeric' - }); + return { + date: date.toISOString().split('T')[0], // YYYY-MM-DD format + revenue: item.revenue || 0, + orders: item.orders || 0, + formattedDate: date.toLocaleDateString('en-GB', { + month: 'short', + day: 'numeric' + }) + }; + }); + + // Calculate summary stats + const safeData = Array.isArray(data) ? data : []; + const totalRevenue = safeData.reduce((sum, item) => sum + (item.revenue || 0), 0); + const totalOrders = safeData.reduce((sum, item) => sum + (item.orders || 0), 0); + const averageRevenue = safeData.length > 0 ? totalRevenue / safeData.length : 0; + + // Custom tooltip for the chart + const CustomTooltip = ({ active, payload, label }: any) => { + if (active && payload && payload.length) { + const data = payload[0].payload; + return ( +
+

{data.formattedDate}

+

+ Revenue: {formatGBP(data.revenue)} +

+

+ Orders: {data.orders} +

+
+ ); + } + return null; }; if (isLoading) { @@ -98,7 +135,7 @@ export default function RevenueChart({ timeRange }: RevenueChartProps) { ); } - if (data.length === 0) { + if (chartData.length === 0) { return ( @@ -132,26 +169,33 @@ export default function RevenueChart({ timeRange }: RevenueChartProps) { - {/* Simple bar chart representation */} -
-
- {data.map((item, index) => { - const maxRevenue = Math.max(...data.map(d => d.revenue)); - const height = maxRevenue > 0 ? (item.revenue / maxRevenue) * 100 : 0; - - return ( -
-
-
- {formatDate(item)} -
-
- ); - })} +
+ {/* Chart */} +
+ + + + + `£${(value / 1000).toFixed(0)}k`} + /> + } /> + + +
{/* Summary stats */} diff --git a/lib/services/analytics-service.ts b/lib/services/analytics-service.ts index 7e37177..ca4ac6f 100644 --- a/lib/services/analytics-service.ts +++ b/lib/services/analytics-service.ts @@ -63,6 +63,8 @@ export interface CustomerInsights { averageOrderValue: number; firstOrder: string; lastOrder: string; + displayName?: string; + username?: string; }>; averageOrdersPerCustomer: string; } diff --git a/package-lock.json b/package-lock.json index 503854e..8de87b8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "my-v0-project", - "version": "1.1.7", + "version": "2.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "my-v0-project", - "version": "1.1.7", + "version": "2.0.0", "dependencies": { "@hookform/resolvers": "^3.9.1", "@radix-ui/react-accordion": "^1.2.2", @@ -61,7 +61,7 @@ "react-hook-form": "^7.54.1", "react-markdown": "^10.0.0", "react-resizable-panels": "^2.1.7", - "recharts": "2.15.0", + "recharts": "^2.15.0", "sonner": "^1.7.4", "tailwind-merge": "^2.5.5", "tailwindcss-animate": "^1.0.7", diff --git a/package.json b/package.json index 1a6f07d..4671542 100644 --- a/package.json +++ b/package.json @@ -69,7 +69,7 @@ "react-hook-form": "^7.54.1", "react-markdown": "^10.0.0", "react-resizable-panels": "^2.1.7", - "recharts": "2.15.0", + "recharts": "^2.15.0", "sonner": "^1.7.4", "tailwind-merge": "^2.5.5", "tailwindcss-animate": "^1.0.7",