1+ <template >
2+ <article >
3+ <h1 class =" text-lightPrimaryText dark:text-gray1 text-4xl font-bold" >Sign up</h1 >
4+ <!-- Enter phone number -->
5+ <div v-show =" !otpSent" >
6+ <p class =" text-gray7 dark:text-gray3 my-10 text-center" >
7+ Verify you’re a human with your phone number so that Blogchain can fund your wallet.
8+ </p >
9+ <label for =" phoneNumber" class =" text-gray5 dark:text-gray3 block pb-1 text-sm font-semibold" >Phone Number</label >
10+ <input
11+ id =" phoneNumber"
12+ v-model =" phoneNumber"
13+ type =" tel"
14+ class =" focus:outline-none focus:border-primary text-primary dark:text-darkPrimaryText bg-gray2 dark:bg-gray7 mt-1 mb-5 w-full rounded-lg px-3 py-2 font-sans text-sm"
15+ />
16+ <div class =" flex w-full justify-end mt-4" >
17+ <BrandedButton :text =" otpSent ? `Re-send code` : `Send Code`" :action =" sendOTP" />
18+ </div >
19+ <h6 v-show =" isLoading" class =" text-primary text-center" >Sending SMS...</h6 >
20+ </div >
21+ <!-- Enter SMS code to complete verify -->
22+ <div v-show =" otpSent" class =" mt-10" >
23+ <label for =" otp" class =" text-gray5 dark:text-gray3 block pb-1 text-sm font-semibold"
24+ >Enter the one-time verification code sent to your phone number.</label
25+ >
26+ <input
27+ id =" otp"
28+ v-model =" otp"
29+ type =" text"
30+ placeholder =" "
31+ class =" focus:outline-none focus:border-primary text-primary dark:text-darkPrimaryText bg-gray2 dark:bg-gray7 mt-1 mb-5 w-full rounded-lg px-3 py-2 font-sans text-sm"
32+ />
33+ <BrandedButton v-show =" !isLoading && !waitingForFunds" :text =" `Verify`" class =" w-full" :action =" validateOTP" />
34+ <h6 v-show =" isLoading" class =" text-primary text-center" >Verifying...</h6 >
35+ <h6 v-show =" waitingForFunds" class =" text-primary text-center" >Executing smart contract...</h6 >
36+ </div >
37+ <p v-show =" otpSent" class =" text-gray7 dark:text-gray2 mt-10 text-center text-sm" >
38+ Didn't receive a code?
39+ <button class =" text-primary font-bold" @click =" otpSent = false" >
40+ Check your phone number and request a new one
41+ </button >
42+ </p >
43+ </article >
44+ </template >
45+
46+ <script lang="ts">
47+ import Vue from ' vue'
48+ import intlTelInput from ' intl-tel-input'
49+ import { AxiosError } from ' axios'
50+ import BrandedButton from ' @/components/BrandedButton.vue'
51+ import { requestOTP , requestPhoneOnboard , waitForFunds } from ' @/backend/funder'
52+ interface IData {
53+ otp: string
54+ otpSent: boolean
55+ iti: null | intlTelInput .Plugin
56+ phoneNumber: string
57+ inputCode: string
58+ isLoading: boolean
59+ waitingForFunds: boolean
60+ }
61+ export default Vue .extend ({
62+ components: {
63+ BrandedButton ,
64+ },
65+ props: {
66+ accountId: {
67+ type: String ,
68+ required: true ,
69+ },
70+ },
71+ data(): IData {
72+ return {
73+ otp: ` ` ,
74+ otpSent: false ,
75+ iti: null ,
76+ phoneNumber: ` ` ,
77+ inputCode: ` ` ,
78+ isLoading: false ,
79+ waitingForFunds: false ,
80+ }
81+ },
82+ mounted() {
83+ const input = document .querySelector (` #phoneNumber ` )
84+ if (input ) {
85+ this .iti = intlTelInput (input , {
86+ utilsScript: require (` intl-tel-input/build/js/utils ` ),
87+ // any initialisation options go here
88+ })
89+ }
90+ },
91+ methods: {
92+ async sendOTP() {
93+ if (this .iti === null ) {
94+ return
95+ }
96+ this .phoneNumber = this .iti .getNumber ()
97+ if (! this .iti .isValidNumber ()) {
98+ this .$toastError (` Invalid phone number ` )
99+ return
100+ }
101+ this .isLoading = true
102+ await requestOTP (this .phoneNumber )
103+ this .otpSent = true
104+ this .$toastSuccess (
105+ ` If you haven't used this phone number before on Blogchain, you'll receive a code on your phone ` ,
106+ )
107+ this .isLoading = false
108+ },
109+ async validateOTP() {
110+ try {
111+ if (this .otp .length !== 6 ) {
112+ this .$toastError (` OTP should have 6 digits ` )
113+ return
114+ }
115+ if (! this .accountId ) {
116+ return
117+ }
118+ this .isLoading = true
119+ await requestPhoneOnboard (this .phoneNumber , this .otp , this .accountId )
120+ this .isLoading = false
121+ this .waitingForFunds = true
122+ const { balance } = await waitForFunds (this .accountId )
123+ this .waitingForFunds = false
124+ this .$emit (` setIsOnboarded ` , true )
125+ this .$emit (` updateFunds ` , balance )
126+ } catch (err : any ) {
127+ this .isLoading = false
128+ this .waitingForFunds = false
129+ if (err instanceof AxiosError && err .response ) {
130+ this .otp = ` `
131+ this .$toastError (err .response .data .error )
132+ return
133+ }
134+ this .$toastError (err .message )
135+ throw err
136+ }
137+ },
138+ },
139+ })
140+ </script >
141+ <style >
142+ .iti {
143+ width : 100% ;
144+ }
145+ </style >
0 commit comments