Skip to content

Commit

Permalink
feat: SSG for analytic charts
Browse files Browse the repository at this point in the history
  • Loading branch information
daoleno committed Jan 16, 2024
1 parent bf9d763 commit 1bc94b6
Show file tree
Hide file tree
Showing 22 changed files with 234 additions and 97 deletions.
1 change: 1 addition & 0 deletions bq-syncer/.gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
service_account.json
*.db
.vscode
*.log
5 changes: 2 additions & 3 deletions dashboard/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,8 @@ Clone the project to your local machine.
```bash
git clone https://github.com/daoleno/lenscan
cd lenscan/dashboard

yarn install
yarn dev
bun install
bun dev
```

## Contributing
Expand Down
4 changes: 2 additions & 2 deletions dashboard/app/analytics/page.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import AllUserActivity from "@/components/charts/all-user-activity"
import ContentLanguageDistribution from "@/components/charts/content-language-distribution"
import DAU from "@/components/charts/dau"
import PopularHashtags from "@/components/charts/hashtags"
import MAU from "@/components/charts/mau"
import PublicationTypesDistribution from "@/components/charts/publication-types-distribution"
import UserActivity from "@/components/charts/user-activity"

export default function Page() {
return (
<div className="grid grid-cols-1 gap-4 p-7 md:grid-cols-2">
<DAU />
<MAU />
<UserActivity />
<AllUserActivity />
<PopularHashtags />
<PublicationTypesDistribution />
<ContentLanguageDistribution />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,20 @@ export type UserStats = {
total: number // Total count of active users
}

export async function getAllNetworkUserStats(
statType: "DAU" | "MAU" = "DAU"
): Promise<{ [key in DateRangeKey]?: UserStats[] }> {
const rangeKeys: DateRangeKey[] = ["1D", "1W", "1M", "3M", "1Y", "ALL"]
const allStats: { [key in DateRangeKey]?: UserStats[] } = {}

for (const rangeKey of rangeKeys) {
const userStatsForRange = await getNetworkUserStats(rangeKey, statType)
allStats[rangeKey] = userStatsForRange
}

return allStats
}

export async function getNetworkUserStats(
rangeKey: DateRangeKey,
statType: "DAU" | "MAU" = "DAU"
Expand Down Expand Up @@ -100,6 +114,20 @@ const topApps = [
"lenster",
]

export async function getAllAppUserStats(
statType: "DAU" | "MAU"
): Promise<{ [key in DateRangeKey]?: AppUserStats }> {
const rangeKeys: DateRangeKey[] = ["1D", "1W", "1M", "3M", "1Y", "ALL"]
const allStats: { [key in DateRangeKey]?: AppUserStats } = {}

for (const rangeKey of rangeKeys) {
const userStatsForRange = await getAppUserStats(rangeKey, statType)
allStats[rangeKey] = userStatsForRange
}

return allStats
}

export async function getAppUserStats(
rangeKey: DateRangeKey,
statType: "DAU" | "MAU"
Expand Down
2 changes: 1 addition & 1 deletion dashboard/app/api/analystics/active-users/route.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { NextRequest } from "next/server"

import { fetchData, getRangeKey } from "../utils"
import { getAppUserStats } from "./getDailyActiveUser"
import { getAppUserStats } from "./getActiveUserStats"

export const GET = (request: NextRequest) => {
const statType = request.nextUrl.searchParams.get("statType")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,19 @@ export type Hashtag = {
count: number
}

export async function getAllPopularHashtags(): Promise<{
[key in DateRangeKey]?: Hashtag[]
}> {
const rangeKeys: DateRangeKey[] = ["1D", "1W", "1M", "3M", "1Y", "ALL"]
const allPopularHashtags: { [key in DateRangeKey]?: Hashtag[] } = {}

for (const rangeKey of rangeKeys) {
allPopularHashtags[rangeKey] = await getPopularHashtags(rangeKey)
}

return allPopularHashtags
}

export async function getPopularHashtags(rangeKey: DateRangeKey = "ALL") {
let sql = `
SELECT hashtag, COUNT(*) AS count
Expand Down
20 changes: 17 additions & 3 deletions dashboard/app/api/analystics/user-activity/getUserActivity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import "server-only"

import { DateRangeKey, getDateRangeAndCondition } from "../utils"

export type UserActivity = {
export type UserActivityStats = {
day: string
posts: number
comments: number
Expand All @@ -13,7 +13,21 @@ export type UserActivity = {
downvotes: number
}

export async function getUserActivity(
export async function getAllUserActivity(): Promise<{
[key in DateRangeKey]?: UserActivityStats[]
}> {
const rangeKeys: DateRangeKey[] = ["1D", "1W", "1M", "3M", "1Y", "ALL"]
const allUserActivityStats: { [key in DateRangeKey]?: UserActivityStats[] } =
{}

for (const rangeKey of rangeKeys) {
allUserActivityStats[rangeKey] = await getUserActivityStats(rangeKey)
}

return allUserActivityStats
}

export async function getUserActivityStats(
rangeKey: DateRangeKey = "ALL",
profileId: string | null = null
) {
Expand Down Expand Up @@ -77,5 +91,5 @@ export async function getUserActivity(
a.day = new Date(a.day).toLocaleDateString()
})

return activities as UserActivity[]
return activities as UserActivityStats[]
}
4 changes: 2 additions & 2 deletions dashboard/app/api/analystics/user-activity/route.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { NextRequest } from "next/server"

import { fetchData, getRangeKey } from "../utils"
import { getUserActivity } from "./getUserActivity"
import { getUserActivityStats } from "./getUserActivity"

export const GET = (request: NextRequest) => {
const profileId = request.nextUrl.searchParams.get("profile_id") || null
return fetchData(getUserActivity, getRangeKey(request), profileId)
return fetchData(getUserActivityStats, getRangeKey(request), profileId)
}
2 changes: 1 addition & 1 deletion dashboard/app/apps/page.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import AppsSummary from "@/components/apps-summary"
import TopApps from "@/components/charts/top-apps"

export const revalidate = 60
export const revalidate = 60 * 60 * 5

export default function Page() {
return (
Expand Down
2 changes: 1 addition & 1 deletion dashboard/app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import DauStats from "@/components/dau-stats"
import Publications, { PublicationsProps } from "@/components/publications"
import StatCards from "@/components/stat-cards"

export const revalidate = 900
export const revalidate = 60 * 60 * 5

export default async function Home() {
const params: PublicationsProps = {
Expand Down
Binary file added dashboard/bun.lockb
Binary file not shown.
39 changes: 39 additions & 0 deletions dashboard/components/charts/active-user-stats.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
"use client"

import { useState } from "react"
import { BarChart } from "@tremor/react"

import { ChartCard } from "./chart-card"

interface ActiveUserStatsProps {
className?: string
title: string
allStats: any
}

export default function ActiveUserStats({
className,
title,
allStats,
}: ActiveUserStatsProps) {
const [range, setRange] = useState("ALL")
const data = allStats[range]

return (
<ChartCard
chartTitle={title}
range={range}
setRange={setRange}
className={className}
>
<BarChart
data={data?.stats}
index="time"
categories={data?.apps}
// showAnimation
showGridLines={false}
stack
/>
</ChartCard>
)
}
37 changes: 37 additions & 0 deletions dashboard/components/charts/all-user-activity-stats.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
"use client"

import { useState } from "react"
import { BarChart } from "@tremor/react"

import { ChartCard } from "./chart-card"

interface UserActivityProps {
className?: string
allStats: any
}

export default function AllUserActivityStats({
className,
allStats,
}: UserActivityProps) {
const [range, setRange] = useState("ALL")
const data = allStats[range]

return (
<ChartCard
chartTitle="Users Activity"
range={range}
setRange={setRange}
className={className}
>
<BarChart
data={data}
index="day"
categories={["posts", "comments", "mirrors", "upvotes", "downvotes"]}
// showAnimation
showGridLines={false}
stack
/>
</ChartCard>
)
}
17 changes: 17 additions & 0 deletions dashboard/components/charts/all-user-activity.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { getAllUserActivity } from "@/app/api/analystics/user-activity/getUserActivity"

import AllUserActivityStats from "./all-user-activity-stats"

interface UserActivityProps {
className?: string
}

export const revalidate = 60 * 60 * 5

export default async function AllUserActivity({
className,
}: UserActivityProps) {
const data = await getAllUserActivity()

return <AllUserActivityStats allStats={data} className={className} />
}
2 changes: 2 additions & 0 deletions dashboard/components/charts/content-language-distribution.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import { getContentLanguageDistribution } from "@/app/api/analystics/getContentL

import { ChartCard } from "./chart-card"

export const revalidate = 60 * 60 * 5

export default async function ContentLanguageDistribution() {
const data = await getContentLanguageDistribution()

Expand Down
39 changes: 10 additions & 29 deletions dashboard/components/charts/dau.tsx
Original file line number Diff line number Diff line change
@@ -1,40 +1,21 @@
"use client"
import { getAllAppUserStats } from "@/app/api/analystics/active-users/getActiveUserStats"

import { useState } from "react"
import { BarChart } from "@tremor/react"
import useSWR from "swr"
import ActiveUserStats from "./active-user-stats"

import fetcher from "@/lib/fetcher"

import { ChartCard } from "./chart-card"

interface UserActivityProps {
profileId?: string | null
interface DAUStaticProps {
className?: string
}

export default function DAU({ className }: UserActivityProps) {
const [range, setRange] = useState("ALL")
const queryString = `/api/analystics/active-users?range=${range}&statType=DAU`
const { data, error } = useSWR(queryString, fetcher)
export const revalidate = 60 * 60 * 5

console.log("data", data)
export default async function DAU({ className }: DAUStaticProps) {
const allStats = await getAllAppUserStats("DAU")

return (
<ChartCard
chartTitle="Daily Active Users"
range={range}
setRange={setRange}
<ActiveUserStats
title="Daily Active Users"
allStats={allStats}
className={className}
>
<BarChart
data={data?.stats}
index="time"
categories={data?.apps}
// showAnimation
showGridLines={false}
stack
/>
</ChartCard>
/>
)
}
22 changes: 22 additions & 0 deletions dashboard/components/charts/hashtags-stats.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
"use client"

import { useState } from "react"
import { BarChart } from "@tremor/react"

import { ChartCard } from "./chart-card"

export default function HashTagsStats({ allStats }: any) {
const [range, setRange] = useState("ALL")
const data = allStats[range]

return (
<ChartCard chartTitle="Popular Hashtags" range={range} setRange={setRange}>
<BarChart
data={data}
index="hashtag"
categories={["count"]}
showAnimation
/>
</ChartCard>
)
}
29 changes: 6 additions & 23 deletions dashboard/components/charts/hashtags.tsx
Original file line number Diff line number Diff line change
@@ -1,28 +1,11 @@
"use client"
import { getAllPopularHashtags } from "@/app/api/analystics/popular-hashtags/getPopularHashtags"

import { useState } from "react"
import { BarChart } from "@tremor/react"
import useSWR from "swr"
import HashTagsStats from "./hashtags-stats"

import fetcher from "@/lib/fetcher"
export const revalidate = 60 * 60 * 5

import { ChartCard } from "./chart-card"
export default async function HashTags() {
const allStats = await getAllPopularHashtags()

export default function HashTags() {
const [range, setRange] = useState("ALL")
const { data, error } = useSWR(
`/api/analystics/popular-hashtags?range=${range}`,
fetcher
)

return (
<ChartCard chartTitle="Popular Hashtags" range={range} setRange={setRange}>
<BarChart
data={data}
index="hashtag"
categories={["count"]}
showAnimation
/>
</ChartCard>
)
return <HashTagsStats allStats={allStats} />
}
Loading

0 comments on commit 1bc94b6

Please sign in to comment.