1+ import { type Project , getProject } from "@/api/projects" ;
2+ import { GenericLoadingPage } from "@/components/blocks/skeletons/GenericLoadingPage" ;
13import { notFound } from "next/navigation" ;
24
3- import { getProject } from "@/api/projects" ;
4-
55import {
66 type DurationId ,
77 type Range ,
@@ -22,6 +22,7 @@ import {
2222 isProjectActive ,
2323} from "@/api/analytics" ;
2424import { EmptyStateCard } from "app/team/components/Analytics/EmptyStateCard" ;
25+ import { Suspense } from "react" ;
2526import {
2627 type ChainMetadata ,
2728 defineChain ,
@@ -69,6 +70,43 @@ export default async function ProjectOverviewPage(props: PageProps) {
6970
7071 const isActive = await isProjectActive ( { clientId : project . publishableKey } ) ;
7172
73+ return (
74+ < div className = "flex grow flex-col" >
75+ < div className = "w-full border-border border-b" >
76+ < AnalyticsHeader
77+ title = { project . name }
78+ interval = { interval }
79+ range = { range }
80+ />
81+ </ div >
82+ { ! isActive ? (
83+ < div className = "container p-6" >
84+ < EmptyState />
85+ </ div >
86+ ) : (
87+ < div className = "container flex grow flex-col py-6" >
88+ < Suspense fallback = { < GenericLoadingPage /> } >
89+ < ProjectAnalytics
90+ project = { project }
91+ range = { range }
92+ interval = { interval }
93+ searchParams = { searchParams }
94+ />
95+ </ Suspense >
96+ </ div >
97+ ) }
98+ </ div >
99+ ) ;
100+ }
101+
102+ async function ProjectAnalytics ( props : {
103+ project : Project ;
104+ range : Range ;
105+ interval : "day" | "week" ;
106+ searchParams : PageSearchParams ;
107+ } ) {
108+ const { project, range, interval, searchParams } = props ;
109+
72110 // Fetch all analytics data in parallel
73111 const [
74112 walletConnections ,
@@ -114,79 +152,64 @@ export default async function ProjectOverviewPage(props: PageProps) {
114152 ] ) ;
115153
116154 return (
117- < div className = "md:pb-16" >
118- < div className = "w-full border-border-800 border-b px-6 dark:bg-muted/50" >
119- < AnalyticsHeader
120- title = { project . name }
121- interval = { interval }
122- range = { range }
123- />
124- </ div >
125- { ! isActive ? (
126- < div className = "container p-6" >
127- < EmptyState />
155+ < div className = "flex grow flex-col gap-6" >
156+ { walletUserStatsTimeSeries . some ( ( w ) => w . totalUsers !== 0 ) ? (
157+ < div className = "" >
158+ < UsersChartCard
159+ chartKey = {
160+ ( searchParams . usersChart as
161+ | "totalUsers"
162+ | "activeUsers"
163+ | "newUsers"
164+ | "returningUsers" ) ?? "activeUsers"
165+ }
166+ userStats = { walletUserStatsTimeSeries }
167+ searchParams = { searchParams }
168+ />
128169 </ div >
129170 ) : (
130- < div className = "space-y-6 md:container md:p-6" >
131- { walletUserStatsTimeSeries . some ( ( w ) => w . totalUsers !== 0 ) ? (
132- < div className = "" >
133- < UsersChartCard
134- chartKey = {
135- ( searchParams . usersChart as
136- | "totalUsers"
137- | "activeUsers"
138- | "newUsers"
139- | "returningUsers" ) ?? "activeUsers"
140- }
141- userStats = { walletUserStatsTimeSeries }
142- searchParams = { searchParams }
143- />
144- </ div >
145- ) : (
146- < EmptyStateCard
147- metric = "Connect"
148- link = "https://portal.thirdweb.com/connect/quickstart"
149- />
150- ) }
151- < RpcMethodBarChartCard
152- from = { range . from }
153- to = { range . to }
154- period = { interval }
155- clientId = { project . publishableKey }
171+ < EmptyStateCard
172+ metric = "Connect"
173+ link = "https://portal.thirdweb.com/connect/quickstart"
174+ />
175+ ) }
176+ < RpcMethodBarChartCard
177+ from = { range . from }
178+ to = { range . to }
179+ period = { interval }
180+ clientId = { project . publishableKey }
181+ />
182+ < div className = "grid gap-6 max-md:px-6 md:grid-cols-2" >
183+ { walletConnections . length > 0 ? (
184+ < WalletDistributionCard data = { walletConnections } />
185+ ) : (
186+ < EmptyStateCard
187+ metric = "Connect"
188+ link = "https://portal.thirdweb.com/connect/quickstart"
189+ />
190+ ) }
191+ { inAppWalletUsage . length > 0 ? (
192+ < AuthMethodDistributionCard data = { inAppWalletUsage } />
193+ ) : (
194+ < EmptyStateCard
195+ metric = "In-App Wallets"
196+ link = "https://portal.thirdweb.com/typescript/v5/inAppWallet"
197+ />
198+ ) }
199+ </ div >
200+ { userOpUsage . length > 0 ? (
201+ < div className = "" >
202+ < TotalSponsoredCard
203+ searchParams = { searchParams }
204+ data = { userOpUsageTimeSeries }
205+ aggregatedData = { userOpUsage }
156206 />
157- < div className = "grid gap-6 max-md:px-6 md:grid-cols-2" >
158- { walletConnections . length > 0 ? (
159- < WalletDistributionCard data = { walletConnections } />
160- ) : (
161- < EmptyStateCard
162- metric = "Connect"
163- link = "https://portal.thirdweb.com/connect/quickstart"
164- />
165- ) }
166- { inAppWalletUsage . length > 0 ? (
167- < AuthMethodDistributionCard data = { inAppWalletUsage } />
168- ) : (
169- < EmptyStateCard
170- metric = "In-App Wallets"
171- link = "https://portal.thirdweb.com/typescript/v5/inAppWallet"
172- />
173- ) }
174- </ div >
175- { userOpUsage . length > 0 ? (
176- < div className = "" >
177- < TotalSponsoredCard
178- searchParams = { searchParams }
179- data = { userOpUsageTimeSeries }
180- aggregatedData = { userOpUsage }
181- />
182- </ div >
183- ) : (
184- < EmptyStateCard
185- metric = "Sponsored Transactions"
186- link = "https://portal.thirdweb.com/typescript/v5/account-abstraction/get-started"
187- />
188- ) }
189207 </ div >
208+ ) : (
209+ < EmptyStateCard
210+ metric = "Sponsored Transactions"
211+ link = "https://portal.thirdweb.com/typescript/v5/account-abstraction/get-started"
212+ />
190213 ) }
191214 </ div >
192215 ) ;
0 commit comments