From 4258d99c250d9c718eb7b49d56caf7a8788803f4 Mon Sep 17 00:00:00 2001 From: Alex Date: Mon, 13 Apr 2026 21:56:25 +0200 Subject: [PATCH] Add Human vs AI chart --- components/bar-chart.tsx | 87 ++++++++++------------------------------ components/wakatime.tsx | 71 ++++++++++++++++++++++++-------- 2 files changed, 75 insertions(+), 83 deletions(-) diff --git a/components/bar-chart.tsx b/components/bar-chart.tsx index d99e1a5..23170a4 100644 --- a/components/bar-chart.tsx +++ b/components/bar-chart.tsx @@ -1,20 +1,10 @@ "use client" -import { Bar, BarChart, LabelList, XAxis, YAxis, Cell } from "recharts"; -import { cn } from "@/lib/utils"; +import { Bar, BarChart, LabelList, XAxis, YAxis, Cell } from "recharts" +import { cn } from "@/lib/utils" +import { ChartContainer, type ChartConfig } from "@/components/ui/chart" -import { - ChartContainer, - type ChartConfig, -} from "@/components/ui/chart"; - -const COLORS = [ - "#4ade80", - "#60a5fa", - "#f87171", - "#fb923c", - "#c084fc", -] +const COLORS = ["#4ade80", "#60a5fa", "#f87171", "#fb923c", "#c084fc"] const chartConfig = { total_seconds: { @@ -33,8 +23,9 @@ interface MyBarChartProps { className?: string } -interface MyBarChartSkeletonProps { +interface MyBarChartStateProps { className?: string + bars?: number } export function MyBarChart({ data, className }: MyBarChartProps) { @@ -83,14 +74,11 @@ export function MyBarChart({ data, className }: MyBarChartProps) { ) } -export function MyBarChartSkeleton({ className }: MyBarChartSkeletonProps) { - const fakeData = [ - { language: "a", total_seconds: 102000 }, - { language: "b", total_seconds: 59000 }, - { language: "c", total_seconds: 41000 }, - { language: "d", total_seconds: 28000 }, - { language: "e", total_seconds: 17000 }, - ] +export function MyBarChartSkeleton({ className, bars = 5 }: MyBarChartStateProps) { + const fakeData = Array.from({ length: bars }).map((_, i) => ({ + language: String.fromCharCode(97 + i), + total_seconds: 100000 - i * 15000, + })) return ( - + - + ) } -export function MyBarChartError({ className }: MyBarChartSkeletonProps) { - const fakeData = [ - { language: "a", total_seconds: 102000 }, - { language: "b", total_seconds: 59000 }, - { language: "c", total_seconds: 41000 }, - { language: "d", total_seconds: 28000 }, - { language: "e", total_seconds: 17000 }, - ] +export function MyBarChartError({ className, bars = 5 }: MyBarChartStateProps) { + const fakeData = Array.from({ length: bars }).map((_, i) => ({ + language: String.fromCharCode(97 + i), + total_seconds: 100000 - i * 15000, + })) return (
- - + + - +
diff --git a/components/wakatime.tsx b/components/wakatime.tsx index ca19dbb..3046bcc 100644 --- a/components/wakatime.tsx +++ b/components/wakatime.tsx @@ -1,4 +1,4 @@ -import { MyBarChart, MyBarChartError } from "./bar-chart"; +import { MyBarChart, MyBarChartError, MyBarChartSkeleton } from "./bar-chart" type WakatimeLanguage = { name: string @@ -7,27 +7,64 @@ type WakatimeLanguage = { } export async function Wakatime({ className }: { className?: string }) { - const response = await fetch("https://wakatime.com/api/v1/users/alixz/stats/last_30_days", { - method: "GET", - headers: { - "Authorization": `Basic ${process.env.WAKATIME}` - }, - next: { revalidate: 3600 } - }); + const response = await fetch( + "https://wakatime.com/api/v1/users/alixz/stats/last_30_days", + { + method: "GET", + headers: { + Authorization: `Basic ${process.env.WAKATIME}`, + }, + next: { revalidate: 3600 }, + } + ) - if (!response.ok) return ; - - const res = await response.json(); - - if (!res?.data?.languages?.length) { - return ; + if (!response.ok) { + return ( +
+ +
+ +
+ ) } - const data = res.data.languages.slice(0, 5).map((lang: WakatimeLanguage) => ({ + const res = await response.json() + const stats = res?.data + + if (!stats?.languages?.length) { + return ( +
+ +
+ +
+ ) + } + + const languagesData = stats.languages.slice(0, 5).map((lang: WakatimeLanguage) => ({ language: lang.name, total_seconds: lang.total_seconds, label: `${lang.name} (${lang.text})`, - })); + })) - return ; + const additionsData = [ + { + language: "Human", + total_seconds: stats.human_additions, + label: `Human (${stats.human_additions.toLocaleString()} lines written)`, + }, + { + language: "AI", + total_seconds: stats.ai_additions, + label: `AI (${stats.ai_additions.toLocaleString()} lines written)`, + }, + ] + + return ( +
+ +
+ +
+ ) } \ No newline at end of file