Skip to content

Commit 2c105c5

Browse files
committed
refactor(dashboard): cleanup project overview page
1 parent 21de259 commit 2c105c5

File tree

3 files changed

+51
-119
lines changed

3 files changed

+51
-119
lines changed

apps/dashboard/src/app/team/[team_slug]/[project_slug]/components/ProjectOverviewHeader.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ export function ProjectOverviewHeader(props: {
1010
const { project, interval, range } = props;
1111

1212
return (
13-
<div className="container flex flex-col items-start gap-6 p-6 md:h-[120px] md:flex-row md:items-center md:py-0">
13+
<div className="container flex flex-col items-start gap-6 px-2 py-6 md:h-[120px] md:flex-row md:items-center md:p-6 md:py-0">
1414
<div className="flex-1">
1515
<h1 className="font-semibold text-3xl text-foreground">
1616
{project.name}

apps/dashboard/src/app/team/[team_slug]/[project_slug]/components/StatBreakdownCard.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ export function StatBreakdownCard({
128128
`[data-index^="${cardId}"]`,
129129
);
130130
for (const bar of bars) {
131-
bar.classList.add("opacity-40");
131+
bar.classList.remove("opacity-40");
132132
}
133133
}}
134134
>

apps/dashboard/src/app/team/[team_slug]/[project_slug]/page.tsx

Lines changed: 49 additions & 117 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import { notFound } from "next/navigation";
22

33
import { getProjects } from "@/api/projects";
4-
import { fetchAnalytics } from "data/analytics/fetch-analytics";
54
import { getThirdwebClient } from "@/constants/thirdweb.server";
5+
import { fetchAnalytics } from "data/analytics/fetch-analytics";
66

77
import type {
88
InAppWalletStats,
@@ -69,41 +69,25 @@ export default async function ProjectOverviewPage(props: PageProps) {
6969

7070
// Fetch all analytics data in parallel
7171
const [
72-
walletConnectionTimeSeries,
7372
walletConnections,
7473
walletUserStatsTimeSeries,
75-
walletUserStats,
7674
inAppWalletUsage,
7775
userOpUsage,
7876
] = await Promise.all([
79-
// Time series data for wallet connections
80-
getWalletConnections({
81-
clientId: "663baecef520df96d08766f37f4b40c0",
82-
from: range.from,
83-
to: range.to,
84-
period: interval,
85-
}),
8677
// Aggregated wallet connections
8778
getWalletConnections({
88-
clientId: "663baecef520df96d08766f37f4b40c0",
79+
clientId: params.project_slug,
8980
from: range.from,
9081
to: range.to,
9182
period: "all",
9283
}),
9384
// Time series data for wallet users
9485
getWalletUsers({
95-
clientId: "663baecef520df96d08766f37f4b40c0",
86+
clientId: params.project_slug,
9687
from: range.from,
9788
to: range.to,
9889
period: interval,
9990
}),
100-
// Aggregated wallet users
101-
getWalletUsers({
102-
clientId: "663baecef520df96d08766f37f4b40c0",
103-
from: range.from,
104-
to: range.to,
105-
period: "all",
106-
}),
10791
// In-app wallet usage
10892
getInAppWalletUsage({
10993
clientId: params.project_slug,
@@ -113,15 +97,15 @@ export default async function ProjectOverviewPage(props: PageProps) {
11397
}),
11498
// User operations usage
11599
getUserOpUsage({
116-
clientId: "f2512e0fb572e1bed2c3d1b64b2ea360",
100+
clientId: params.project_slug,
117101
from: range.from,
118102
to: range.to,
119103
period: "all",
120104
}),
121105
]);
122106

123107
const isEmpty =
124-
walletConnectionTimeSeries.length === 0 &&
108+
walletUserStatsTimeSeries.length === 0 &&
125109
walletConnections.length === 0 &&
126110
inAppWalletUsage.length === 0 &&
127111
userOpUsage.length === 0;
@@ -141,27 +125,35 @@ export default async function ProjectOverviewPage(props: PageProps) {
141125
</div>
142126
) : (
143127
<div className="space-y-6 md:container md:p-6">
144-
<div className="md:px-6">
145-
<UsersChartCard
146-
chartKey={
147-
(searchParams.usersChart as "totalUsers" | "uniqueUsers") ??
148-
"totalUsers"
149-
}
150-
walletStats={walletConnectionTimeSeries}
151-
userStats={walletUserStatsTimeSeries}
152-
aggregatedWalletStats={walletConnections}
153-
aggregatedUserStats={walletUserStats}
154-
searchParams={searchParams}
155-
/>
156-
</div>
157-
<div className="grid gap-6 px-6 md:grid-cols-2">
158-
<WalletDistributionCard data={walletConnections} />
159-
<AuthMethodDistributionCard data={inAppWalletUsage} />
160-
</div>
161-
<div className="grid gap-6 px-6 max-md:pb-6 md:grid-cols-2">
162-
<TotalSponsoredCard data={userOpUsage} />
163-
<UserOpUsageCard data={userOpUsage} />
128+
{walletUserStatsTimeSeries.length > 0 && (
129+
<div className="">
130+
<UsersChartCard
131+
chartKey={
132+
(searchParams.usersChart as
133+
| "totalUsers"
134+
| "activeUsers"
135+
| "newUsers"
136+
| "returningUsers") ?? "activeUsers"
137+
}
138+
userStats={walletUserStatsTimeSeries}
139+
searchParams={searchParams}
140+
/>
141+
</div>
142+
)}
143+
<div className="grid gap-6 max-md:px-6 md:grid-cols-2">
144+
{walletConnections.length > 0 && (
145+
<WalletDistributionCard data={walletConnections} />
146+
)}
147+
{inAppWalletUsage.length > 0 && (
148+
<AuthMethodDistributionCard data={inAppWalletUsage} />
149+
)}
164150
</div>
151+
{userOpUsage.length > 0 && (
152+
<div className="grid gap-6 max-md:px-6 max-md:pb-6 md:grid-cols-2">
153+
<TotalSponsoredCard data={userOpUsage} />
154+
<UserOpUsageCard data={userOpUsage} />
155+
</div>
156+
)}
165157
</div>
166158
)}
167159
</div>
@@ -170,7 +162,7 @@ export default async function ProjectOverviewPage(props: PageProps) {
170162

171163
type UserMetrics = {
172164
totalUsers: number;
173-
uniqueUsers: number;
165+
activeUsers: number;
174166
newUsers: number;
175167
returningUsers: number;
176168
};
@@ -184,100 +176,38 @@ type TimeSeriesMetrics = UserMetrics & {
184176
*/
185177
function processTimeSeriesData(
186178
userStats: WalletUserStats[],
187-
walletStats: WalletStats[],
188179
): TimeSeriesMetrics[] {
189180
const metrics: TimeSeriesMetrics[] = [];
190181

182+
let cumulativeUsers = 0;
191183
for (const stat of userStats) {
192-
// Get all wallet stats for this date
193-
const walletStatsForDate = walletStats.filter((s) => s.date === stat.date);
194-
195-
// Calculate total connections across all wallet types
196-
const totalConnections = walletStatsForDate.reduce(
197-
(sum, curr) => sum + curr.totalConnections,
198-
0,
199-
);
200-
201-
const existingMetric = metrics.find((m) => m.date === stat.date);
202-
203-
if (!existingMetric) {
204-
// Add new metrics entry
205-
metrics.push({
206-
date: stat.date,
207-
totalUsers: totalConnections,
208-
returningUsers: stat.returningUsers ?? 0,
209-
newUsers: stat.newUsers ?? 0,
210-
uniqueUsers: stat.totalUsers ?? 0,
211-
});
212-
} else {
213-
// Update existing metrics
214-
existingMetric.totalUsers += totalConnections;
215-
existingMetric.uniqueUsers += stat.totalUsers ?? 0;
216-
existingMetric.newUsers += stat.newUsers ?? 0;
217-
existingMetric.returningUsers += stat.returningUsers ?? 0;
218-
}
219-
}
220-
221-
return metrics;
222-
}
223-
224-
/**
225-
* Aggregates total metrics across all time periods
226-
*/
227-
function calculateAggregatedMetrics(
228-
aggregatedUserStats: WalletUserStats[],
229-
aggregatedWalletStats: WalletStats[],
230-
): UserMetrics {
231-
const metrics: UserMetrics = {
232-
totalUsers: 0,
233-
uniqueUsers: 0,
234-
newUsers: 0,
235-
returningUsers: 0,
236-
};
237-
238-
for (const stat of aggregatedUserStats) {
239-
// Get all wallet stats for this date
240-
const walletStatsForDate = aggregatedWalletStats.filter(
241-
(s) => s.date === stat.date,
242-
);
243-
244-
// Add up metrics
245-
metrics.totalUsers += walletStatsForDate.reduce(
246-
(sum, curr) => sum + curr.totalConnections,
247-
0,
248-
);
249-
metrics.uniqueUsers += stat.totalUsers ?? 0;
250-
metrics.newUsers += stat.newUsers ?? 0;
251-
metrics.returningUsers += stat.returningUsers ?? 0;
184+
cumulativeUsers += stat.totalUsers ?? 0;
185+
metrics.push({
186+
date: stat.date,
187+
activeUsers: stat.totalUsers ?? 0,
188+
returningUsers: stat.returningUsers ?? 0,
189+
newUsers: stat.newUsers ?? 0,
190+
totalUsers: cumulativeUsers,
191+
});
252192
}
253193

254194
return metrics;
255195
}
256196

257197
function UsersChartCard({
258198
chartKey,
259-
walletStats,
260199
userStats,
261-
aggregatedWalletStats,
262-
aggregatedUserStats,
263200
searchParams,
264201
}: {
265202
chartKey: keyof UserMetrics;
266-
walletStats: WalletStats[];
267203
userStats: WalletUserStats[];
268-
aggregatedWalletStats: WalletStats[];
269-
aggregatedUserStats: WalletUserStats[];
270204
searchParams?: { [key: string]: string | string[] | undefined };
271205
}) {
272-
const timeSeriesData = processTimeSeriesData(userStats, walletStats);
273-
const aggregatedData = calculateAggregatedMetrics(
274-
aggregatedUserStats,
275-
aggregatedWalletStats,
276-
);
206+
const timeSeriesData = processTimeSeriesData(userStats);
277207

278208
const chartConfig = {
279-
totalUsers: { label: "Total Users", color: "hsl(var(--chart-1))" },
280-
uniqueUsers: { label: "Unique Users", color: "hsl(var(--chart-2))" },
209+
activeUsers: { label: "Active Users", color: "hsl(var(--chart-1))" },
210+
totalUsers: { label: "Total Users", color: "hsl(var(--chart-2))" },
281211
newUsers: { label: "New Users", color: "hsl(var(--chart-3))" },
282212
returningUsers: {
283213
label: "Returning Users",
@@ -291,7 +221,9 @@ function UsersChartCard({
291221
chartConfig={chartConfig}
292222
activeChart={chartKey}
293223
data={timeSeriesData}
294-
aggregateFn={(_data, key) => aggregatedData[key]}
224+
aggregateFn={(_data, key) =>
225+
timeSeriesData[timeSeriesData.length - 1]?.[key]
226+
}
295227
existingQueryParams={searchParams}
296228
/>
297229
);

0 commit comments

Comments
 (0)