From b5c4f1d982dea2503b12e393302f555c075a48ca Mon Sep 17 00:00:00 2001 From: ViVaLaDaniel Date: Sun, 19 Apr 2026 20:20:52 +0200 Subject: [PATCH] feat: add group analytics dashboard with charts --- package.json | 2 + src/app/groups/[id]/page.tsx | 3 + src/components/GroupAnalytics.tsx | 129 ++++++++++++++++++++++++++++++ 3 files changed, 134 insertions(+) create mode 100644 src/components/GroupAnalytics.tsx diff --git a/package.json b/package.json index 7e788f6..1f19cf6 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,8 @@ "dependencies": { "@sorosave/sdk": "workspace:*", "@stellar/freighter-api": "^2.0.0", + "recharts": "^2.12.0", + "lucide-react": "^0.378.0", "next": "^14.2.0", "react": "^18.3.0", "react-dom": "^18.3.0" diff --git a/src/app/groups/[id]/page.tsx b/src/app/groups/[id]/page.tsx index 02ab880..007d5f5 100644 --- a/src/app/groups/[id]/page.tsx +++ b/src/app/groups/[id]/page.tsx @@ -3,6 +3,7 @@ import { Navbar } from "@/components/Navbar"; import { MemberList } from "@/components/MemberList"; import { RoundProgress } from "@/components/RoundProgress"; +import { GroupAnalytics } from "@/components/GroupAnalytics"; import { ContributeModal } from "@/components/ContributeModal"; import { useState } from "react"; import { formatAmount, GroupStatus } from "@sorosave/sdk"; @@ -62,6 +63,8 @@ export default function GroupDetailPage() { payoutOrder={group.payoutOrder} currentRound={group.currentRound} /> + +
diff --git a/src/components/GroupAnalytics.tsx b/src/components/GroupAnalytics.tsx new file mode 100644 index 0000000..f2355be --- /dev/null +++ b/src/components/GroupAnalytics.tsx @@ -0,0 +1,129 @@ +"use client"; + +import React from 'react'; +import { + LineChart, + Line, + PieChart, + Pie, + Cell, + XAxis, + YAxis, + CartesianGrid, + Tooltip, + ResponsiveContainer, + Legend, +} from 'recharts'; +import { TrendingUp, Users, DollarSign } from 'lucide-react'; + +const COLORS = ['#16a34a', '#22c55e', '#86efac', '#e5e7eb']; + +export function GroupAnalytics({ group }: { group: any }) { + // Mock data for analytics - in real app this would come from an API/Contract + const contributionData = [ + { round: 'Round 1', total: 5000, participation: 100 }, + { round: 'Round 2', total: 4500, participation: 90 }, + { round: 'Round 3', total: 5000, participation: 100 }, + { round: 'Round 4', total: 3000, participation: 60 }, + ]; + + const participationData = [ + { name: 'Paid', value: group.members.length * 0.8 }, + { name: 'Pending', value: group.members.length * 0.2 }, + ]; + + return ( +
+
+
+
+ + Growth +
+
+12.5%
+
Vs last cycle
+
+
+
+ + Active Members +
+
{group.members.length}
+
100% participation
+
+
+
+ + Total Pot +
+
15,400
+
XLM Vol.
+
+
+ +
+
+

+ Contribution History +

+
+ + + + + + + + + +
+
+ +
+

+ Participation Breakdown +

+
+ + + + {participationData.map((entry, index) => ( + + ))} + + + + + +
+
+
+
+ ); +}