Skip to content

Commit 2529846

Browse files
jnsdlsMananTank
authored andcommitted
posthog migration: part 5
1 parent 09cc9b3 commit 2529846

File tree

114 files changed

+730
-2331
lines changed

Some content is hidden

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

114 files changed

+730
-2331
lines changed

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

Lines changed: 210 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ export function reportContractDeployed(properties: {
2020
chainId: number;
2121
publisher: string | undefined;
2222
contractName: string | undefined;
23+
deploymentType?: "asset";
2324
}) {
2425
posthog.capture("contract deployed", properties);
2526
}
@@ -39,6 +40,25 @@ export function reportContractDeployFailed(properties: {
3940
posthog.capture("contract deploy failed", properties);
4041
}
4142

43+
/**
44+
* ### Why do we need to report this event?
45+
* - To track the number of contracts published
46+
* - To understand the type of contracts published
47+
* - To understand who publishes contracts
48+
*
49+
* ### Who is responsible for this event?
50+
* @jnsdls
51+
*
52+
*/
53+
export function reportContractPublished(properties: {
54+
publisher: string;
55+
contractName: string;
56+
version: string;
57+
deployType: string | undefined;
58+
}) {
59+
posthog.capture("contract published", properties);
60+
}
61+
4262
// ----------------------------
4363
// ONBOARDING (TEAM)
4464
// ----------------------------
@@ -148,3 +168,193 @@ export function reportOnboardingMembersUpsellPlanSelected(properties: {
148168
export function reportOnboardingCompleted() {
149169
posthog.capture("onboarding completed");
150170
}
171+
172+
// ----------------------------
173+
// FAUCET
174+
// ----------------------------
175+
/**
176+
* ### Why do we need to report this event?
177+
* - To track which chain the faucet was used on
178+
* - To track how popular specific faucets are
179+
*
180+
* ### Who is responsible for this event?
181+
* @jnsdls
182+
*
183+
*/
184+
export function reportFaucetUsed(properties: {
185+
chainId: number;
186+
}) {
187+
posthog.capture("faucet used", {
188+
chainId: properties.chainId,
189+
});
190+
}
191+
// ----------------------------
192+
// CHAIN CONFIGURATION
193+
// ----------------------------
194+
/**
195+
* ### Why do we need to report this event?
196+
* - To track which custom chains customers are adding that we may want to add to the app
197+
*
198+
* ### Who is responsible for this event?
199+
* @jnsdls
200+
*
201+
*/
202+
export function reportChainConfigurationAdded(properties: {
203+
chainId: number;
204+
chainName: string;
205+
rpcURLs: readonly string[];
206+
nativeCurrency: {
207+
name: string;
208+
symbol: string;
209+
decimals: number;
210+
};
211+
}) {
212+
posthog.capture("chain configuration added", {
213+
chainId: properties.chainId,
214+
chainName: properties.chainName,
215+
rpcURLs: properties.rpcURLs,
216+
nativeCurrency: properties.nativeCurrency,
217+
});
218+
}
219+
220+
// ----------------------------
221+
// ASSETS
222+
// ----------------------------
223+
224+
type StatusWithError =
225+
| {
226+
status: "successful" | "attempted";
227+
}
228+
| {
229+
status: "failed";
230+
error: string;
231+
};
232+
233+
type AssetContractType = "DropERC20" | "DropERC1155" | "DropERC721";
234+
235+
/**
236+
* ### Why do we need to report this event?
237+
* - To track asset buy statuses (successful, failed, attempted) in the new asset pages
238+
*
239+
* ### Who is responsible for this event?
240+
* @MananTank
241+
*
242+
*/
243+
export function reportAssetBuy(
244+
properties: {
245+
chainId: number;
246+
assetType: "NFT" | "Coin";
247+
contractType: AssetContractType;
248+
} & StatusWithError,
249+
) {
250+
// Example: asset buy NFT successful
251+
posthog.capture(`asset buy ${properties.assetType} ${properties.status}`, {
252+
chainId: properties.chainId,
253+
contractType: properties.contractType,
254+
...(properties.status === "failed" && {
255+
error: properties.error,
256+
}),
257+
});
258+
}
259+
260+
/**
261+
* ### Why do we need to report this event?
262+
* - To track asset buy statuses (successful, failed, attempted) in the new asset pages
263+
*
264+
* ### Who is responsible for this event?
265+
* @MananTank
266+
*
267+
*/
268+
export function reportAssetsPageCardClick(properties: {
269+
label: "create-nft-collection" | "import-asset" | "create-coin";
270+
}) {
271+
// Example: asset page card create-nft-collection clicked
272+
posthog.capture(`assets page card ${properties.label} clicked`);
273+
}
274+
275+
/**
276+
* ### Why do we need to report this event?
277+
* - To track the steps UI that users are going through when creating an asset
278+
*
279+
* ### Who is responsible for this event?
280+
* @MananTank
281+
*
282+
*/
283+
export function reportCreateAssetStepNextClicked(
284+
properties:
285+
| {
286+
assetType: "NFT";
287+
page: "collection-info" | "upload-assets" | "sales-settings";
288+
}
289+
| {
290+
assetType: "Coin";
291+
page: "coin-info" | "token-distribution" | "launch-coin";
292+
},
293+
) {
294+
// Example: create asset NFT collection-info next clicked
295+
posthog.capture(
296+
`create asset ${properties.assetType} ${properties.page} next clicked`,
297+
);
298+
}
299+
300+
/**
301+
* ### Why do we need to report this event?
302+
* - To track the status of each step of the create asset flow
303+
*
304+
* ### Who is responsible for this event?
305+
* @MananTank
306+
*
307+
*/
308+
export function reportCreateAssetStepStatus(
309+
properties: (
310+
| {
311+
assetType: "NFT";
312+
step: "deploy-contract" | "lazy-mint-nfts" | "set-claim-conditions";
313+
}
314+
| {
315+
assetType: "Coin";
316+
step:
317+
| "deploy-contract"
318+
| "set-claim-conditions"
319+
| "mint-tokens"
320+
| "airdrop-tokens";
321+
}
322+
) &
323+
StatusWithError & {
324+
contractType: AssetContractType;
325+
},
326+
) {
327+
// Example: create asset NFT deploy-contract successful
328+
posthog.capture(
329+
`create asset ${properties.assetType} ${properties.step} ${properties.status}`,
330+
{
331+
...(properties.status === "failed" && {
332+
error: properties.error,
333+
}),
334+
contractType: properties.contractType,
335+
},
336+
);
337+
}
338+
339+
/**
340+
* ### Why do we need to report this event?
341+
* - To track the status of create asset as a whole (successful, failed, attempted)
342+
*
343+
* ### Who is responsible for this event?
344+
* @MananTank
345+
*
346+
*/
347+
export function reportCreateAssetStatus(
348+
properties: {
349+
assetType: "NFT" | "Coin";
350+
contractType: AssetContractType;
351+
} & StatusWithError,
352+
) {
353+
// Example: create asset NFT successful
354+
posthog.capture(`create asset ${properties.assetType} ${properties.status}`, {
355+
...(properties.status === "failed" && {
356+
error: properties.error,
357+
}),
358+
contractType: properties.contractType,
359+
});
360+
}

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)