@@ -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 ) ;
0 commit comments