diff --git a/apps/dashboard/src/@/api/analytics.ts b/apps/dashboard/src/@/api/analytics.ts index 55d82f0fe46..46e0eeab01f 100644 --- a/apps/dashboard/src/@/api/analytics.ts +++ b/apps/dashboard/src/@/api/analytics.ts @@ -346,7 +346,7 @@ export async function getEcosystemWalletUsage(args: { searchParams.append("period", period); } const res = await fetchAnalytics( - `v2/wallets/connects/${ecosystemSlug}?${searchParams.toString()}`, + `v2/wallet/connects?${searchParams.toString()}`, { method: "GET", headers: { @@ -356,7 +356,10 @@ export async function getEcosystemWalletUsage(args: { ); if (res?.status !== 200) { - console.error("Failed to fetch ecosystem wallet stats"); + const reason = await res?.text(); + console.error( + `Failed to fetch ecosystem wallet stats: ${res?.status} - ${res.statusText} - ${reason}`, + ); return null; } diff --git a/apps/dashboard/src/app/team/[team_slug]/(team)/~/ecosystem/[slug]/(active)/analytics/components/EcosystemAnalyticsPage.tsx b/apps/dashboard/src/app/team/[team_slug]/(team)/~/ecosystem/[slug]/(active)/analytics/components/EcosystemAnalyticsPage.tsx index e8d1a0f3c6a..c31430079bc 100644 --- a/apps/dashboard/src/app/team/[team_slug]/(team)/~/ecosystem/[slug]/(active)/analytics/components/EcosystemAnalyticsPage.tsx +++ b/apps/dashboard/src/app/team/[team_slug]/(team)/~/ecosystem/[slug]/(active)/analytics/components/EcosystemAnalyticsPage.tsx @@ -4,6 +4,7 @@ import { getLastNDaysRange, } from "components/analytics/date-range-selector"; import { RangeSelector } from "components/analytics/range-selector"; +import type { Partner } from "../../../../types"; import { EcosystemWalletUsersChartCard } from "./EcosystemWalletUsersChartCard"; import { EcosystemWalletsSummary } from "./Summary"; @@ -12,11 +13,13 @@ export async function EcosystemAnalyticsPage({ teamId, interval, range, + partners, }: { ecosystemSlug: string; teamId: string; interval: "day" | "week"; range?: Range; + partners: Partner[]; }) { if (!range) { range = getLastNDaysRange("last-120"); @@ -69,6 +72,14 @@ export async function EcosystemAnalyticsPage({ + diff --git a/apps/dashboard/src/app/team/[team_slug]/(team)/~/ecosystem/[slug]/(active)/analytics/components/EcosystemWalletUsersChartCard.stories.tsx b/apps/dashboard/src/app/team/[team_slug]/(team)/~/ecosystem/[slug]/(active)/analytics/components/EcosystemWalletUsersChartCard.stories.tsx index 4f65c2a448e..7a5273581ac 100644 --- a/apps/dashboard/src/app/team/[team_slug]/(team)/~/ecosystem/[slug]/(active)/analytics/components/EcosystemWalletUsersChartCard.stories.tsx +++ b/apps/dashboard/src/app/team/[team_slug]/(team)/~/ecosystem/[slug]/(active)/analytics/components/EcosystemWalletUsersChartCard.stories.tsx @@ -53,6 +53,7 @@ function ecosystemWalletStatsStub( date: formattedDate, authenticationMethod: authMethod || "MetaMask", uniqueWalletsConnected: Math.floor(Math.random() * 1000) + 1, + ecosystemPartnerId: "123", }); } } @@ -65,6 +66,7 @@ export const EmptyData: Story = { args: { ecosystemWalletStats: [], isPending: false, + groupBy: "authenticationMethod", }, }; @@ -73,6 +75,7 @@ export const Loading: Story = { args: { ecosystemWalletStats: [], isPending: true, + groupBy: "authenticationMethod", }, }; @@ -81,6 +84,7 @@ export const ThirtyDaysData: Story = { args: { ecosystemWalletStats: ecosystemWalletStatsStub(30), isPending: false, + groupBy: "authenticationMethod", }, }; @@ -89,6 +93,7 @@ export const SixtyDaysData: Story = { args: { ecosystemWalletStats: ecosystemWalletStatsStub(60), isPending: false, + groupBy: "authenticationMethod", }, }; @@ -97,6 +102,7 @@ export const OneHundredTwentyDaysData: Story = { args: { ecosystemWalletStats: ecosystemWalletStatsStub(120), isPending: false, + groupBy: "authenticationMethod", }, }; @@ -114,6 +120,7 @@ export const ManyAuthMethods: Story = { })); })(), isPending: false, + groupBy: "authenticationMethod", }, }; @@ -125,5 +132,6 @@ export const ZeroValues: Story = { uniqueWalletsConnected: 0, })), isPending: false, + groupBy: "authenticationMethod", }, }; diff --git a/apps/dashboard/src/app/team/[team_slug]/(team)/~/ecosystem/[slug]/(active)/analytics/components/EcosystemWalletUsersChartCard.tsx b/apps/dashboard/src/app/team/[team_slug]/(team)/~/ecosystem/[slug]/(active)/analytics/components/EcosystemWalletUsersChartCard.tsx index e5e4972f0a6..72c6700dd42 100644 --- a/apps/dashboard/src/app/team/[team_slug]/(team)/~/ecosystem/[slug]/(active)/analytics/components/EcosystemWalletUsersChartCard.tsx +++ b/apps/dashboard/src/app/team/[team_slug]/(team)/~/ecosystem/[slug]/(active)/analytics/components/EcosystemWalletUsersChartCard.tsx @@ -10,6 +10,7 @@ import { formatDate } from "date-fns"; import { useMemo } from "react"; import type { EcosystemWalletStats } from "types/analytics"; import { formatTickerNumber } from "../../../../../../../../../../lib/format-utils"; +import type { Partner } from "../../../../types"; type ChartData = Record & { time: string; // human readable date @@ -19,8 +20,10 @@ const defaultLabel = "Unknown Auth"; export function EcosystemWalletUsersChartCard(props: { ecosystemWalletStats: EcosystemWalletStats[]; isPending: boolean; + groupBy: "ecosystemPartnerId" | "authenticationMethod"; + partners?: Partner[]; }) { - const { ecosystemWalletStats } = props; + const { ecosystemWalletStats, groupBy, partners } = props; const topChainsToShow = 10; @@ -31,25 +34,40 @@ export function EcosystemWalletUsersChartCard(props: { // for each stat, add it in _chartDataMap for (const stat of ecosystemWalletStats) { const chartData = _chartDataMap.get(stat.date); - const { authenticationMethod } = stat; + const { authenticationMethod, ecosystemPartnerId } = stat; // if no data for current day - create new entry if (!chartData) { _chartDataMap.set(stat.date, { time: stat.date, - [authenticationMethod || defaultLabel]: stat.uniqueWalletsConnected, + [groupBy === "ecosystemPartnerId" + ? ecosystemPartnerId + : authenticationMethod || defaultLabel]: + stat.uniqueWalletsConnected, } as ChartData); } else if (chartData) { - chartData[authenticationMethod || defaultLabel] = - (chartData[authenticationMethod || defaultLabel] || 0) + - stat.uniqueWalletsConnected; + chartData[ + groupBy === "ecosystemPartnerId" + ? ecosystemPartnerId + : authenticationMethod || defaultLabel + ] = + (chartData[ + groupBy === "ecosystemPartnerId" + ? ecosystemPartnerId + : authenticationMethod || defaultLabel + ] || 0) + stat.uniqueWalletsConnected; } authMethodToVolumeMap.set( - authenticationMethod || defaultLabel, + groupBy === "ecosystemPartnerId" + ? ecosystemPartnerId + : authenticationMethod || defaultLabel, stat.uniqueWalletsConnected + - (authMethodToVolumeMap.get(authenticationMethod || defaultLabel) || - 0), + (authMethodToVolumeMap.get( + groupBy === "ecosystemPartnerId" + ? ecosystemPartnerId + : authenticationMethod || defaultLabel, + ) || 0), ); } @@ -72,7 +90,12 @@ export function EcosystemWalletUsersChartCard(props: { authMethodsToShow.forEach((walletType, i) => { _chartConfig[walletType] = { - label: authMethodsToShow[i], + label: + groupBy === "ecosystemPartnerId" + ? partners?.find((p) => p.id === walletType)?.name || + authMethodsToShow[i] || + "none" + : authMethodsToShow[i], color: `hsl(var(--chart-${(i % 10) + 1}))`, }; }); @@ -92,7 +115,7 @@ export function EcosystemWalletUsersChartCard(props: { ), chartConfig: _chartConfig, }; - }, [ecosystemWalletStats]); + }, [ecosystemWalletStats, groupBy, partners]); const uniqueAuthMethods = Object.keys(chartConfig); const disableActions = @@ -108,7 +131,8 @@ export function EcosystemWalletUsersChartCard(props: { customHeader={

- Unique Users + Unique Users by{" "} + {groupBy === "ecosystemPartnerId" ? "Partner" : "Auth Method"}

The total number of active users in your ecosystem for each period. diff --git a/apps/dashboard/src/app/team/[team_slug]/(team)/~/ecosystem/[slug]/(active)/analytics/page.tsx b/apps/dashboard/src/app/team/[team_slug]/(team)/~/ecosystem/[slug]/(active)/analytics/page.tsx index cd0c845684c..81a9f2dbf90 100644 --- a/apps/dashboard/src/app/team/[team_slug]/(team)/~/ecosystem/[slug]/(active)/analytics/page.tsx +++ b/apps/dashboard/src/app/team/[team_slug]/(team)/~/ecosystem/[slug]/(active)/analytics/page.tsx @@ -2,6 +2,7 @@ import { redirect } from "next/navigation"; import { getTeamBySlug } from "../../../../../../../../../@/api/team"; import { getAuthToken } from "../../../../../../../../api/lib/getAuthToken"; import { fetchEcosystem } from "../../../utils/fetchEcosystem"; +import { fetchPartners } from "../configuration/hooks/fetchPartners"; import { EcosystemAnalyticsPage } from "./components/EcosystemAnalyticsPage"; export default async function Page(props: { @@ -40,11 +41,18 @@ export default async function Page(props: { redirect("/team"); } + const partners = await fetchPartners({ + ecosystem, + authToken, + teamId: team.id, + }); + return (