Skip to content

Commit 0e630c4

Browse files
committed
[MNY-304] Move engine tx summary request to client side to fix page crash (#8379)
<!-- ## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes" If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000): ## Notes for the reviewer Anything important to call out? Be sure to also clarify these in your comments. ## How to test Unit tests, playground, etc. --> <!-- start pr-codex --> --- ## PR-Codex overview This PR focuses on refactoring the transaction analytics feature by updating data fetching methods, improving UI components, and enhancing error handling for transaction summaries and charts. ### Detailed summary - Removed outdated files: `utils.ts` and `filter.tsx`. - Updated import paths for `TransactionSummaryData`. - Changed UI text in `tx-chart-ui.tsx` for clarity. - Enhanced error handling in data fetching functions. - Introduced `getTransactionsChartData` and `getTransactionAnalyticsSummary` for improved data management. - Refactored `TransactionsAnalyticsPageContent` to streamline data flow and UI rendering. - Added new components for date and interval selection in transaction charts. > ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}` <!-- end pr-codex --> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Refactor** * Analytics now load client-side with a spinner and a streamlined layout; analytics sections only show when transactions exist. * **New Features** * Direct date-range and interval controls in the analytics view. * Unified analytics summary and charts presented above the transactions table. * Chart header updated to "Transactions" with revised description. * **Chores** * Removed URL-synced filter behavior; filters are local. * Empty-chart messaging changed to "No transactions found." <!-- end of auto-generated comment: release notes by coderabbit.ai -->
1 parent 11c7bf0 commit 0e630c4

File tree

10 files changed

+298
-341
lines changed

10 files changed

+298
-341
lines changed
Lines changed: 81 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,95 @@
1-
import { ResponsiveSearchParamsProvider } from "responsive-rsc";
1+
"use client";
2+
import { useQuery } from "@tanstack/react-query";
3+
import { Spinner } from "@workspace/ui/components/spinner";
24
import type { ThirdwebClient } from "thirdweb";
35
import type { Project } from "@/api/project/projects";
46
import { UnifiedTransactionsTable } from "../components/transactions-table.client";
7+
import { getTransactionAnalyticsSummary } from "../lib/analytics-summary.client";
58
import type { Wallet } from "../server-wallets/wallet-table/types";
6-
import { TransactionAnalyticsFilter } from "./filter";
7-
import { TransactionsChartCard } from "./tx-chart/tx-chart";
9+
import type { SolanaWallet } from "../solana-wallets/wallet-table/types";
10+
import { EngineChecklist } from "./ftux.client";
11+
import { TransactionAnalyticsSummary } from "./summary";
12+
import { TransactionsAnalytics } from "./tx-chart/tx-chart";
813

914
export function TransactionsAnalyticsPageContent(props: {
10-
searchParams: {
11-
from?: string | undefined | string[];
12-
to?: string | undefined | string[];
13-
interval?: string | undefined | string[];
14-
};
1515
project: Project;
1616
showAnalytics: boolean;
17-
wallets?: Wallet[];
17+
wallets: Wallet[];
1818
teamSlug: string;
1919
client: ThirdwebClient;
20+
authToken: string;
21+
teamId: string;
22+
isManagedVault: boolean;
23+
testTxWithWallet: string | undefined;
24+
testSolanaTxWithWallet: string | undefined;
25+
solanaWallets: SolanaWallet[];
2026
}) {
21-
return (
22-
<ResponsiveSearchParamsProvider value={props.searchParams}>
23-
<div className="flex grow flex-col gap-6">
24-
{props.showAnalytics && (
25-
<>
26-
<div className="flex justify-end">
27-
<TransactionAnalyticsFilter />
28-
</div>
29-
<TransactionsChartCard
30-
project={props.project}
31-
searchParams={props.searchParams}
32-
teamSlug={props.teamSlug}
33-
wallets={props.wallets ?? []}
34-
/>
35-
</>
36-
)}
37-
<UnifiedTransactionsTable
38-
client={props.client}
39-
project={props.project}
40-
teamSlug={props.teamSlug}
41-
/>
27+
const engineTxSummaryQuery = useQuery({
28+
queryKey: [
29+
"engine-tx-analytics-summary",
30+
props.teamId,
31+
props.project.publishableKey,
32+
props.authToken,
33+
],
34+
queryFn: async () => {
35+
const data = await getTransactionAnalyticsSummary({
36+
clientId: props.project.publishableKey,
37+
teamId: props.teamId,
38+
authToken: props.authToken,
39+
});
40+
return data;
41+
},
42+
refetchOnWindowFocus: false,
43+
refetchOnMount: false,
44+
});
45+
46+
if (engineTxSummaryQuery.isPending) {
47+
return (
48+
<div className="flex h-[642px] grow items-center justify-center bg-card rounded-xl border">
49+
<Spinner className="size-10" />
4250
</div>
43-
</ResponsiveSearchParamsProvider>
51+
);
52+
}
53+
54+
const hasTransactions = engineTxSummaryQuery.data
55+
? engineTxSummaryQuery.data.totalCount > 0
56+
: false;
57+
58+
return (
59+
<div className="flex grow flex-col gap-10">
60+
<EngineChecklist
61+
isManagedVault={props.isManagedVault}
62+
client={props.client}
63+
hasTransactions={hasTransactions}
64+
project={props.project}
65+
teamSlug={props.teamSlug}
66+
testTxWithWallet={props.testTxWithWallet}
67+
testSolanaTxWithWallet={props.testSolanaTxWithWallet}
68+
wallets={props.wallets}
69+
solanaWallets={props.solanaWallets}
70+
/>
71+
72+
{props.showAnalytics && hasTransactions && (
73+
<div className="flex flex-col gap-6">
74+
<TransactionAnalyticsSummary
75+
clientId={props.project.publishableKey}
76+
teamId={props.project.teamId}
77+
initialData={engineTxSummaryQuery.data}
78+
/>
79+
<TransactionsAnalytics
80+
project={props.project}
81+
authToken={props.authToken}
82+
teamSlug={props.teamSlug}
83+
wallets={props.wallets ?? []}
84+
/>
85+
</div>
86+
)}
87+
88+
<UnifiedTransactionsTable
89+
client={props.client}
90+
project={props.project}
91+
teamSlug={props.teamSlug}
92+
/>
93+
</div>
4494
);
4595
}

apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/transactions/analytics/filter.tsx

Lines changed: 0 additions & 51 deletions
This file was deleted.

apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/transactions/analytics/summary.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { ActivityIcon, CoinsIcon } from "lucide-react";
22
import { toEther } from "thirdweb/utils";
33
import { StatCard } from "@/components/analytics/stat"; // Assuming correct path
4-
import type { TransactionSummaryData } from "../lib/analytics";
4+
import type { TransactionSummaryData } from "../lib/analytics-summary.client";
55

66
// Renders the UI based on fetched data or pending state
77
function TransactionAnalyticsSummaryUI(props: {
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
"use client";
2+
import { NEXT_PUBLIC_ENGINE_CLOUD_URL } from "@/constants/public-envs";
3+
import type { TransactionStats } from "@/types/analytics";
4+
5+
export async function getTransactionsChartData({
6+
teamId,
7+
clientId,
8+
from,
9+
to,
10+
interval,
11+
authToken,
12+
}: {
13+
teamId: string;
14+
clientId: string;
15+
from: string;
16+
to: string;
17+
interval: "day" | "week";
18+
authToken: string;
19+
}): Promise<TransactionStats[]> {
20+
const filters = {
21+
endDate: to,
22+
resolution: interval,
23+
startDate: from,
24+
};
25+
26+
const response = await fetch(
27+
`${NEXT_PUBLIC_ENGINE_CLOUD_URL}/v1/transactions/analytics`,
28+
{
29+
body: JSON.stringify(filters),
30+
headers: {
31+
Authorization: `Bearer ${authToken}`,
32+
"Content-Type": "application/json",
33+
"x-client-id": clientId,
34+
"x-team-id": teamId,
35+
},
36+
method: "POST",
37+
},
38+
);
39+
40+
if (!response.ok) {
41+
if (response.status === 401 || response.status === 400) {
42+
return [];
43+
}
44+
45+
// TODO - need to handle this error state, like we do with the connect charts
46+
throw new Error(
47+
`Error fetching transactions chart data: ${response.status} ${
48+
response.statusText
49+
} - ${await response.text().catch(() => "Unknown error")}`,
50+
);
51+
}
52+
53+
type TransactionsChartResponse = {
54+
result: {
55+
analytics: Array<{
56+
timeBucket: string;
57+
chainId: string;
58+
count: number;
59+
}>;
60+
metadata: {
61+
resolution: string;
62+
startDate: string;
63+
endDate: string;
64+
};
65+
};
66+
};
67+
68+
const data = (await response.json()) as TransactionsChartResponse;
69+
70+
return data.result.analytics.map((stat) => ({
71+
chainId: Number(stat.chainId),
72+
count: stat.count,
73+
date: stat.timeBucket,
74+
}));
75+
}

apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/transactions/analytics/tx-chart/tx-chart-ui.tsx

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -108,10 +108,10 @@ export function TransactionsChartCardUI(props: {
108108
customHeader={
109109
<div className="relative px-6 pt-6">
110110
<h3 className="mb-0.5 font-semibold text-xl tracking-tight">
111-
Daily Transactions
111+
Transactions
112112
</h3>
113113
<p className="text-muted-foreground text-sm">
114-
Amount of daily transactions by chain.
114+
transactions broken down by chain
115115
</p>
116116

117117
<div className="top-6 right-6 mb-8 grid grid-cols-2 items-center gap-2 md:absolute md:mb-0 md:flex">
@@ -194,13 +194,7 @@ function EmptyChartContent(props: {
194194
</div>
195195
</>
196196
) : (
197-
<p className="flex items-center gap-2 rounded-full border bg-background px-3.5 py-1.5 text-sm">
198-
<span className="!pointer-events-auto relative flex size-2">
199-
<span className="absolute inline-flex h-full w-full animate-ping rounded-full bg-sky-400 opacity-75" />
200-
<span className="relative inline-flex size-2 rounded-full bg-primary" />
201-
</span>
202-
Waiting for transactions...
203-
</p>
197+
<p className="text-sm text-muted-foreground">No transactions found</p>
204198
)}
205199
</div>
206200
);

0 commit comments

Comments
 (0)