From 4dc2f3b9b9cb3a767487626d60652520d27cca39 Mon Sep 17 00:00:00 2001 From: MartinBraquet Date: Wed, 1 Oct 2025 08:56:03 +0200 Subject: [PATCH] Add Community Growth over Time --- web/components/widgets/charts.tsx | 63 ++++++++++++++++++++++--------- web/lib/supabase/users.ts | 34 +++++++++++------ web/pages/charts.tsx | 2 +- 3 files changed, 69 insertions(+), 30 deletions(-) diff --git a/web/components/widgets/charts.tsx b/web/components/widgets/charts.tsx index 386a3dc9..2465983d 100644 --- a/web/components/widgets/charts.tsx +++ b/web/components/widgets/charts.tsx @@ -1,6 +1,6 @@ -// ChartComponent.jsx -import { useEffect, useState } from "react"; -import { LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer } from "recharts"; +import {useEffect, useState} from "react"; +import {CartesianGrid, Line, LineChart, ResponsiveContainer, Tooltip, XAxis, YAxis} from "recharts"; +import {getUserCreations} from "web/lib/supabase/users"; export default function ChartComponent() { const [data, setData] = useState([]); @@ -8,28 +8,57 @@ export default function ChartComponent() { useEffect(() => { async function loadData() { // Load some data from the backend API or Supabase - // const res = await fetch("http://localhost:5000/api/data"); - // const json = await res.json(); - const json: any = [ - { date: '2023-01-01', value: 400 }, - { date: '2023-02-01', value: 300 }, - { date: '2023-03-01', value: 500 }, - { date: '2023-04-01', value: 200 }, - { date: '2023-05-01', value: 600 }, - ] + const data = await getUserCreations() + let counts: { [date: string]: number } = {} + data.forEach((d) => { + const date = new Date(d.created_time).toISOString().split('T')[0] + counts[date] = (counts[date] || 0) + 1 + }) + const json: any = Object.entries(counts).map(([date, value]) => ({date, value})) + let prev = 0 + for (let i = 0; i < json.length; i++) { + json[i].value += prev + prev = json[i].value + } + json.sort((a: any, b: any) => a.date.localeCompare(b.date)) + + // Example static data + // const json: any = [ + // { date: '2023-01-01', value: 400 }, + // { date: '2023-02-01', value: 300 }, + // { date: '2023-03-01', value: 500 }, + // { date: '2023-04-01', value: 200 }, + // { date: '2023-05-01', value: 600 }, + // ] setData(json); } + loadData(); }, []); return ( - - - - - + + + + + ); diff --git a/web/lib/supabase/users.ts b/web/lib/supabase/users.ts index b48797c6..54f93b6b 100644 --- a/web/lib/supabase/users.ts +++ b/web/lib/supabase/users.ts @@ -1,9 +1,10 @@ -import { db } from './db' -import { run } from 'common/supabase/utils' -import { APIError, api } from 'web/lib/api' -import { unauthedApi } from 'common/util/api' -import type { DisplayUser } from 'common/api/user-types' -export type { DisplayUser } +import {db} from './db' +import {run} from 'common/supabase/utils' +import {APIError, api} from 'web/lib/api' +import {unauthedApi} from 'common/util/api' +import type {DisplayUser} from 'common/api/user-types' + +export type {DisplayUser} export async function getUserSafe(userId: string) { try { @@ -25,27 +26,27 @@ export async function getPrivateUserSafe() { } export async function getUserById(id: string) { - return unauthedApi('user/by-id/:id/lite', { id }) + return unauthedApi('user/by-id/:id/lite', {id}) } export async function getUserByUsername(username: string) { - return unauthedApi('user/:username/lite', { username }) + return unauthedApi('user/:username/lite', {username}) } export async function getFullUserByUsername(username: string) { - return unauthedApi('user/:username', { username }) + return unauthedApi('user/:username', {username}) } export async function getFullUserById(id: string) { - return unauthedApi('user/by-id/:id', { id }) + return unauthedApi('user/by-id/:id', {id}) } export async function searchUsers(prompt: string, limit: number) { - return unauthedApi('search-users', { term: prompt, limit: limit }) + return unauthedApi('search-users', {term: prompt, limit: limit}) } export async function getDisplayUsers(userIds: string[]) { - const { data } = await run( + const {data} = await run( db .from('users') .select(`id, name, username, data->avatarUrl, data->isBannedFromPosting`) @@ -54,3 +55,12 @@ export async function getDisplayUsers(userIds: string[]) { return data as unknown as DisplayUser[] } + +export async function getUserCreations() { + const {data} = await run( + db.from('users') + .select(`id, created_time`) + .order('created_time') + ) + return data +} \ No newline at end of file diff --git a/web/pages/charts.tsx b/web/pages/charts.tsx index 092ee716..07240940 100644 --- a/web/pages/charts.tsx +++ b/web/pages/charts.tsx @@ -6,7 +6,7 @@ export default function Charts() { -

An example of dynamic charts

+

Community Growth over Time

);