diff --git a/apps/dashboard/src/@/analytics/report.ts b/apps/dashboard/src/@/analytics/report.ts index 217b2d87f7f..d94b646172f 100644 --- a/apps/dashboard/src/@/analytics/report.ts +++ b/apps/dashboard/src/@/analytics/report.ts @@ -189,6 +189,7 @@ export function reportFaucetUsed(properties: { chainId: properties.chainId, }); } + // ---------------------------- // CHAIN CONFIGURATION // ---------------------------- @@ -222,140 +223,161 @@ export function reportChainConfigurationAdded(properties: { // ASSETS // ---------------------------- -type StatusWithError = - | { - status: "successful" | "attempted"; - } - | { - status: "failed"; - error: string; - }; - type AssetContractType = "DropERC20" | "DropERC1155" | "DropERC721"; /** * ### Why do we need to report this event? - * - To track asset buy statuses (successful, failed, attempted) in the new asset pages + * - To track number of successful asset purchases from the asset page + * - To track which asset and contract types are being purchased the most * * ### Who is responsible for this event? * @MananTank - * */ -export function reportAssetBuy( - properties: { - chainId: number; - assetType: "NFT" | "Coin"; - contractType: AssetContractType; - } & StatusWithError, -) { - // Example: asset buy NFT successful - posthog.capture(`asset buy ${properties.assetType} ${properties.status}`, { +export function reportAssetBuySuccessful(properties: { + chainId: number; + contractType: AssetContractType; + assetType: "nft" | "coin"; +}) { + posthog.capture("asset buy successful", { chainId: properties.chainId, contractType: properties.contractType, - ...(properties.status === "failed" && { - error: properties.error, - }), + assetType: properties.assetType, }); } /** * ### Why do we need to report this event? - * - To track the CTA card clicks on the assets page + * - To track number of failed asset purchases from the asset page + * - To track the errors that users encounter when trying to purchase an asset * * ### Who is responsible for this event? * @MananTank + */ +export function reportAssetBuyFailed(properties: { + chainId: number; + contractType: AssetContractType; + assetType: "nft" | "coin"; + error: string; +}) { + posthog.capture("asset buy failed", { + chainId: properties.chainId, + contractType: properties.contractType, + assetType: properties.assetType, + error: properties.error, + }); +} + +// Assets Landing Page ---------------------------- + +/** + * ### Why do we need to report this event? + * - To track number of asset creation started from the assets page + * - To track which asset types are being created the most * + * ### Who is responsible for this event? + * @MananTank */ -export function reportAssetsPageCardClick(properties: { - label: "create-nft-collection" | "import-asset" | "create-coin"; +export function reportAssetCreationStarted(properties: { + assetType: "nft" | "coin"; }) { - // Example: asset page card create-nft-collection clicked - posthog.capture(`assets page card ${properties.label} clicked`); + posthog.capture("asset creation started", { + assetType: properties.assetType, + }); +} + +/** + * ### Why do we need to report this event? + * - To track number of assets imported successfully from the assets page + * + * ### Who is responsible for this event? + * @MananTank + */ +export function reportAssetImportSuccessful() { + posthog.capture("asset import successful"); } /** * ### Why do we need to report this event? - * - To track the steps that users are going through in asset creation flow + * - To track number of asset import started in the assets page * * ### Who is responsible for this event? * @MananTank + */ +export function reportAssetImportStarted() { + posthog.capture("asset import started"); +} + +/** + * ### Why do we need to report this event? + * - To track the steps users are configuring in the asset creation to understand if there are any drop-offs * + * ### Who is responsible for this event? + * @MananTank */ -export function reportCreateAssetStepNextClicked( +export function reportAssetCreationStepConfigured( properties: | { - assetType: "NFT"; - page: "collection-info" | "upload-assets" | "sales-settings"; + assetType: "nft"; + step: "collection-info" | "upload-assets" | "sales-settings"; } | { - assetType: "Coin"; - page: "coin-info" | "token-distribution" | "launch-coin"; + assetType: "coin"; + step: "coin-info" | "token-distribution" | "launch-coin"; }, ) { - // Example: create asset NFT collection-info next clicked - posthog.capture( - `create asset ${properties.assetType} ${properties.page} next clicked`, - ); + posthog.capture("asset creation step configured", { + assetType: properties.assetType, + step: properties.step, + }); } /** * ### Why do we need to report this event? - * - To track the status of each step of the create asset flow + * - To track number of successful asset creations + * - To track which asset types are being created the most * * ### Who is responsible for this event? * @MananTank + */ +export function reportAssetCreationSuccessful(properties: { + assetType: "nft" | "coin"; + contractType: AssetContractType; +}) { + posthog.capture("asset creation successful", { + assetType: properties.assetType, + contractType: properties.contractType, + }); +} + +/** + * ### Why do we need to report this event? + * - To track number of failed asset creations + * - To track the errors that users encounter when trying to create an asset + * - To track the step that is failing in the asset creation * + * ### Who is responsible for this event? + * @MananTank */ -export function reportCreateAssetStepStatus( - properties: ( +export function reportAssetCreationFailed( + properties: { contractType: AssetContractType; error: string } & ( | { - assetType: "NFT"; - step: "deploy-contract" | "lazy-mint-nfts" | "set-claim-conditions"; + assetType: "nft"; + step: "deploy-contract" | "mint-nfts" | "set-claim-conditions"; } | { - assetType: "Coin"; + assetType: "coin"; step: | "deploy-contract" | "set-claim-conditions" | "mint-tokens" | "airdrop-tokens"; } - ) & - StatusWithError & { - contractType: AssetContractType; - }, -) { - // Example: create asset NFT deploy-contract successful - posthog.capture( - `create asset ${properties.assetType} ${properties.step} ${properties.status}`, - { - ...(properties.status === "failed" && { - error: properties.error, - }), - contractType: properties.contractType, - }, - ); -} - -/** - * ### Why do we need to report this event? - * - To track the status of create asset as a whole (successful, failed, attempted) - * - * ### Who is responsible for this event? - * @MananTank - * - */ -export function reportCreateAssetStatus( - properties: { - assetType: "NFT" | "Coin"; - contractType: AssetContractType; - } & StatusWithError, + ), ) { - // Example: create asset NFT successful - posthog.capture(`create asset ${properties.assetType} ${properties.status}`, { - ...(properties.status === "failed" && { - error: properties.error, - }), + posthog.capture("asset creation failed", { + assetType: properties.assetType, contractType: properties.contractType, + error: properties.error, + step: properties.step, }); } diff --git a/apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/claim-tokens/claim-tokens-ui.tsx b/apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/claim-tokens/claim-tokens-ui.tsx index 0b47a55085d..3b58ce26e95 100644 --- a/apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/claim-tokens/claim-tokens-ui.tsx +++ b/apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/claim-tokens/claim-tokens-ui.tsx @@ -1,5 +1,9 @@ "use client"; -import { reportAssetBuy } from "@/analytics/report"; + +import { + reportAssetBuyFailed, + reportAssetBuySuccessful, +} from "@/analytics/report"; import { Spinner } from "@/components/ui/Spinner/Spinner"; import { Button } from "@/components/ui/button"; import { DecimalInput } from "@/components/ui/decimal-input"; @@ -84,31 +88,6 @@ export function TokenDropClaim(props: { } >(undefined); - function report( - params: - | { - status: "attempted" | "successful"; - } - | { - status: "failed"; - errorMessage: string; - }, - ) { - reportAssetBuy({ - chainId: props.contract.chain.id, - assetType: "Coin", - contractType: "DropERC20", - ...(params.status === "failed" - ? { - status: "failed", - error: params.errorMessage, - } - : { - status: "attempted", - }), - }); - } - const approveAndClaim = useMutation({ mutationFn: async () => { if (!account) { @@ -116,10 +95,6 @@ export function TokenDropClaim(props: { return; } - report({ - status: "attempted", - }); - setStepsUI(undefined); const transaction = claimTo({ @@ -157,9 +132,11 @@ export function TokenDropClaim(props: { const errorMessage = parseError(approveTxResult.error); - report({ - status: "failed", - errorMessage, + reportAssetBuyFailed({ + chainId: props.contract.chain.id, + contractType: "DropERC20", + assetType: "coin", + error: errorMessage, }); toast.error("Failed to approve spending", { @@ -193,9 +170,11 @@ export function TokenDropClaim(props: { claim: "error", }); - report({ - status: "failed", - errorMessage, + reportAssetBuyFailed({ + chainId: props.contract.chain.id, + contractType: "DropERC20", + assetType: "coin", + error: errorMessage, }); toast.error("Failed to buy tokens", { @@ -204,8 +183,10 @@ export function TokenDropClaim(props: { return; } - report({ - status: "successful", + reportAssetBuySuccessful({ + chainId: props.contract.chain.id, + contractType: "DropERC20", + assetType: "coin", }); setStepsUI({ diff --git a/apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/nft/overview/buy-edition-drop/buy-edition-drop.client.tsx b/apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/nft/overview/buy-edition-drop/buy-edition-drop.client.tsx index 5f6c5e4aa17..4258a9ce4d4 100644 --- a/apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/nft/overview/buy-edition-drop/buy-edition-drop.client.tsx +++ b/apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/nft/overview/buy-edition-drop/buy-edition-drop.client.tsx @@ -1,6 +1,9 @@ "use client"; -import { reportAssetBuy } from "@/analytics/report"; +import { + reportAssetBuyFailed, + reportAssetBuySuccessful, +} from "@/analytics/report"; import { Form, FormControl, @@ -70,41 +73,12 @@ export function BuyEditionDrop(props: BuyEditionDropProps) { enabled: true, }); - function report( - params: - | { - status: "attempted" | "successful"; - } - | { - status: "failed"; - errorMessage: string; - }, - ) { - reportAssetBuy({ - chainId: props.contract.chain.id, - assetType: "NFT", - contractType: "DropERC1155", - ...(params.status === "failed" - ? { - status: "failed", - error: params.errorMessage, - } - : { - status: "attempted", - }), - }); - } - const handleSubmit = form.handleSubmit(async (data) => { try { if (!account) { return toast.error("No account detected"); } - report({ - status: "attempted", - }); - const transaction = claimTo({ contract: props.contract, to: account.address, @@ -139,9 +113,11 @@ export function BuyEditionDrop(props: BuyEditionDropProps) { } catch (err) { const errorMessage = parseError(err); - report({ - status: "failed", - errorMessage, + reportAssetBuyFailed({ + chainId: props.contract.chain.id, + contractType: "DropERC1155", + assetType: "nft", + error: errorMessage, }); console.error(errorMessage); @@ -165,8 +141,10 @@ export function BuyEditionDrop(props: BuyEditionDropProps) { try { await claimTxPromise; - report({ - status: "successful", + reportAssetBuySuccessful({ + chainId: props.contract.chain.id, + contractType: "DropERC1155", + assetType: "nft", }); props.onSuccess?.(); @@ -178,9 +156,11 @@ export function BuyEditionDrop(props: BuyEditionDropProps) { console.error(err); const errorMessage = parseError(err); - report({ - status: "failed", - errorMessage, + reportAssetBuyFailed({ + chainId: props.contract.chain.id, + contractType: "DropERC1155", + assetType: "nft", + error: errorMessage, }); return; @@ -193,9 +173,11 @@ export function BuyEditionDrop(props: BuyEditionDropProps) { description: errorMessage, }); - report({ - status: "failed", - errorMessage, + reportAssetBuyFailed({ + chainId: props.contract.chain.id, + contractType: "DropERC1155", + assetType: "nft", + error: errorMessage, }); } }); diff --git a/apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/nft/overview/buy-nft-drop/buy-nft-drop.client.tsx b/apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/nft/overview/buy-nft-drop/buy-nft-drop.client.tsx index 4911101a5ee..25efe376fe8 100644 --- a/apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/nft/overview/buy-nft-drop/buy-nft-drop.client.tsx +++ b/apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/nft/overview/buy-nft-drop/buy-nft-drop.client.tsx @@ -1,5 +1,8 @@ "use client"; -import { reportAssetBuy } from "@/analytics/report"; +import { + reportAssetBuyFailed, + reportAssetBuySuccessful, +} from "@/analytics/report"; import { toast } from "sonner"; import type { ThirdwebContract } from "thirdweb"; import type { NFT } from "thirdweb"; @@ -28,31 +31,6 @@ export function BuyNFTDrop(props: BuyNFTDropProps) { const sendAndConfirmTx = useSendAndConfirmTransaction(); const account = useActiveAccount(); - function report( - params: - | { - status: "attempted" | "successful"; - } - | { - status: "failed"; - errorMessage: string; - }, - ) { - reportAssetBuy({ - chainId: props.contract.chain.id, - assetType: "NFT", - contractType: "DropERC721", - ...(params.status === "failed" - ? { - status: "failed", - error: params.errorMessage, - } - : { - status: "attempted", - }), - }); - } - const handleSubmit = async (form: BuyNFTDropForm) => { const nftAmountToClaim = form.getValues("amount"); try { @@ -60,10 +38,6 @@ export function BuyNFTDrop(props: BuyNFTDropProps) { return toast.error("No account detected"); } - report({ - status: "attempted", - }); - const transaction = claimTo({ contract: props.contract, to: account.address, @@ -98,9 +72,11 @@ export function BuyNFTDrop(props: BuyNFTDropProps) { console.error(err); const errorMessage = parseError(err); - report({ - status: "failed", - errorMessage, + reportAssetBuyFailed({ + chainId: props.contract.chain.id, + contractType: "DropERC721", + assetType: "nft", + error: errorMessage, }); return; @@ -123,8 +99,10 @@ export function BuyNFTDrop(props: BuyNFTDropProps) { try { await claimTxPromise; - report({ - status: "successful", + reportAssetBuySuccessful({ + chainId: props.contract.chain.id, + contractType: "DropERC721", + assetType: "nft", }); props.onSuccess?.(); @@ -132,9 +110,11 @@ export function BuyNFTDrop(props: BuyNFTDropProps) { console.error(err); const errorMessage = parseError(err); - report({ - status: "failed", - errorMessage, + reportAssetBuyFailed({ + chainId: props.contract.chain.id, + contractType: "DropERC721", + assetType: "nft", + error: errorMessage, }); return; @@ -146,9 +126,11 @@ export function BuyNFTDrop(props: BuyNFTDropProps) { toast.error("Failed to buy NFTs", { description: errorMessage, }); - report({ - status: "failed", - errorMessage, + reportAssetBuyFailed({ + chainId: props.contract.chain.id, + contractType: "DropERC721", + assetType: "nft", + error: errorMessage, }); } }; diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/cards.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/cards.tsx index 2e0b2d29b8e..e9fe1a4649d 100644 --- a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/cards.tsx +++ b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/cards.tsx @@ -1,6 +1,10 @@ "use client"; -import { reportAssetsPageCardClick } from "@/analytics/report"; +import { + reportAssetCreationStarted, + reportAssetImportStarted, + reportAssetImportSuccessful, +} from "@/analytics/report"; import { cn } from "@/lib/utils"; import { ImportModal } from "components/contract-components/import-contract/modal"; import { ArrowDownToLineIcon, CoinsIcon, ImagesIcon } from "lucide-react"; @@ -28,31 +32,42 @@ export function Cards(props: { teamId={props.teamId} projectId={props.projectId} type="asset" + onSuccess={() => { + reportAssetImportSuccessful(); + }} /> { + reportAssetCreationStarted({ + assetType: "coin", + }); + }} /> { + reportAssetCreationStarted({ + assetType: "nft", + }); + }} /> { + reportAssetImportStarted(); setImportModalOpen(true); }} /> @@ -66,31 +81,22 @@ function CardLink(props: { href: string | undefined; onClick?: () => void; icon: React.FC<{ className?: string }>; - trackingLabel: "create-nft-collection" | "import-asset" | "create-coin"; }) { const { onClick } = props; const isClickable = !!onClick || !!props.href; - function handleClick() { - reportAssetsPageCardClick({ - label: props.trackingLabel, - }); - - onClick?.(); - } - return (
{ if (e.key === "Enter" || e.key === " ") { - handleClick(); + onClick?.(); } }} > diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/nft/create-nft-page-ui.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/nft/create-nft-page-ui.tsx index be578625fe0..5a7364e832d 100644 --- a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/nft/create-nft-page-ui.tsx +++ b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/nft/create-nft-page-ui.tsx @@ -1,6 +1,6 @@ "use client"; -import { reportCreateAssetStepNextClicked } from "@/analytics/report"; +import { reportAssetCreationStepConfigured } from "@/analytics/report"; import { zodResolver } from "@hookform/resolvers/zod"; import { useState } from "react"; import { useForm } from "react-hook-form"; @@ -87,9 +87,9 @@ export function CreateNFTPageUI(props: { client={props.client} form={nftCollectionInfoForm} onNext={() => { - reportCreateAssetStepNextClicked({ - assetType: "NFT", - page: "collection-info", + reportAssetCreationStepConfigured({ + assetType: "nft", + step: "collection-info", }); setStep(nftCreationPages["upload-assets"]); }} @@ -101,9 +101,9 @@ export function CreateNFTPageUI(props: { nftData={nftData} setNFTData={setNFTData} onNext={() => { - reportCreateAssetStepNextClicked({ - assetType: "NFT", - page: "upload-assets", + reportAssetCreationStepConfigured({ + assetType: "nft", + step: "upload-assets", }); setStep(nftCreationPages["sales-settings"]); }} @@ -120,9 +120,9 @@ export function CreateNFTPageUI(props: { form={nftSalesSettingsForm} client={props.client} onNext={() => { - reportCreateAssetStepNextClicked({ - assetType: "NFT", - page: "sales-settings", + reportAssetCreationStepConfigured({ + assetType: "nft", + step: "sales-settings", }); setStep(nftCreationPages["launch-nft"]); }} diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/nft/create-nft-page.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/nft/create-nft-page.tsx index abae8f0480f..c292e88416f 100644 --- a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/nft/create-nft-page.tsx +++ b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/nft/create-nft-page.tsx @@ -1,8 +1,8 @@ "use client"; import { revalidatePathAction } from "@/actions/revalidate"; import { + reportAssetCreationFailed, reportContractDeployed, - reportCreateAssetStepStatus, } from "@/analytics/report"; import { useRef } from "react"; import { @@ -87,13 +87,6 @@ export function CreateNFTPage(props: { // eslint-disable-next-line no-restricted-syntax const chain = defineChain(Number(collectionInfo.chain)); - reportCreateAssetStepStatus({ - assetType: "NFT", - step: "deploy-contract", - status: "attempted", - contractType, - }); - try { let contractAddress: string; @@ -133,13 +126,6 @@ export function CreateNFTPage(props: { }); } - reportCreateAssetStepStatus({ - assetType: "NFT", - step: "deploy-contract", - status: "successful", - contractType, - }); - reportContractDeployed({ address: contractAddress, chainId: Number(collectionInfo.chain), @@ -165,13 +151,13 @@ export function CreateNFTPage(props: { }; } catch (error) { const errorMessage = parseError(error); - console.error(error); - reportCreateAssetStepStatus({ - assetType: "NFT", - step: "deploy-contract", - status: "failed", - error: errorMessage, + console.error(errorMessage); + + reportAssetCreationFailed({ + assetType: "nft", contractType, + error: errorMessage, + step: "deploy-contract", }); throw error; @@ -197,35 +183,20 @@ export function CreateNFTPage(props: { nfts: formValues.nfts, }); - reportCreateAssetStepStatus({ - assetType: "NFT", - step: "lazy-mint-nfts", - status: "attempted", - contractType, - }); - try { await sendAndConfirmTransaction({ account: activeAccount, transaction, }); - - reportCreateAssetStepStatus({ - assetType: "NFT", - step: "lazy-mint-nfts", - status: "successful", - contractType, - }); } catch (error) { const errorMessage = parseError(error); console.error(error); - reportCreateAssetStepStatus({ - assetType: "NFT", - step: "lazy-mint-nfts", - status: "failed", - error: errorMessage, + reportAssetCreationFailed({ + assetType: "nft", contractType, + error: errorMessage, + step: "mint-nfts", }); throw error; @@ -261,35 +232,20 @@ export function CreateNFTPage(props: { ], }); - reportCreateAssetStepStatus({ - assetType: "NFT", - step: "set-claim-conditions", - status: "attempted", - contractType: "DropERC721", - }); - try { await sendAndConfirmTransaction({ account: activeAccount, transaction, }); - - reportCreateAssetStepStatus({ - assetType: "NFT", - step: "set-claim-conditions", - status: "successful", - contractType: "DropERC721", - }); } catch (error) { const errorMessage = parseError(error); console.error(errorMessage); - reportCreateAssetStepStatus({ - assetType: "NFT", - step: "set-claim-conditions", - status: "failed", - error: errorMessage, + reportAssetCreationFailed({ + assetType: "nft", contractType: "DropERC721", + error: errorMessage, + step: "set-claim-conditions", }); throw error; @@ -356,35 +312,20 @@ export function CreateNFTPage(props: { data: encodedTransactions, }); - reportCreateAssetStepStatus({ - assetType: "NFT", - step: "set-claim-conditions", - status: "attempted", - contractType: "DropERC1155", - }); - try { await sendAndConfirmTransaction({ transaction: tx, account: activeAccount, }); - - reportCreateAssetStepStatus({ - assetType: "NFT", - step: "set-claim-conditions", - status: "successful", - contractType: "DropERC1155", - }); } catch (error) { const errorMessage = parseError(error); - console.error(error); + console.error(errorMessage); - reportCreateAssetStepStatus({ - assetType: "NFT", - step: "set-claim-conditions", - status: "failed", - error: errorMessage, + reportAssetCreationFailed({ + assetType: "nft", contractType: "DropERC1155", + error: errorMessage, + step: "set-claim-conditions", }); throw error; diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/nft/launch/launch-nft.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/nft/launch/launch-nft.tsx index 982c56ef933..69e76c8dcf6 100644 --- a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/nft/launch/launch-nft.tsx +++ b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/nft/launch/launch-nft.tsx @@ -1,6 +1,6 @@ "use client"; -import { reportCreateAssetStatus } from "@/analytics/report"; +import { reportAssetCreationFailed } from "@/analytics/report"; import { MultiStepStatus } from "@/components/blocks/multi-step-status/multi-step-status"; import type { MultiStepState } from "@/components/blocks/multi-step-status/multi-step-status"; import { WalletAddress } from "@/components/blocks/wallet-address"; @@ -81,12 +81,6 @@ export function LaunchNFT(props: { } async function handleSubmitClick() { - reportCreateAssetStatus({ - assetType: "NFT", - status: "attempted", - contractType: ercType === "erc721" ? "DropERC721" : "DropERC1155", - }); - const initialSteps: MultiStepState[] = [ { label: "Deploy contract", @@ -217,23 +211,17 @@ export function LaunchNFT(props: { message: errorMessage, }); - reportCreateAssetStatus({ - assetType: "NFT", - status: "failed", + reportAssetCreationFailed({ + assetType: "nft", contractType: ercType === "erc721" ? "DropERC721" : "DropERC1155", error: errorMessage, + step: currentStep.id, }); throw error; } } - reportCreateAssetStatus({ - assetType: "NFT", - status: "successful", - contractType: ercType === "erc721" ? "DropERC721" : "DropERC1155", - }); - props.onLaunchSuccess(); batchesProcessedRef.current = 0; } diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/token/create-token-page-impl.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/token/create-token-page-impl.tsx index bcb834004e8..6bd10a355f4 100644 --- a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/token/create-token-page-impl.tsx +++ b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/token/create-token-page-impl.tsx @@ -1,8 +1,8 @@ "use client"; import { revalidatePathAction } from "@/actions/revalidate"; import { + reportAssetCreationFailed, reportContractDeployed, - reportCreateAssetStepStatus, } from "@/analytics/report"; import { DEFAULT_FEE_BPS_NEW, @@ -54,13 +54,6 @@ export function CreateTokenAssetPage(props: { throw new Error("No Connected Wallet"); } - reportCreateAssetStepStatus({ - assetType: "Coin", - step: "deploy-contract", - status: "attempted", - contractType: "DropERC20", - }); - const socialUrls = formValues.socialUrls.reduce( (acc, url) => { if (url.url && url.platform) { @@ -106,13 +99,6 @@ export function CreateTokenAssetPage(props: { contractType: "DropERC20", }); - reportCreateAssetStepStatus({ - assetType: "Coin", - step: "deploy-contract", - status: "successful", - contractType: "DropERC20", - }); - reportContractDeployed({ address: contractAddress, chainId: Number(formValues.chain), @@ -131,12 +117,11 @@ export function CreateTokenAssetPage(props: { const errorMessage = typeof parsedError === "string" ? parsedError : "Unknown error"; - reportCreateAssetStepStatus({ - assetType: "Coin", - step: "deploy-contract", - status: "failed", - error: errorMessage, + reportAssetCreationFailed({ + assetType: "coin", contractType: "DropERC20", + error: errorMessage, + step: "deploy-contract", }); console.error(errorMessage); @@ -167,13 +152,6 @@ export function CreateTokenAssetPage(props: { chain, }); - reportCreateAssetStepStatus({ - assetType: "Coin", - step: "airdrop-tokens", - status: "attempted", - contractType: "DropERC20", - }); - try { const airdropTx = transferBatch({ contract, @@ -187,23 +165,15 @@ export function CreateTokenAssetPage(props: { transaction: airdropTx, account, }); - - reportCreateAssetStepStatus({ - assetType: "Coin", - step: "airdrop-tokens", - status: "successful", - contractType: "DropERC20", - }); } catch (e) { console.error(e); const errorMessage = parseError(e); - reportCreateAssetStepStatus({ - assetType: "Coin", - step: "airdrop-tokens", - status: "failed", - error: errorMessage, + reportAssetCreationFailed({ + assetType: "coin", contractType: "DropERC20", + error: errorMessage, + step: "airdrop-tokens", }); throw e; } @@ -219,13 +189,6 @@ export function CreateTokenAssetPage(props: { throw new Error("No connected account"); } - reportCreateAssetStepStatus({ - assetType: "Coin", - step: "mint-tokens", - status: "attempted", - contractType: "DropERC20", - }); - // eslint-disable-next-line no-restricted-syntax const chain = defineDashboardChain( Number(formValues.chain), @@ -268,23 +231,15 @@ export function CreateTokenAssetPage(props: { transaction: claimTx, account, }); - - reportCreateAssetStepStatus({ - assetType: "Coin", - step: "mint-tokens", - status: "successful", - contractType: "DropERC20", - }); } catch (e) { const errorMessage = parseError(e); console.error(e); - reportCreateAssetStepStatus({ - assetType: "Coin", - step: "mint-tokens", - status: "failed", - error: errorMessage, + reportAssetCreationFailed({ + assetType: "coin", contractType: "DropERC20", + error: errorMessage, + step: "mint-tokens", }); throw e; @@ -351,13 +306,6 @@ export function CreateTokenAssetPage(props: { }, ]; - reportCreateAssetStepStatus({ - assetType: "Coin", - step: "set-claim-conditions", - status: "attempted", - contractType: "DropERC20", - }); - const preparedTx = setClaimConditionsExtension({ contract, phases, @@ -368,23 +316,15 @@ export function CreateTokenAssetPage(props: { transaction: preparedTx, account, }); - - reportCreateAssetStepStatus({ - assetType: "Coin", - step: "set-claim-conditions", - status: "successful", - contractType: "DropERC20", - }); } catch (e) { const errorMessage = parseError(e); console.error(e); - reportCreateAssetStepStatus({ - assetType: "Coin", - step: "set-claim-conditions", - status: "failed", - error: errorMessage, + reportAssetCreationFailed({ + assetType: "coin", contractType: "DropERC20", + error: errorMessage, + step: "set-claim-conditions", }); throw e; } diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/token/create-token-page.client.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/token/create-token-page.client.tsx index 174d6403b99..fb83082856d 100644 --- a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/token/create-token-page.client.tsx +++ b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/token/create-token-page.client.tsx @@ -1,6 +1,6 @@ "use client"; -import { reportCreateAssetStepNextClicked } from "@/analytics/report"; +import { reportAssetCreationStepConfigured } from "@/analytics/report"; import { zodResolver } from "@hookform/resolvers/zod"; import { useState } from "react"; import { useForm } from "react-hook-form"; @@ -95,9 +95,9 @@ export function CreateTokenAssetPageUI(props: { client={props.client} form={tokenInfoForm} onNext={() => { - reportCreateAssetStepNextClicked({ - assetType: "Coin", - page: "coin-info", + reportAssetCreationStepConfigured({ + assetType: "coin", + step: "coin-info", }); setStep("distribution"); }} @@ -115,9 +115,9 @@ export function CreateTokenAssetPageUI(props: { setStep("token-info"); }} onNext={() => { - reportCreateAssetStepNextClicked({ - assetType: "Coin", - page: "token-distribution", + reportAssetCreationStepConfigured({ + assetType: "coin", + step: "token-distribution", }); setStep("launch"); }} diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/token/launch/launch-token.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/token/launch/launch-token.tsx index 9dec9d7b475..efeaf0183b4 100644 --- a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/token/launch/launch-token.tsx +++ b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/token/launch/launch-token.tsx @@ -1,5 +1,8 @@ "use client"; -import { reportCreateAssetStatus } from "@/analytics/report"; +import { + reportAssetCreationFailed, + reportAssetCreationSuccessful, +} from "@/analytics/report"; import { type MultiStepState, MultiStepStatus, @@ -70,12 +73,6 @@ export function LaunchTokenStatus(props: { } async function handleSubmitClick() { - reportCreateAssetStatus({ - assetType: "Coin", - status: "attempted", - contractType: "DropERC20", - }); - const initialSteps: MultiStepState[] = [ { label: "Deploy contract", @@ -148,11 +145,11 @@ export function LaunchTokenStatus(props: { } catch (error) { const errorMessage = parseError(error); - reportCreateAssetStatus({ - assetType: "Coin", - status: "failed", + reportAssetCreationFailed({ + assetType: "coin", contractType: "DropERC20", error: errorMessage, + step: currentStep.id, }); updateStatus(i, { @@ -164,9 +161,8 @@ export function LaunchTokenStatus(props: { } } - reportCreateAssetStatus({ - assetType: "Coin", - status: "successful", + reportAssetCreationSuccessful({ + assetType: "coin", contractType: "DropERC20", }); diff --git a/apps/dashboard/src/components/contract-components/import-contract/modal.tsx b/apps/dashboard/src/components/contract-components/import-contract/modal.tsx index fab146c8e50..0e2d957b198 100644 --- a/apps/dashboard/src/components/contract-components/import-contract/modal.tsx +++ b/apps/dashboard/src/components/contract-components/import-contract/modal.tsx @@ -39,6 +39,7 @@ type ImportModalProps = { projectId: string; client: ThirdwebClient; type: "contract" | "asset"; + onSuccess?: () => void; }; export const ImportModal: React.FC = (props) => { @@ -69,6 +70,7 @@ export const ImportModal: React.FC = (props) => { projectId={props.projectId} client={props.client} type={props.type} + onSuccess={props.onSuccess} /> @@ -96,6 +98,7 @@ function ImportForm(props: { projectId: string; client: ThirdwebClient; type: "contract" | "asset"; + onSuccess?: () => void; }) { const router = useDashboardRouter(); const activeChainId = useActiveWalletChain()?.id; @@ -162,6 +165,7 @@ function ImportForm(props: { onSuccess: () => { router.refresh(); toast.success("Contract imported successfully"); + props.onSuccess?.(); }, onError: (err) => { console.error(err);