From ecf597d0720eb4d33e8e29d92c1479e0f1ee8991 Mon Sep 17 00:00:00 2001 From: highperfocused Date: Sun, 28 Dec 2025 14:24:40 +0100 Subject: [PATCH] feat: refactor EventKindsChart to use current user context and update chart colors --- src/components/dashboard/EventKindsChart.tsx | 246 +++++++++++++------ src/index.css | 12 + src/pages/Dashboard.tsx | 2 +- 3 files changed, 182 insertions(+), 78 deletions(-) diff --git a/src/components/dashboard/EventKindsChart.tsx b/src/components/dashboard/EventKindsChart.tsx index 40cc2a7..784dc0f 100644 --- a/src/components/dashboard/EventKindsChart.tsx +++ b/src/components/dashboard/EventKindsChart.tsx @@ -1,99 +1,191 @@ -import { Card, CardContent, CardHeader, CardTitle, CardDescription } from '@/components/ui/card'; -import { ChartContainer, ChartTooltip, ChartTooltipContent } from '@/components/ui/chart'; -import { Bar, BarChart, CartesianGrid, XAxis, YAxis } from 'recharts'; -import { useUserStats } from '@/hooks/useUserStats'; -import { Skeleton } from '@/components/ui/skeleton'; +"use client" -interface EventKindsChartProps { - pubkey: string; +import { TrendingUp } from "lucide-react" +import { Pie, PieChart } from "recharts" +import { useMemo } from "react" + +import { + Card, + CardContent, + CardDescription, + CardFooter, + CardHeader, + CardTitle, +} from "@/components/ui/card" +import { + ChartContainer, + ChartTooltip, + ChartTooltipContent, + type ChartConfig, +} from "@/components/ui/chart" +import { Skeleton } from "@/components/ui/skeleton" +import { useCurrentUser } from "@/hooks/useCurrentUser" +import { useUserStats } from "@/hooks/useUserStats" + +export const description = "Distribution of event kinds for the logged-in user" + +// Common Nostr event kind labels +const kindLabels: Record = { + 0: "Metadata", + 1: "Note", + 3: "Contacts", + 4: "DM (Encrypted)", + 5: "Delete", + 6: "Repost", + 7: "Reaction", + 16: "Generic Repost", + 40: "Channel Create", + 41: "Channel Metadata", + 42: "Channel Message", + 43: "Channel Hide", + 44: "Channel Mute", + 1984: "Report", + 9734: "Zap Request", + 9735: "Zap", + 10002: "Relay List", + 30023: "Long-form", + 30311: "Live Event", } -// Map of common kind numbers to their names -const kindNames: Record = { - 0: 'Metadata', - 1: 'Text Note', - 3: 'Contacts', - 4: 'DM', - 5: 'Deletion', - 6: 'Repost', - 7: 'Reaction', - 9735: 'Zap', - 10002: 'Relay List', - 30023: 'Article', -}; +const chartColors = [ + "var(--chart-1)", + "var(--chart-2)", + "var(--chart-3)", + "var(--chart-4)", + "var(--chart-5)", +] -export function EventKindsChart({ pubkey }: EventKindsChartProps) { - const { data: stats, isLoading } = useUserStats(pubkey); +export function EventKindsChart() { + const { user } = useCurrentUser() + const { data: stats, isLoading } = useUserStats(user?.pubkey) + + const { chartData, chartConfig, topKind } = useMemo(() => { + if (!stats || !stats.eventsByKind) { + return { chartData: [], chartConfig: {}, topKind: null } + } + + // Sort event kinds by count and take top 5 + const sortedKinds = Object.entries(stats.eventsByKind) + .sort(([, a], [, b]) => b - a) + .slice(0, 5) + + // Calculate total for percentage + const total = sortedKinds.reduce((sum, [, count]) => sum + count, 0) + + // Generate chart data + const data = sortedKinds.map(([kind, count], index) => ({ + kind: `kind${kind}`, + kindNumber: parseInt(kind), + label: kindLabels[parseInt(kind)] || `Kind ${kind}`, + count, + fill: chartColors[index % chartColors.length], + })) + + // Generate chart config + const config: ChartConfig = { + count: { + label: "Events", + }, + ...Object.fromEntries( + data.map((item) => [ + item.kind, + { + label: item.label, + color: item.fill, + }, + ]) + ), + } + + // Find top kind + const top = sortedKinds[0] ? { + kind: parseInt(sortedKinds[0][0]), + count: sortedKinds[0][1], + percentage: total > 0 ? ((sortedKinds[0][1] / total) * 100).toFixed(1) : "0", + } : null + + return { chartData: data, chartConfig: config, topKind: top } + }, [stats]) if (isLoading) { return ( - - - - + + + + - - - - - ); - } - - if (!stats || Object.keys(stats.eventsByKind).length === 0) { - return ( - - - Event Distribution - Events published by kind - - -
- No events found + +
+
+ + + + - ); + ) } - // Transform data for chart - const chartData = Object.entries(stats.eventsByKind) - .sort(([, a], [, b]) => b - a) - .slice(0, 10) // Top 10 kinds - .map(([kind, count]) => ({ - kind: kindNames[Number(kind)] || `Kind ${kind}`, - count, - })); + if (!user) { + return ( + + + Event Kinds Distribution + Log in to see your event distribution + + +

Please log in to view your stats

+
+
+ ) + } - const chartConfig = { - count: { - label: 'Events', - color: 'hsl(var(--chart-1))', - }, - }; + if (!stats || chartData.length === 0) { + return ( + + + Event Kinds Distribution + Your published event types + + +

No events found

+
+
+ ) + } return ( - - - Event Distribution - Top event types you've published + + + Event Kinds Distribution + Your top 5 event types - - - - - + + + } /> - - } /> - - + + + + {topKind && ( +
+ {kindLabels[topKind.kind] || `Kind ${topKind.kind}`} is your most common event ({topKind.percentage}%) + +
+ )} +
+ Showing distribution of your last {stats.totalEvents} events +
+
- ); + ) } diff --git a/src/index.css b/src/index.css index 33fdf9d..745eecf 100644 --- a/src/index.css +++ b/src/index.css @@ -49,6 +49,12 @@ --sidebar-border: 220 13% 91%; --sidebar-ring: 217.2 91.2% 59.8%; + + --chart-1: oklch(0.646 0.222 41.116); + --chart-2: oklch(0.6 0.118 184.704); + --chart-3: oklch(0.398 0.07 227.392); + --chart-4: oklch(0.828 0.189 84.429); + --chart-5: oklch(0.769 0.188 70.08); } .dark { @@ -87,6 +93,12 @@ --sidebar-accent-foreground: 240 4.8% 95.9%; --sidebar-border: 240 3.7% 15.9%; --sidebar-ring: 217.2 91.2% 59.8%; + + --chart-1: oklch(0.488 0.243 264.376); + --chart-2: oklch(0.696 0.17 162.48); + --chart-3: oklch(0.769 0.188 70.08); + --chart-4: oklch(0.627 0.265 303.9); + --chart-5: oklch(0.645 0.246 16.439); } } diff --git a/src/pages/Dashboard.tsx b/src/pages/Dashboard.tsx index 056f3a7..ad5093d 100644 --- a/src/pages/Dashboard.tsx +++ b/src/pages/Dashboard.tsx @@ -49,7 +49,7 @@ export function Dashboard() {
- +