Skip to content

Commit bf77802

Browse files
authored
Merge pull request #216 from vechain/jennifer/214-analytics-customization-flow-drop-off-handling-and-error-reporting
Analytics: drop-off handling and error reporting
2 parents 936d9e6 + 9617845 commit bf77802

File tree

19 files changed

+230
-95
lines changed

19 files changed

+230
-95
lines changed

packages/vechain-kit/src/components/AccountModal/Contents/ChooseName/ChooseNameContent.tsx

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import { AccountModalContentTypes } from '../../Types';
1313
import { FaRegAddressCard } from 'react-icons/fa';
1414
import { useTranslation } from 'react-i18next';
1515
import { useVeChainKitConfig } from '@/providers';
16+
import { Analytics } from '@/utils/mixpanelClientInstance';
1617

1718
export type ChooseNameContentProps = {
1819
setCurrentContent: React.Dispatch<
@@ -30,12 +31,29 @@ export const ChooseNameContent = ({
3031
const { t } = useTranslation();
3132
const { darkMode: isDark } = useVeChainKitConfig();
3233

34+
const handleClose = () => {
35+
Analytics.nameSelection.dropOff('search', {
36+
isError: false,
37+
name: '',
38+
reason: 'modal_closed',
39+
});
40+
};
41+
42+
const handleBack = () => {
43+
Analytics.nameSelection.dropOff('search', {
44+
isError: false,
45+
name: '',
46+
reason: 'back_button',
47+
});
48+
onBack();
49+
};
50+
3351
return (
3452
<>
3553
<StickyHeaderContainer>
3654
<ModalHeader>{t('Choose your account name')}</ModalHeader>
37-
<ModalBackButton onClick={onBack} />
38-
<ModalCloseButton />
55+
<ModalBackButton onClick={handleBack} />
56+
<ModalCloseButton onClick={handleClose} />
3957
</StickyHeaderContainer>
4058

4159
<ModalBody>

packages/vechain-kit/src/components/AccountModal/Contents/ChooseName/ChooseNameSearchContent.tsx

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -169,14 +169,29 @@ export const ChooseNameSearchContent = ({
169169
});
170170
};
171171

172+
const handleClose = () => {
173+
Analytics.nameSelection.dropOff('search', {
174+
isError: false,
175+
name,
176+
error: 'modal_closed',
177+
});
178+
};
179+
180+
const handleBack = () => {
181+
Analytics.nameSelection.dropOff('search', {
182+
isError: false,
183+
name,
184+
reason: 'back_button',
185+
});
186+
setCurrentContent(initialContentSource);
187+
};
188+
172189
return (
173190
<>
174191
<StickyHeaderContainer>
175192
<ModalHeader>{t('Choose Name')}</ModalHeader>
176-
<ModalBackButton
177-
onClick={() => setCurrentContent(initialContentSource)}
178-
/>
179-
<ModalCloseButton />
193+
<ModalBackButton onClick={handleBack} />
194+
<ModalCloseButton onClick={handleClose} />
180195
</StickyHeaderContainer>
181196

182197
<ModalBody>

packages/vechain-kit/src/components/AccountModal/Contents/ChooseName/ChooseNameSummaryContent.tsx

Lines changed: 33 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ import {
2222
useWallet,
2323
} from '@/hooks';
2424
import { Analytics } from '@/utils/mixpanelClientInstance';
25-
25+
import { isRejectionError } from '@/utils/StringUtils';
2626
export type ChooseNameSummaryContentProps = {
2727
setCurrentContent: React.Dispatch<
2828
React.SetStateAction<AccountModalContentTypes>
@@ -53,14 +53,12 @@ export const ChooseNameSummaryContent = ({
5353
useUpgradeSmartAccountModal();
5454

5555
const handleError = (error: string) => {
56-
if (
57-
error.toLowerCase().includes('rejected') ||
58-
error.toLowerCase().includes('cancelled') ||
59-
error.toLowerCase().includes('user denied')
60-
) {
56+
if (isRejectionError(error)) {
6157
Analytics.nameSelection.dropOff('confirmation', {
58+
isError: true,
6259
name,
6360
error,
61+
reason: 'wallet_rejected',
6462
});
6563
} else {
6664
Analytics.nameSelection.failed('confirmation', {
@@ -143,6 +141,30 @@ export const ChooseNameSummaryContent = ({
143141
handleConfirm();
144142
};
145143

144+
const handleClose = () => {
145+
Analytics.nameSelection.dropOff('confirmation', {
146+
isError: false,
147+
name: isUnsetting ? '' : name,
148+
error: 'modal_closed',
149+
});
150+
};
151+
152+
const handleBack = () => {
153+
Analytics.nameSelection.dropOff('confirmation', {
154+
isError: false,
155+
name: isUnsetting ? '' : name,
156+
error: 'back_button',
157+
});
158+
setCurrentContent({
159+
type: 'choose-name-search',
160+
props: {
161+
setCurrentContent,
162+
name,
163+
initialContentSource,
164+
},
165+
});
166+
};
167+
146168
return (
147169
<>
148170
<StickyHeaderContainer>
@@ -152,19 +174,13 @@ export const ChooseNameSummaryContent = ({
152174
: t('Confirm Name')}
153175
</ModalHeader>
154176
<ModalBackButton
155-
onClick={() =>
156-
setCurrentContent({
157-
type: 'choose-name-search',
158-
props: {
159-
setCurrentContent,
160-
name,
161-
initialContentSource,
162-
},
163-
})
164-
}
177+
onClick={handleBack}
178+
isDisabled={isTransactionPending}
179+
/>
180+
<ModalCloseButton
165181
isDisabled={isTransactionPending}
182+
onClick={handleClose}
166183
/>
167-
<ModalCloseButton isDisabled={isTransactionPending} />
168184
</StickyHeaderContainer>
169185

170186
<ModalBody>

packages/vechain-kit/src/components/AccountModal/Contents/Profile/Customization/CustomizationContent.tsx

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -212,20 +212,41 @@ export const CustomizationContent = ({
212212
});
213213
};
214214

215-
useEffect(() => {
216-
return () => {
217-
if (hasChanges && !isUploading) {
218-
Analytics.customization.dropOff('form');
219-
}
220-
};
221-
}, [hasChanges, isUploading]);
215+
const handleClose = () => {
216+
if (isUploading) {
217+
Analytics.customization.dropOff({
218+
stage: 'avatar',
219+
reason: 'modal_closed_during_upload',
220+
});
221+
} else {
222+
Analytics.customization.dropOff({
223+
stage: 'form',
224+
reason: 'modal_closed',
225+
});
226+
}
227+
};
228+
229+
const handleBack = () => {
230+
if (isUploading) {
231+
Analytics.customization.dropOff({
232+
stage: 'avatar',
233+
reason: 'back_button_during_upload',
234+
});
235+
} else {
236+
Analytics.customization.dropOff({
237+
stage: 'form',
238+
reason: 'back_button',
239+
});
240+
}
241+
setCurrentContent('profile');
242+
};
222243

223244
return (
224245
<Box>
225246
<StickyHeaderContainer>
226247
<ModalHeader>{t('Customization')}</ModalHeader>
227-
<ModalBackButton onClick={() => setCurrentContent('profile')} />
228-
<ModalCloseButton />
248+
<ModalBackButton onClick={handleBack} />
249+
<ModalCloseButton onClick={handleClose} />
229250
</StickyHeaderContainer>
230251

231252
<ModalBody>

packages/vechain-kit/src/components/AccountModal/Contents/Profile/Customization/CustomizationSummaryContent.tsx

Lines changed: 40 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ import {
2424
import { useUpdateTextRecord } from '@/hooks';
2525
import { useForm } from 'react-hook-form';
2626
import { useGetResolverAddress } from '@/hooks/api/vetDomains/useGetResolverAddress';
27-
import { useEffect } from 'react';
2827
import { Analytics } from '@/utils/mixpanelClientInstance';
28+
import { isRejectionError } from '@/utils/StringUtils';
2929

3030
export type CustomizationSummaryContentProps = {
3131
setCurrentContent: React.Dispatch<
@@ -106,6 +106,20 @@ export const CustomizationSummaryContent = ({
106106
},
107107
});
108108
},
109+
onError: (error) => {
110+
if (error && isRejectionError(error?.message ?? '')) {
111+
Analytics.customization.dropOff({
112+
stage: 'confirmation',
113+
reason: 'wallet_rejected',
114+
error: error?.message,
115+
});
116+
} else {
117+
Analytics.customization.failed(
118+
'confirmation',
119+
error instanceof Error ? error.message : 'Unknown error',
120+
);
121+
}
122+
},
109123
});
110124

111125
const onSubmit = async (data: FormValues) => {
@@ -148,18 +162,14 @@ export const CustomizationSummaryContent = ({
148162
}
149163
} catch (error) {
150164
console.error('Error saving changes:', error);
151-
Analytics.customization.dropOff('confirmation');
165+
Analytics.customization.dropOff({
166+
stage: 'confirmation',
167+
reason: 'transaction_error',
168+
error: error instanceof Error ? error.message : 'Unknown error',
169+
});
152170
}
153171
};
154172

155-
useEffect(() => {
156-
return () => {
157-
if (!txReceipt && !isTransactionPending) {
158-
Analytics.customization.dropOff('confirmation');
159-
}
160-
};
161-
}, [txReceipt, isTransactionPending]);
162-
163173
const renderField = (label: string, value: string) => {
164174
if (!value?.trim()) return null;
165175
return (
@@ -183,15 +193,33 @@ export const CustomizationSummaryContent = ({
183193
handleSubmit(onSubmit)();
184194
};
185195

196+
const handleClose = () => {
197+
Analytics.customization.dropOff({
198+
stage: 'confirmation',
199+
reason: 'modal_closed',
200+
});
201+
};
202+
203+
const handleBack = () => {
204+
Analytics.customization.dropOff({
205+
stage: 'confirmation',
206+
reason: 'back_button',
207+
});
208+
setCurrentContent('account-customization');
209+
};
210+
186211
return (
187212
<Box as="form" onSubmit={handleSubmit(onSubmit)}>
188213
<StickyHeaderContainer>
189214
<ModalHeader>{t('Confirm Changes')}</ModalHeader>
190215
<ModalBackButton
191216
isDisabled={isTransactionPending}
192-
onClick={() => setCurrentContent('account-customization')}
217+
onClick={handleBack}
218+
/>
219+
<ModalCloseButton
220+
isDisabled={isTransactionPending}
221+
onClick={handleClose}
193222
/>
194-
<ModalCloseButton isDisabled={isTransactionPending} />
195223
</StickyHeaderContainer>
196224

197225
<ModalBody>

packages/vechain-kit/src/components/AccountModal/Contents/SendToken/SendTokenContent.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,8 @@ export const SendTokenContent = ({
125125
tokenSymbol: selectedToken.symbol,
126126
amount: amount || undefined,
127127
recipientAddress: toAddressOrDomain || undefined,
128-
error: 'User cancelled - back button',
128+
error: 'back_button',
129+
isError: false,
129130
});
130131
}
131132
parentOnBack();
@@ -137,7 +138,8 @@ export const SendTokenContent = ({
137138
tokenSymbol: selectedToken.symbol,
138139
amount: amount || undefined,
139140
recipientAddress: toAddressOrDomain || undefined,
140-
error: 'User cancelled - close modal',
141+
error: 'modal_closed',
142+
isError: false,
141143
});
142144
}
143145
};

0 commit comments

Comments
 (0)