)
}
-function StatCard({ label, value, sub }: { label: string; value: string; sub?: string }) {
- return (
-
- )
-}
-
export default function StoreViewPage() {
const { id } = useParams<{ id: string }>()
const router = useRouter()
@@ -66,7 +50,6 @@ export default function StoreViewPage() {
const routeName = store ? routesList.find((r) => r.id === store.routeId)?.routeName : undefined
- const availableCredit = store ? store.creditLimit - store.outstandingBalance : 0
return (
@@ -103,73 +86,26 @@ export default function StoreViewPage() {
-
- {/* Left — store details */}
-
-
- {store.ownerName ?? "—"}
- {store.contactNumber ?? "—"}
- {store.storeAddress}
-
- {routeName ?? {store.routeId}}
-
- {store.segment && (
- {store.segment}
- )}
- {fmtMoney(store.creditLimit)}
- {fmtDate(store.createdAt)}
-
-
-
- {/* Right — credit stats + map */}
-
-
-
-
-
-
-
-
+
+
+ {store.ownerName ?? '—'}
+ {store.contactNumber ?? '—'}
+
+ {routeName ?? {store.routeId}}
+
+ {store.storeAddress}
+ {store.segment ?? '—'}
+ {fmtDate(store.createdAt)}
)}
+
+ {/* Shop analytics */}
+ {!loading && store &&
}
)
}
diff --git a/distribution_fe/app/(dashboard)/stores/_components/store-analytics.tsx b/distribution_fe/app/(dashboard)/stores/_components/store-analytics.tsx
new file mode 100644
index 0000000..41b5fb0
--- /dev/null
+++ b/distribution_fe/app/(dashboard)/stores/_components/store-analytics.tsx
@@ -0,0 +1,403 @@
+'use client'
+
+import { useEffect, useState } from 'react'
+import {
+ Area,
+ AreaChart,
+ Bar,
+ BarChart,
+ CartesianGrid,
+ Cell,
+ Label,
+ Line,
+ LineChart,
+ PolarAngleAxis,
+ Pie,
+ PieChart,
+ RadialBar,
+ RadialBarChart,
+ XAxis,
+ YAxis,
+} from 'recharts'
+import { Badge } from '@/components/ui/badge'
+import { Skeleton } from '@/components/ui/skeleton'
+import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'
+import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'
+import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table'
+import {
+ ChartContainer,
+ ChartLegend,
+ ChartLegendContent,
+ ChartTooltip,
+ ChartTooltipContent,
+ type ChartConfig,
+} from '@/components/ui/chart'
+import { toast } from '@/components/ui/toast'
+import { stores as storesApi, getApiError } from '@/lib/api/index'
+import type { StoreAnalyticsResponse } from '@/types/api'
+
+const fmtMoney = (v: number) =>
+ `Rs. ${v.toLocaleString('en-LK', { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`
+
+const fmtCompact = (v: number) =>
+ v.toLocaleString('en-LK', { notation: 'compact', maximumFractionDigits: 1 })
+
+const fmtDate = (v: string) =>
+ new Date(v).toLocaleDateString('en-GB', { day: '2-digit', month: 'short', year: 'numeric' })
+
+const fmtMonth = (v: string) =>
+ new Date(`${v}-01`).toLocaleDateString('en-GB', { month: 'short', year: '2-digit' })
+
+const daysAgo = (v: string) => {
+ const d = Math.floor((Date.now() - new Date(v).getTime()) / 86_400_000)
+ return d <= 0 ? 'Today' : d === 1 ? '1 day ago' : `${d} days ago`
+}
+
+const salesConfig = {
+ invoiced: { label: 'Invoiced', color: 'var(--chart-2)' },
+ collected: { label: 'Collected', color: 'var(--chart-4)' },
+} satisfies ChartConfig
+
+const trendConfig = {
+ invoiced: { label: "Invoiced", color: "var(--chart-2)" },
+ outstanding: { label: "Outstanding", color: "var(--destructive)" },
+} satisfies ChartConfig
+
+const creditConfig = {
+ used: { label: 'Credit used', color: 'var(--chart-2)' },
+} satisfies ChartConfig
+
+const AGEING_FILL: Record
= {
+ 'Current': { color: 'var(--chart-2)', opacity: 1 },
+ '1-30': { color: 'var(--destructive)', opacity: 0.45 },
+ '31-60': { color: 'var(--destructive)', opacity: 0.65 },
+ '61-90': { color: 'var(--destructive)', opacity: 0.85 },
+ '90+': { color: 'var(--destructive)', opacity: 1 },
+}
+
+const PRODUCT_COLORS = ['var(--chart-1)', 'var(--chart-2)', 'var(--chart-3)', 'var(--chart-4)', 'var(--chart-5)', 'var(--muted-foreground)']
+
+function DonutCenter({ title, value }: { title: string; value: string }) {
+ return (
+