Skip to content

Commit 1397adf

Browse files
committed
posthog migration: part 5 (#7367)
<!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Added event reporting for contract publishing, faucet usage, and custom chain configuration additions. - Introduced detailed event reporting for asset purchases, creations, imports, and configuration steps. - **Refactor** - Replaced legacy analytics tracking hooks with centralized reporting functions for key user actions. - Updated asset creation flows to report step transitions and outcomes with enhanced detail. - **Bug Fixes** - Clarified faucet claim restriction text to include the "Scale" plan alongside other eligible plans. - **Chores** - Removed all legacy analytics tracking hooks and event calls across the dashboard. - Simplified event reporting by eliminating unused tracking utilities and hooks without affecting user workflows. <!-- end of auto-generated comment: release notes by coderabbit.ai --> <!-- start pr-codex --> --- ## PR-Codex overview This PR focuses on removing the `useTrack` analytics hook from various components and replacing it with direct logging or removing tracking functionality entirely. ### Detailed summary - Deleted `useTrack` imports and instances from multiple files. - Removed tracking-related code from components such as `LinkWalletPrompt`, `LoginOrSignup`, and `StepCard`. - Replaced tracking calls with direct logging in error handling. - Adjusted various components to eliminate unnecessary tracking. > The following files were skipped due to too many changes: `apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/cloud/vault/components/list-access-tokens.client.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/settings/components/primary-sale.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/components/mint-form.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/[tokenId]/components/mint-supply-tab.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/reset-claim-eligibility.tsx`, `apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/dedicated/(instance)/[engineId]/wallet-credentials/components/edit-wallet-credential-button.tsx`, `apps/dashboard/src/@/components/blocks/pricing-card.tsx`, `apps/dashboard/src/components/embedded-wallets/Configure/index.tsx`, `apps/dashboard/src/components/onboarding/ApplyForOpCreditsForm.tsx`, `apps/dashboard/src/components/settings/AuthorizedWallets/AuthorizedWalletsTable.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/settings/components/platform-fees.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/[tokenId]/components/update-metadata-form.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/[tokenId]/components/burn-tab.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/components/shared-metadata-form.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/components/batch-lazy-mint-button.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/[tokenId]/components/airdrop-tab.tsx`, `apps/dashboard/src/components/configure-networks/ConfigureNetworks.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/tokens/components/airdrop-form.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/tokens/components/burn-button.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/tokens/components/transfer-button.tsx`, `apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/dedicated/(instance)/[engineId]/overview/components/backend-wallets-table.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/components/claim-button.tsx`, `apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/dedicated/(instance)/[engineId]/admins/components/admins-table.tsx`, `apps/dashboard/src/components/smart-wallets/SponsorshipPolicies/index.tsx`, `apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/dedicated/(instance)/[engineId]/relayers/components/relayers-table.tsx`, `apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/dedicated/(instance)/[engineId]/access-tokens/components/access-tokens-table.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/tokens/components/claim-button.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/(chainPage)/components/client/PayModal.tsx`, `apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/settings/ProjectGeneralSettingsPage.tsx`, `apps/dashboard/src/app/(app)/login/onboarding/account-onboarding-ui.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/claim-conditions-form/index.tsx`, `apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/nft/upload-nfts/upload-nfts.tsx`, `apps/dashboard/src/components/CustomChat/CustomChatContent.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_layout/primary-dashboard-button.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/(chainPage)/components/client/FaucetButton.tsx`, `apps/dashboard/src/components/contract-components/contract-publish-form/index.tsx`, `apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/cards.tsx`, `apps/dashboard/src/app/(app)/login/onboarding/VerifyEmail/VerifyEmail.tsx`, `apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/nft/launch/launch-nft.tsx`, `apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/token/launch/launch-token.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/nft/overview/buy-nft-drop/buy-nft-drop.client.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/claim-tokens/claim-tokens-ui.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/nft/overview/buy-edition-drop/buy-edition-drop.client.tsx`, `apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/token/create-token-page-impl.tsx`, `apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/nft/create-nft-page.tsx`, `apps/dashboard/src/@/analytics/report.ts` > ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}` <!-- end pr-codex -->
1 parent 2aa9ce5 commit 1397adf

File tree

115 files changed

+634
-2394
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

115 files changed

+634
-2394
lines changed

apps/dashboard/src/@/analytics/report.ts

Lines changed: 233 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import type { Team } from "../api/team";
1010
* ### Why do we need to report this event?
1111
* - To track the number of contracts deployed
1212
* - To track the number of contracts deployed on each chain
13+
* - To track if the contract was deployed on the asset page vs on the deploy page
1314
*
1415
* ### Who is responsible for this event?
1516
* @jnsdls
@@ -20,6 +21,7 @@ export function reportContractDeployed(properties: {
2021
chainId: number;
2122
publisher: string | undefined;
2223
contractName: string | undefined;
24+
deploymentType?: "asset";
2325
}) {
2426
posthog.capture("contract deployed", properties);
2527
}
@@ -39,6 +41,25 @@ export function reportContractDeployFailed(properties: {
3941
posthog.capture("contract deploy failed", properties);
4042
}
4143

44+
/**
45+
* ### Why do we need to report this event?
46+
* - To track the number of contracts published
47+
* - To understand the type of contracts published
48+
* - To understand who publishes contracts
49+
*
50+
* ### Who is responsible for this event?
51+
* @jnsdls
52+
*
53+
*/
54+
export function reportContractPublished(properties: {
55+
publisher: string;
56+
contractName: string;
57+
version: string;
58+
deployType: string | undefined;
59+
}) {
60+
posthog.capture("contract published", properties);
61+
}
62+
4263
// ----------------------------
4364
// ONBOARDING (TEAM)
4465
// ----------------------------
@@ -148,3 +169,215 @@ export function reportOnboardingMembersUpsellPlanSelected(properties: {
148169
export function reportOnboardingCompleted() {
149170
posthog.capture("onboarding completed");
150171
}
172+
173+
// ----------------------------
174+
// FAUCET
175+
// ----------------------------
176+
/**
177+
* ### Why do we need to report this event?
178+
* - To track which chain the faucet was used on
179+
* - To track how popular specific faucets are
180+
*
181+
* ### Who is responsible for this event?
182+
* @jnsdls
183+
*
184+
*/
185+
export function reportFaucetUsed(properties: {
186+
chainId: number;
187+
}) {
188+
posthog.capture("faucet used", {
189+
chainId: properties.chainId,
190+
});
191+
}
192+
193+
// ----------------------------
194+
// CHAIN CONFIGURATION
195+
// ----------------------------
196+
/**
197+
* ### Why do we need to report this event?
198+
* - To track which custom chains customers are adding that we may want to add to the app
199+
*
200+
* ### Who is responsible for this event?
201+
* @jnsdls
202+
*
203+
*/
204+
export function reportChainConfigurationAdded(properties: {
205+
chainId: number;
206+
chainName: string;
207+
rpcURLs: readonly string[];
208+
nativeCurrency: {
209+
name: string;
210+
symbol: string;
211+
decimals: number;
212+
};
213+
}) {
214+
posthog.capture("chain configuration added", {
215+
chainId: properties.chainId,
216+
chainName: properties.chainName,
217+
rpcURLs: properties.rpcURLs,
218+
nativeCurrency: properties.nativeCurrency,
219+
});
220+
}
221+
222+
// ----------------------------
223+
// ASSETS
224+
// ----------------------------
225+
226+
type AssetContractType = "DropERC20" | "DropERC1155" | "DropERC721";
227+
228+
/**
229+
* ### Why do we need to report this event?
230+
* - To track number of successful asset purchases from the asset page
231+
* - To track which asset and contract types are being purchased the most
232+
*
233+
* ### Who is responsible for this event?
234+
* @MananTank
235+
*/
236+
export function reportAssetBuySuccessful(properties: {
237+
chainId: number;
238+
contractType: AssetContractType;
239+
assetType: "nft" | "coin";
240+
}) {
241+
posthog.capture("asset buy successful", {
242+
chainId: properties.chainId,
243+
contractType: properties.contractType,
244+
assetType: properties.assetType,
245+
});
246+
}
247+
248+
/**
249+
* ### Why do we need to report this event?
250+
* - To track number of failed asset purchases from the asset page
251+
* - To track the errors that users encounter when trying to purchase an asset
252+
*
253+
* ### Who is responsible for this event?
254+
* @MananTank
255+
*/
256+
export function reportAssetBuyFailed(properties: {
257+
chainId: number;
258+
contractType: AssetContractType;
259+
assetType: "nft" | "coin";
260+
error: string;
261+
}) {
262+
posthog.capture("asset buy failed", {
263+
chainId: properties.chainId,
264+
contractType: properties.contractType,
265+
assetType: properties.assetType,
266+
error: properties.error,
267+
});
268+
}
269+
270+
// Assets Landing Page ----------------------------
271+
272+
/**
273+
* ### Why do we need to report this event?
274+
* - To track number of asset creation started from the assets page
275+
* - To track which asset types are being created the most
276+
*
277+
* ### Who is responsible for this event?
278+
* @MananTank
279+
*/
280+
export function reportAssetCreationStarted(properties: {
281+
assetType: "nft" | "coin";
282+
}) {
283+
posthog.capture("asset creation started", {
284+
assetType: properties.assetType,
285+
});
286+
}
287+
288+
/**
289+
* ### Why do we need to report this event?
290+
* - To track number of assets imported successfully from the assets page
291+
*
292+
* ### Who is responsible for this event?
293+
* @MananTank
294+
*/
295+
export function reportAssetImportSuccessful() {
296+
posthog.capture("asset import successful");
297+
}
298+
299+
/**
300+
* ### Why do we need to report this event?
301+
* - To track number of asset import started in the assets page
302+
*
303+
* ### Who is responsible for this event?
304+
* @MananTank
305+
*/
306+
export function reportAssetImportStarted() {
307+
posthog.capture("asset import started");
308+
}
309+
310+
/**
311+
* ### Why do we need to report this event?
312+
* - To track the steps users are configuring in the asset creation to understand if there are any drop-offs
313+
*
314+
* ### Who is responsible for this event?
315+
* @MananTank
316+
*/
317+
export function reportAssetCreationStepConfigured(
318+
properties:
319+
| {
320+
assetType: "nft";
321+
step: "collection-info" | "upload-assets" | "sales-settings";
322+
}
323+
| {
324+
assetType: "coin";
325+
step: "coin-info" | "token-distribution" | "launch-coin";
326+
},
327+
) {
328+
posthog.capture("asset creation step configured", {
329+
assetType: properties.assetType,
330+
step: properties.step,
331+
});
332+
}
333+
334+
/**
335+
* ### Why do we need to report this event?
336+
* - To track number of successful asset creations
337+
* - To track which asset types are being created the most
338+
*
339+
* ### Who is responsible for this event?
340+
* @MananTank
341+
*/
342+
export function reportAssetCreationSuccessful(properties: {
343+
assetType: "nft" | "coin";
344+
contractType: AssetContractType;
345+
}) {
346+
posthog.capture("asset creation successful", {
347+
assetType: properties.assetType,
348+
contractType: properties.contractType,
349+
});
350+
}
351+
352+
/**
353+
* ### Why do we need to report this event?
354+
* - To track number of failed asset creations
355+
* - To track the errors that users encounter when trying to create an asset
356+
* - To track the step that is failing in the asset creation
357+
*
358+
* ### Who is responsible for this event?
359+
* @MananTank
360+
*/
361+
export function reportAssetCreationFailed(
362+
properties: { contractType: AssetContractType; error: string } & (
363+
| {
364+
assetType: "nft";
365+
step: "deploy-contract" | "mint-nfts" | "set-claim-conditions";
366+
}
367+
| {
368+
assetType: "coin";
369+
step:
370+
| "deploy-contract"
371+
| "set-claim-conditions"
372+
| "mint-tokens"
373+
| "airdrop-tokens";
374+
}
375+
),
376+
) {
377+
posthog.capture("asset creation failed", {
378+
assetType: properties.assetType,
379+
contractType: properties.contractType,
380+
error: properties.error,
381+
step: properties.step,
382+
});
383+
}

apps/dashboard/src/@/components/blocks/pricing-card.tsx

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import { Button } from "@/components/ui/button";
55
import { ToolTipLabel } from "@/components/ui/tooltip";
66
import { cn } from "@/lib/utils";
77
import { RenewSubscriptionButton } from "components/settings/Account/Billing/renew-subscription/renew-subscription-button";
8-
import { useTrack } from "hooks/analytics/useTrack";
98
import { CheckIcon, DollarSignIcon } from "lucide-react";
109
import Link from "next/link";
1110
import type React from "react";
@@ -58,7 +57,6 @@ export const PricingCard: React.FC<PricingCardProps> = ({
5857
}) => {
5958
const plan = TEAM_PLANS[billingPlan];
6059

61-
const trackEvent = useTrack();
6260
const remainingTrialDays =
6361
(activeTrialEndsAt ? remainingDays(activeTrialEndsAt) : 0) || 0;
6462

@@ -68,15 +66,6 @@ export const PricingCard: React.FC<PricingCardProps> = ({
6866
billingStatus === "noPayment" &&
6967
billingPlan === "growth";
7068

71-
const handleCTAClick = () => {
72-
cta?.onClick?.();
73-
trackEvent({
74-
category: "account",
75-
label: `${billingPlan}Plan`,
76-
action: "click",
77-
});
78-
};
79-
8069
return (
8170
<div
8271
className={cn(
@@ -163,7 +152,7 @@ export const PricingCard: React.FC<PricingCardProps> = ({
163152
buttonProps={{
164153
variant: highlighted ? "default" : "outline",
165154
className: highlighted ? undefined : "bg-background",
166-
onClick: handleCTAClick,
155+
onClick: cta.onClick,
167156
}}
168157
teamSlug={teamSlug}
169158
sku={billingPlanToSkuMap[billingPlan]}
@@ -181,7 +170,7 @@ export const PricingCard: React.FC<PricingCardProps> = ({
181170
<Link
182171
href={cta.href}
183172
target="_blank"
184-
onClick={handleCTAClick}
173+
onClick={cta.onClick}
185174
rel="noopener noreferrer"
186175
>
187176
{has7DayTrial ? "Start 7 Day Free Trial" : cta.label}

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/(chainPage)/components/client/FaucetButton.tsx

Lines changed: 6 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
"use client";
2+
import { reportFaucetUsed } from "@/analytics/report";
23
import { CopyTextButton } from "@/components/ui/CopyTextButton";
34
import { Spinner } from "@/components/ui/Spinner/Spinner";
45
import { Button } from "@/components/ui/button";
@@ -29,7 +30,6 @@ import { Turnstile } from "@marsidev/react-turnstile";
2930
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
3031
import type { CanClaimResponseType } from "app/(app)/api/testnet-faucet/can-claim/CanClaimResponseType";
3132
import { mapV4ChainToV5Chain } from "contexts/map-chains";
32-
import { useTrack } from "hooks/analytics/useTrack";
3333
import Link from "next/link";
3434
import { usePathname } from "next/navigation";
3535
import { useForm } from "react-hook-form";
@@ -95,17 +95,11 @@ export function FaucetButton({
9595
chain: definedChain,
9696
client,
9797
});
98-
const trackEvent = useTrack();
98+
9999
const queryClient = useQueryClient();
100100

101101
const claimMutation = useMutation({
102102
mutationFn: async (turnstileToken: string) => {
103-
trackEvent({
104-
category: "faucet",
105-
action: "claim",
106-
label: "attempt",
107-
chain_id: chainId,
108-
});
109103
const response = await fetch("/api/testnet-faucet/claim", {
110104
method: "POST",
111105
headers: {
@@ -124,20 +118,8 @@ export function FaucetButton({
124118
}
125119
},
126120
onSuccess: () => {
127-
trackEvent({
128-
category: "faucet",
129-
action: "claim",
130-
label: "success",
131-
chain_id: chainId,
132-
});
133-
},
134-
onError: (error) => {
135-
trackEvent({
136-
category: "faucet",
137-
action: "claim",
138-
label: "error",
139-
chain_id: chainId,
140-
errorMsg: error instanceof Error ? error.message : "Unknown error",
121+
reportFaucetUsed({
122+
chainId,
141123
});
142124
},
143125
onSettled: () => {
@@ -223,8 +205,9 @@ export function FaucetButton({
223205
{canClaimFaucetQuery.data.type === "unsupported-chain" &&
224206
"Faucet is empty right now"}
225207

208+
{/* TODO: add an upsell path here to subscribe to one of these plans */}
226209
{canClaimFaucetQuery.data.type === "paid-plan-required" &&
227-
"Faucet is only available on Starter, Growth and Pro plans."}
210+
"Faucet is only available on Starter, Growth, Scale and Pro plans."}
228211
</Button>
229212
);
230213
}

0 commit comments

Comments
 (0)