Skip to content

Commit 4dc2f3b

Browse files
committed
Add Community Growth over Time
1 parent f30cfff commit 4dc2f3b

File tree

3 files changed

+69
-30
lines changed

3 files changed

+69
-30
lines changed

web/components/widgets/charts.tsx

Lines changed: 46 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,64 @@
1-
// ChartComponent.jsx
2-
import { useEffect, useState } from "react";
3-
import { LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer } from "recharts";
1+
import {useEffect, useState} from "react";
2+
import {CartesianGrid, Line, LineChart, ResponsiveContainer, Tooltip, XAxis, YAxis} from "recharts";
3+
import {getUserCreations} from "web/lib/supabase/users";
44

55
export default function ChartComponent() {
66
const [data, setData] = useState([]);
77

88
useEffect(() => {
99
async function loadData() {
1010
// Load some data from the backend API or Supabase
11-
// const res = await fetch("http://localhost:5000/api/data");
12-
// const json = await res.json();
13-
const json: any = [
14-
{ date: '2023-01-01', value: 400 },
15-
{ date: '2023-02-01', value: 300 },
16-
{ date: '2023-03-01', value: 500 },
17-
{ date: '2023-04-01', value: 200 },
18-
{ date: '2023-05-01', value: 600 },
19-
]
11+
const data = await getUserCreations()
12+
let counts: { [date: string]: number } = {}
13+
data.forEach((d) => {
14+
const date = new Date(d.created_time).toISOString().split('T')[0]
15+
counts[date] = (counts[date] || 0) + 1
16+
})
17+
const json: any = Object.entries(counts).map(([date, value]) => ({date, value}))
18+
let prev = 0
19+
for (let i = 0; i < json.length; i++) {
20+
json[i].value += prev
21+
prev = json[i].value
22+
}
23+
json.sort((a: any, b: any) => a.date.localeCompare(b.date))
24+
25+
// Example static data
26+
// const json: any = [
27+
// { date: '2023-01-01', value: 400 },
28+
// { date: '2023-02-01', value: 300 },
29+
// { date: '2023-03-01', value: 500 },
30+
// { date: '2023-04-01', value: 200 },
31+
// { date: '2023-05-01', value: 600 },
32+
// ]
2033
setData(json);
2134
}
35+
2236
loadData();
2337
}, []);
2438

2539
return (
2640
<ResponsiveContainer width="100%" height={400}>
2741
<LineChart data={data}>
28-
<CartesianGrid strokeDasharray="3 3" />
29-
<XAxis dataKey="date" />
30-
<YAxis />
31-
<Tooltip />
32-
<Line type="monotone" dataKey="value" stroke="#2563eb" strokeWidth={2} />
42+
<CartesianGrid strokeDasharray="3 3"/>
43+
<XAxis dataKey="date" label={{value: "Date", position: "insideBottomRight", offset: -5}}/>
44+
<YAxis label={{value: "Number of Members", angle: -90, position: "insideLeft"}}/>
45+
<Tooltip
46+
contentStyle={{
47+
backgroundColor: "rgb(var(--color-canvas-100))",
48+
border: "none",
49+
borderRadius: "8px",
50+
color: "rgb(var(--color-primary-900))",
51+
}}
52+
labelStyle={{
53+
color: "rgb(var(--color-primary-900))",
54+
}}
55+
/>
56+
<Line
57+
type="monotone"
58+
dataKey="value"
59+
stroke="rgb(var(--color-primary-900))"
60+
strokeWidth={2}
61+
/>
3362
</LineChart>
3463
</ResponsiveContainer>
3564
);

web/lib/supabase/users.ts

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1-
import { db } from './db'
2-
import { run } from 'common/supabase/utils'
3-
import { APIError, api } from 'web/lib/api'
4-
import { unauthedApi } from 'common/util/api'
5-
import type { DisplayUser } from 'common/api/user-types'
6-
export type { DisplayUser }
1+
import {db} from './db'
2+
import {run} from 'common/supabase/utils'
3+
import {APIError, api} from 'web/lib/api'
4+
import {unauthedApi} from 'common/util/api'
5+
import type {DisplayUser} from 'common/api/user-types'
6+
7+
export type {DisplayUser}
78

89
export async function getUserSafe(userId: string) {
910
try {
@@ -25,27 +26,27 @@ export async function getPrivateUserSafe() {
2526
}
2627

2728
export async function getUserById(id: string) {
28-
return unauthedApi('user/by-id/:id/lite', { id })
29+
return unauthedApi('user/by-id/:id/lite', {id})
2930
}
3031

3132
export async function getUserByUsername(username: string) {
32-
return unauthedApi('user/:username/lite', { username })
33+
return unauthedApi('user/:username/lite', {username})
3334
}
3435

3536
export async function getFullUserByUsername(username: string) {
36-
return unauthedApi('user/:username', { username })
37+
return unauthedApi('user/:username', {username})
3738
}
3839

3940
export async function getFullUserById(id: string) {
40-
return unauthedApi('user/by-id/:id', { id })
41+
return unauthedApi('user/by-id/:id', {id})
4142
}
4243

4344
export async function searchUsers(prompt: string, limit: number) {
44-
return unauthedApi('search-users', { term: prompt, limit: limit })
45+
return unauthedApi('search-users', {term: prompt, limit: limit})
4546
}
4647

4748
export async function getDisplayUsers(userIds: string[]) {
48-
const { data } = await run(
49+
const {data} = await run(
4950
db
5051
.from('users')
5152
.select(`id, name, username, data->avatarUrl, data->isBannedFromPosting`)
@@ -54,3 +55,12 @@ export async function getDisplayUsers(userIds: string[]) {
5455

5556
return data as unknown as DisplayUser[]
5657
}
58+
59+
export async function getUserCreations() {
60+
const {data} = await run(
61+
db.from('users')
62+
.select(`id, created_time`)
63+
.order('created_time')
64+
)
65+
return data
66+
}

web/pages/charts.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ export default function Charts() {
66
<LovePage
77
trackPageView={'charts'}
88
>
9-
<h1 className="text-3xl font-semibold text-center mb-6">An example of dynamic charts</h1>
9+
<h1 className="text-3xl font-semibold text-center mb-6">Community Growth over Time</h1>
1010
<ChartComponent/>
1111
</LovePage>
1212
);

0 commit comments

Comments
 (0)