Skip to content

Commit 6cc7f8b

Browse files
authored
Feat: account change improvements (#1038)
* feat: account change confirmation + cancel * feat: wallet for mail sign in * feat: adapted to cancel API change
1 parent 054a59e commit 6cc7f8b

8 files changed

Lines changed: 159 additions & 59 deletions

File tree

package-lock.json

Lines changed: 8 additions & 8 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@
1212
"access": "public"
1313
},
1414
"dependencies": {
15-
"@dfx.swiss/react": "^1.3.0-beta.262",
16-
"@dfx.swiss/react-components": "^1.3.0-beta.262",
15+
"@dfx.swiss/react": "^1.3.0-beta.266",
16+
"@dfx.swiss/react-components": "^1.3.0-beta.266",
1717
"@ledgerhq/hw-app-btc": "^6.24.1",
1818
"@ledgerhq/hw-app-eth": "^6.33.7",
1919
"@ledgerhq/hw-transport-webhid": "^6.27.19",

src/components/home/wallet/connect-mail.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ export default function ConnectMail({ onCancel }: ConnectProps): JSX.Element {
2626
const { navigate } = useNavigation();
2727
const { redirectPath } = useAppHandlingContext();
2828
const { search } = useLocation();
29-
const { recommendationCode } = useAppParams();
29+
const { wallet, recommendationCode } = useAppParams();
3030

3131
const [isLoading, setIsLoading] = useState(false);
3232
const [mailSent, setMailSent] = useState(false);
@@ -53,7 +53,7 @@ export default function ConnectMail({ onCancel }: ConnectProps): JSX.Element {
5353
async function submit({ mail }: FormData): Promise<void> {
5454
setIsLoading(true);
5555
setError(undefined);
56-
signInWithMail(mail, redirectUri, recommendationCode)
56+
signInWithMail(mail, redirectUri, recommendationCode, wallet)
5757
.then(() => setMailSent(true))
5858
.catch((error: ApiError) => setError(error.message ?? 'Unknown error'))
5959
.finally(() => setIsLoading(false));

src/screens/account.screen.tsx

Lines changed: 45 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import {
1414
useUser,
1515
useUserContext,
1616
} from '@dfx.swiss/react';
17+
import { ConfirmationOverlay } from 'src/components/overlay/confirmation-overlay';
1718
import {
1819
AlignContent,
1920
CopyButton,
@@ -102,6 +103,7 @@ export default function AccountScreen(): JSX.Element {
102103
const [showRecommendationModal, setShowRecommendationModal] = useState(false);
103104
const [isDataLoading, setIsDataLoading] = useState(true);
104105
const [pdfBlockchains, setPdfBlockchains] = useState<Blockchain[]>([]);
106+
const [confirmEditStep, setConfirmEditStep] = useState<KycStepName>();
105107

106108
const recommendationsRef = useRef<HTMLHeadingElement>(null);
107109
useAnchor('recommendation', recommendationsRef, !isUserLoading && !isDataLoading);
@@ -304,29 +306,56 @@ export default function AccountScreen(): JSX.Element {
304306
const totalVolumeSum = totalVolumeItems?.reduce((acc, item) => acc + item.value, 0);
305307
const annualVolumeSum = annualVolumeItems?.reduce((acc, item) => acc + item.value, 0);
306308

307-
const title = showPdfModal
308-
? translate('screens/home', 'PDF Download Address Report')
309-
: showRecommendationModal
310-
? translate('screens/recommendation', 'Create Invitation')
311-
: isEmbedded
312-
? translate('screens/home', 'DFX services')
313-
: translate('screens/home', 'Account');
314-
const hasBackButton = (canClose && !isEmbedded) || showPdfModal || showRecommendationModal;
315-
const onBack = showPdfModal
316-
? closePdfModal
317-
: showRecommendationModal
318-
? () => setShowRecommendationModal(false)
319-
: undefined;
309+
const confirmEditStepLabels: Record<string, string> = {
310+
[KycStepName.PHONE_CHANGE]: translate('screens/home', 'Change phone number'),
311+
[KycStepName.ADDRESS_CHANGE]: translate('screens/home', 'Change address'),
312+
[KycStepName.NAME_CHANGE]: translate('screens/home', 'Change name'),
313+
};
314+
315+
const title = confirmEditStep
316+
? confirmEditStepLabels[confirmEditStep]
317+
: showPdfModal
318+
? translate('screens/home', 'PDF Download Address Report')
319+
: showRecommendationModal
320+
? translate('screens/recommendation', 'Create Invitation')
321+
: isEmbedded
322+
? translate('screens/home', 'DFX services')
323+
: translate('screens/home', 'Account');
324+
const hasBackButton = (canClose && !isEmbedded) || showPdfModal || showRecommendationModal || !!confirmEditStep;
325+
const onBack = confirmEditStep
326+
? () => setConfirmEditStep(undefined)
327+
: showPdfModal
328+
? closePdfModal
329+
: showRecommendationModal
330+
? () => setShowRecommendationModal(false)
331+
: undefined;
320332
const image = 'https://dfx.swiss/images/app/berge.jpg';
321333

322334
useLayoutOptions({ title, backButton: hasBackButton, onBack });
323335

336+
const confirmEditStepMessages: Record<string, string> = {
337+
[KycStepName.PHONE_CHANGE]: translate('screens/home', 'Do you really want to change your phone number?'),
338+
[KycStepName.ADDRESS_CHANGE]: translate('screens/home', 'Do you really want to change your address?'),
339+
[KycStepName.NAME_CHANGE]: translate('screens/home', 'Do you really want to change your name?'),
340+
};
341+
324342
return (
325343
<>
326344
{!isInitialized || !isLoggedIn || isUserLoading || isDataLoading ? (
327345
<div className="mt-4">
328346
<StyledLoadingSpinner size={SpinnerSize.LG} />
329347
</div>
348+
) : confirmEditStep ? (
349+
<ConfirmationOverlay
350+
message={confirmEditStepMessages[confirmEditStep]}
351+
cancelLabel={translate('general/actions', 'Cancel')}
352+
confirmLabel={translate('general/actions', 'Continue')}
353+
onCancel={() => setConfirmEditStep(undefined)}
354+
onConfirm={async () => {
355+
startStep(confirmEditStep);
356+
setConfirmEditStep(undefined);
357+
}}
358+
/>
330359
) : (
331360
<StyledVerticalStack gap={4} center full marginY={4} className="z-10">
332361
{/* Profile Data */}
@@ -355,7 +384,7 @@ export default function AccountScreen(): JSX.Element {
355384
{profile.phone}
356385
<StyledIconButton
357386
icon={IconVariant.EDIT}
358-
onClick={() => startStep(KycStepName.PHONE_CHANGE)}
387+
onClick={() => setConfirmEditStep(KycStepName.PHONE_CHANGE)}
359388
inline
360389
/>
361390
</div>
@@ -367,7 +396,7 @@ export default function AccountScreen(): JSX.Element {
367396
{[profile.firstName, profile.lastName].filter(Boolean).join(' ')}
368397
<StyledIconButton
369398
icon={IconVariant.EDIT}
370-
onClick={() => startStep(KycStepName.NAME_CHANGE)}
399+
onClick={() => setConfirmEditStep(KycStepName.NAME_CHANGE)}
371400
inline
372401
/>
373402
</div>
@@ -379,7 +408,7 @@ export default function AccountScreen(): JSX.Element {
379408
{formatAddress(profile.address)}
380409
<StyledIconButton
381410
icon={IconVariant.EDIT}
382-
onClick={() => startStep(KycStepName.ADDRESS_CHANGE)}
411+
onClick={() => setConfirmEditStep(KycStepName.ADDRESS_CHANGE)}
383412
inline
384413
/>
385414
</div>

src/screens/kyc.screen.tsx

Lines changed: 78 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import {
2323
KycSession,
2424
KycSignatoryPowerData,
2525
KycStepBase,
26+
KycStepCancelable,
2627
KycStepName,
2728
KycStepReason,
2829
KycStepSession,
@@ -107,7 +108,7 @@ export default function KycScreen(): JSX.Element {
107108
const { clearParams } = useNavigation();
108109
const { translate, changeLanguage, processingKycData } = useSettingsContext();
109110
const { user, reloadUser } = useUserContext();
110-
const { getKycInfo, continueKyc, startStep, addTransferClient } = useKyc();
111+
const { getKycInfo, continueKyc, startStep, addTransferClient, cancelStep } = useKyc();
111112
const { nameToString } = useKycHelper();
112113
const { pathname, search } = useLocation();
113114
const { navigate, goBack } = useNavigation();
@@ -123,6 +124,7 @@ export default function KycScreen(): JSX.Element {
123124
const [stepInProgress, setStepInProgress] = useState<KycStepSession>();
124125
const [error, setError] = useState<string>();
125126
const [showLinkHint, setShowLinkHint] = useState(false);
127+
const [isCanceling, setIsCanceling] = useState(false);
126128
const { rootRef } = useLayoutContext();
127129

128130
const mode = pathname.includes('/profile') ? Mode.PROFILE : pathname.includes('/contact') ? Mode.CONTACT : Mode.KYC;
@@ -307,6 +309,17 @@ export default function KycScreen(): JSX.Element {
307309
}
308310
};
309311

312+
const handleCancel = () => {
313+
if (!stepInProgress?.session || !kycCode) return;
314+
315+
setIsCanceling(true);
316+
setError(undefined);
317+
cancelStep(kycCode, stepInProgress.session.url)
318+
.then(() => onLoad(false))
319+
.catch((error: ApiError) => setError(error.message ?? 'Unknown error'))
320+
.finally(() => setIsCanceling(false));
321+
};
322+
310323
useLayoutOptions({
311324
title: stepInProgress ? nameToString(stepInProgress.name) : translate('screens/kyc', 'DFX KYC'),
312325
backButton: !!(stepInProgress || showLinkHint || consentClient),
@@ -364,6 +377,8 @@ export default function KycScreen(): JSX.Element {
364377
lang={info.language}
365378
onDone={() => onLoad(true)}
366379
onBack={() => onLoad(false)}
380+
onCancel={KycStepCancelable.includes(stepInProgress.name) ? handleCancel : undefined}
381+
isCanceling={isCanceling}
367382
onError={setError}
368383
showLinkHint={onLink}
369384
/>
@@ -428,6 +443,8 @@ interface EditProps {
428443
lang: Language;
429444
onDone: () => void;
430445
onBack: () => void;
446+
onCancel?: () => void;
447+
isCanceling?: boolean;
431448
onError: (error: string) => void;
432449
showLinkHint: () => void;
433450
}
@@ -2258,7 +2275,7 @@ interface PhoneChangeFormData {
22582275
phone: string;
22592276
}
22602277

2261-
function PhoneChangeData({ code, isLoading, step, onDone }: EditProps): JSX.Element {
2278+
function PhoneChangeData({ code, isLoading, step, onDone, onCancel, isCanceling }: EditProps): JSX.Element {
22622279
const { translate, translateError } = useSettingsContext();
22632280
const { setPhoneChangeData } = useKyc();
22642281

@@ -2305,14 +2322,25 @@ function PhoneChangeData({ code, isLoading, step, onDone }: EditProps): JSX.Elem
23052322
</div>
23062323
)}
23072324

2308-
<StyledButton
2309-
type="submit"
2310-
label={translate('general/actions', 'Next')}
2311-
onClick={handleSubmit(onSubmit)}
2312-
width={StyledButtonWidth.FULL}
2313-
disabled={!isValid}
2314-
isLoading={isUpdating || isLoading}
2315-
/>
2325+
<StyledHorizontalStack gap={4} spanAcross>
2326+
{onCancel && (
2327+
<StyledButton
2328+
color={StyledButtonColor.STURDY_WHITE}
2329+
width={StyledButtonWidth.FULL}
2330+
label={translate('general/actions', 'Cancel')}
2331+
onClick={onCancel}
2332+
isLoading={isCanceling}
2333+
/>
2334+
)}
2335+
<StyledButton
2336+
type="submit"
2337+
label={translate('general/actions', 'Next')}
2338+
onClick={handleSubmit(onSubmit)}
2339+
width={StyledButtonWidth.FULL}
2340+
disabled={!isValid}
2341+
isLoading={isUpdating || isLoading}
2342+
/>
2343+
</StyledHorizontalStack>
23162344
</StyledVerticalStack>
23172345
</Form>
23182346
);
@@ -2323,7 +2351,7 @@ interface AddressChangeFormData {
23232351
address: KycAddress;
23242352
}
23252353

2326-
function AddressChangeData({ rootRef, code, isLoading, step, onDone }: EditProps): JSX.Element {
2354+
function AddressChangeData({ rootRef, code, isLoading, step, onDone, onCancel, isCanceling }: EditProps): JSX.Element {
23272355
const { allowedCountries, translate, translateError } = useSettingsContext();
23282356
const { setAddressChangeData } = useKyc();
23292357
const { countryCode } = useGeoLocation();
@@ -2447,14 +2475,25 @@ function AddressChangeData({ rootRef, code, isLoading, step, onDone }: EditProps
24472475
</div>
24482476
)}
24492477

2450-
<StyledButton
2451-
type="submit"
2452-
label={translate('general/actions', 'Next')}
2453-
onClick={handleSubmit(onSubmit)}
2454-
width={StyledButtonWidth.FULL}
2455-
disabled={!isValid}
2456-
isLoading={isUpdating || isLoading}
2457-
/>
2478+
<StyledHorizontalStack gap={4} spanAcross>
2479+
{onCancel && (
2480+
<StyledButton
2481+
color={StyledButtonColor.STURDY_WHITE}
2482+
width={StyledButtonWidth.FULL}
2483+
label={translate('general/actions', 'Cancel')}
2484+
onClick={onCancel}
2485+
isLoading={isCanceling}
2486+
/>
2487+
)}
2488+
<StyledButton
2489+
type="submit"
2490+
label={translate('general/actions', 'Next')}
2491+
onClick={handleSubmit(onSubmit)}
2492+
width={StyledButtonWidth.FULL}
2493+
disabled={!isValid}
2494+
isLoading={isUpdating || isLoading}
2495+
/>
2496+
</StyledHorizontalStack>
24582497
</StyledVerticalStack>
24592498
</Form>
24602499
);
@@ -2466,7 +2505,7 @@ interface NameChangeFormData {
24662505
lastName: string;
24672506
}
24682507

2469-
function NameChangeData({ code, isLoading, step, onDone }: EditProps): JSX.Element {
2508+
function NameChangeData({ code, isLoading, step, onDone, onCancel, isCanceling }: EditProps): JSX.Element {
24702509
const { translate, translateError } = useSettingsContext();
24712510
const { setNameChangeData } = useKyc();
24722511

@@ -2556,14 +2595,25 @@ function NameChangeData({ code, isLoading, step, onDone }: EditProps): JSX.Eleme
25562595
</div>
25572596
)}
25582597

2559-
<StyledButton
2560-
type="submit"
2561-
label={translate('general/actions', 'Next')}
2562-
onClick={handleSubmit(onSubmit)}
2563-
width={StyledButtonWidth.FULL}
2564-
disabled={!isValid}
2565-
isLoading={isUpdating || isLoading}
2566-
/>
2598+
<StyledHorizontalStack gap={4} spanAcross>
2599+
{onCancel && (
2600+
<StyledButton
2601+
color={StyledButtonColor.STURDY_WHITE}
2602+
width={StyledButtonWidth.FULL}
2603+
label={translate('general/actions', 'Cancel')}
2604+
onClick={onCancel}
2605+
isLoading={isCanceling}
2606+
/>
2607+
)}
2608+
<StyledButton
2609+
type="submit"
2610+
label={translate('general/actions', 'Next')}
2611+
onClick={handleSubmit(onSubmit)}
2612+
width={StyledButtonWidth.FULL}
2613+
disabled={!isValid}
2614+
isLoading={isUpdating || isLoading}
2615+
/>
2616+
</StyledHorizontalStack>
25672617
</StyledVerticalStack>
25682618
</Form>
25692619
);

src/translations/languages/de.json

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -543,7 +543,14 @@
543543
"Please select an address or add a new one to continue.": "Bitte wähle eine Adresse aus oder füge eine neue hinzu, um fortzufahren.",
544544

545545
"PDF Download Address Report": "PDF Adressbericht herunterladen",
546-
"Date": "Datum"
546+
"Date": "Datum",
547+
548+
"Change phone number": "Telefonnummer ändern",
549+
"Change address": "Adresse ändern",
550+
"Change name": "Name ändern",
551+
"Do you really want to change your phone number?": "Möchtest Du wirklich Deine Telefonnummer ändern?",
552+
"Do you really want to change your address?": "Möchtest Du wirklich Deine Adresse ändern?",
553+
"Do you really want to change your name?": "Möchtest Du wirklich Deinen Namen ändern?"
547554
},
548555
"screens/buy": {
549556
"You spend": "Du zahlst",

0 commit comments

Comments
 (0)