1313 * See the License for the specific language governing permissions and
1414 * limitations under the License.
1515 */
16- import React , { useEffect , useRef } from 'react' ;
16+ import React , { useEffect , useRef , useState } from 'react' ;
1717import { E164Number , parsePhoneNumber } from 'libphonenumber-js/min' ;
1818import { useTheme } from '@mui/material/styles' ;
1919import Typography from '@mui/material/Typography' ;
@@ -31,35 +31,51 @@ import CloseIcon from '@mui/icons-material/Close';
3131import CheckCircleIcon from '@mui/icons-material/CheckCircle' ;
3232import CircularProgress from '@mui/material/CircularProgress' ;
3333import { isValidOTP } from '../../../utils/phone-utils' ;
34+ import { Product } from '../../SandboxCatalog/productData' ;
35+ import { signupDataToStatus } from '../../../utils/register-utils' ;
36+ import { productsURLMapping } from '../../../hooks/useProductURLs' ;
37+ import { errorMessage } from '../../../utils/common' ;
38+ import { useSandboxContext } from '../../../hooks/useSandboxContext' ;
39+ import { Country , getCountryCallingCode } from 'react-phone-number-input' ;
40+ import { useApi } from '@backstage/core-plugin-api' ;
41+ import { registerApiRef } from '../../../api' ;
3442
3543type VerificationCodeProps = {
44+ id : Product ;
3645 otp : string [ ] ;
3746 setOtp : React . Dispatch < React . SetStateAction < string [ ] > > ;
38- handleResendCode : ( ) => void ;
39- codeResent : boolean ;
47+ country : Country ;
4048 phoneNumber : E164Number | undefined ;
4149 handleEditPhoneNumber : ( ) => void ;
42- handleStartTrialClick : ( ) => void ;
4350 handleClose : ( ) => void ;
51+ setAnsibleCredsModalOpen : React . Dispatch < React . SetStateAction < boolean > > ;
52+ setRefetchingUserData : React . Dispatch < React . SetStateAction < boolean > > ;
53+ setLoading : React . Dispatch < React . SetStateAction < boolean > > ;
4454 loading ?: boolean ;
45- error ?: string ;
4655} ;
4756
4857export const VerificationCodeStep : React . FC < VerificationCodeProps > = ( {
58+ id,
4959 otp,
5060 setOtp,
51- handleResendCode,
52- codeResent,
61+ country,
5362 phoneNumber,
5463 handleEditPhoneNumber,
55- handleStartTrialClick,
64+ setAnsibleCredsModalOpen,
65+ setRefetchingUserData,
5666 handleClose,
5767 loading,
58- error ,
68+ setLoading ,
5969} ) => {
6070 const theme = useTheme ( ) ;
6171
6272 const inputRefs = useRef < any > ( [ ] ) ;
73+ const { refetchUserData, handleAAPInstance } = useSandboxContext ( ) ;
74+ const [ verificationCodeError , setVerificationCodeError ] = React . useState <
75+ string | undefined
76+ > ( ) ;
77+ const [ codeResent , setCodeResent ] = useState < boolean > ( false ) ;
78+ const registerApi = useApi ( registerApiRef ) ;
6379
6480 useEffect ( ( ) => {
6581 // Focus on the first input box when modal opens
@@ -107,6 +123,82 @@ export const VerificationCodeStep: React.FC<VerificationCodeProps> = ({
107123 }
108124 } ;
109125
126+ const handleResendCode = async ( ) => {
127+ if ( codeResent ) return ;
128+
129+ const countryCallingCode = `+${ getCountryCallingCode ( country ) } ` ;
130+ setOtp ( [ '' , '' , '' , '' , '' , '' ] ) ;
131+ try {
132+ setVerificationCodeError ( undefined ) ;
133+ setLoading ( true ) ;
134+ await registerApi . initiatePhoneVerification (
135+ countryCallingCode ,
136+ ( phoneNumber as string ) ?. replace ( countryCallingCode , '' ) ,
137+ ) ;
138+ setCodeResent ( true ) ;
139+ } catch ( e ) {
140+ setVerificationCodeError ( errorMessage ( e ) ) ;
141+ } finally {
142+ setLoading ( false ) ;
143+ }
144+ } ;
145+
146+ const handleStartTrialClick = async ( pdt : Product ) => {
147+ try {
148+ setVerificationCodeError ( undefined ) ;
149+ setLoading ( true ) ;
150+ await registerApi . completePhoneVerification ( otp . join ( '' ) ) ;
151+ const maxAttempts = 5 ;
152+ const retryInterval = 1000 ; // 1 second
153+
154+ // Poll until user is found or max attempts reached
155+ let urlToOpen = '' ;
156+ let userFound = false ;
157+ let userReady = false ;
158+ for ( let i = 0 ; i < maxAttempts ; i ++ ) {
159+ setRefetchingUserData ( true ) ;
160+ await new Promise ( resolve => setTimeout ( resolve , retryInterval ) ) ;
161+
162+ // Fetch the latest user data and check if user is found
163+ const userData = await refetchUserData ( ) ;
164+ if ( userData ) {
165+ userFound = true ;
166+ const userStatus = signupDataToStatus ( userData ) ;
167+ userReady = userStatus === 'ready' ;
168+ // if user is ready we can stop fetching the data
169+ if ( userReady ) {
170+ const productURLs = productsURLMapping ( userData ) ;
171+ // find the link to open if any
172+ urlToOpen = productURLs . find ( pu => pu . id === id ) ?. url || '' ;
173+ // User has signed up and the trial is ready and user selects the AAP Trial
174+ if ( userFound && userReady ) {
175+ if ( pdt === Product . AAP ) {
176+ if ( ! userData ?. defaultUserNamespace ) {
177+ // eslint-disable-next-line
178+ console . error (
179+ 'unable to provision AAP. user namespace is not defined.' ,
180+ ) ;
181+ return ;
182+ }
183+ handleAAPInstance ( userData . defaultUserNamespace ) ;
184+ setAnsibleCredsModalOpen ( true ) ;
185+ } else if ( urlToOpen ) {
186+ window . open ( urlToOpen , '_blank' ) ;
187+ }
188+ }
189+ break ;
190+ }
191+ }
192+ }
193+ handleClose ( ) ;
194+ } catch ( error ) {
195+ setVerificationCodeError ( errorMessage ( error ) ) ;
196+ } finally {
197+ setLoading ( false ) ;
198+ setRefetchingUserData ( false ) ;
199+ }
200+ } ;
201+
110202 return (
111203 < >
112204 < DialogTitle
@@ -202,14 +294,14 @@ export const VerificationCodeStep: React.FC<VerificationCodeProps> = ({
202294 </ div >
203295 </ Typography >
204296
205- { error && (
297+ { verificationCodeError && (
206298 < Typography
207299 color = "error"
208300 style = { { fontSize : '16px' , fontWeight : 400 , marginTop : '16px' } }
209301 >
210302 < div style = { { display : 'flex' , alignItems : 'center' , gap : '5px' } } >
211303 < ErrorIcon color = "error" style = { { fontSize : '16px' } } />
212- { error }
304+ { verificationCodeError }
213305 </ div >
214306 </ Typography >
215307 ) }
@@ -219,7 +311,7 @@ export const VerificationCodeStep: React.FC<VerificationCodeProps> = ({
219311 data-testid = "submit-opt-button"
220312 variant = "contained"
221313 type = "submit"
222- onClick = { handleStartTrialClick }
314+ onClick = { ( ) => handleStartTrialClick ( id ) }
223315 disabled = { otp . some ( digit => ! digit ) || loading }
224316 endIcon = {
225317 loading && < CircularProgress size = { 20 } sx = { { color : '#AFAFAF' } } />
0 commit comments