verification.tsx 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. import { View, Text, StyleSheet, TextInput, Pressable } from 'react-native';
  2. import { useEffect, useState } from 'react';
  3. import PhoneInput from '../../../global/phone_input';
  4. import NumberInput from '../../../global/number_input';
  5. import NormalButton from '../../../global/normal_button';
  6. import useSignUpStore from '../../../../providers/signup_form_store';
  7. import { authenticationService } from '../../../../service/authService';
  8. import { usePushNotifications } from '../../../../app/hooks/usePushNotifications';
  9. import { useTranslation } from '../../../../util/hooks/useTranslation';
  10. type VerificationProps = {
  11. setScreen: React.Dispatch<React.SetStateAction<number>>;
  12. };
  13. const Verification: React.FC<VerificationProps> = ({ setScreen }) => {
  14. const { signUpFormData, setSignUpFormData } = useSignUpStore();
  15. const [error, setError] = useState('');
  16. const [otp, setOtp] = useState('');
  17. const [canSendOtp, setCanSendOtp] = useState(true);
  18. const [lockPhoneInput, setLockPhoneInput] = useState(false);
  19. const [countdown, setCountdown] = useState(0);
  20. const [loading, setLoading] = useState(false);
  21. const { expoPushToken } = usePushNotifications();
  22. const { t, ready, currentLanguage } = useTranslation();
  23. const handleVerification = async () => {
  24. setLoading(true);
  25. if (signUpFormData.phone === '' || otp === '') {
  26. setError(t("register.two.error1"));
  27. } else {
  28. setError('');
  29. console.log('signUpFormData.phone', signUpFormData.phone);
  30. console.log('otp', otp);
  31. console.log('notifysession id in handleVerification', expoPushToken?.data);
  32. try {
  33. const result = await authenticationService.verifyPhoneOtp(
  34. signUpFormData.phone as string,
  35. otp,
  36. expoPushToken?.data as string
  37. );
  38. if (result.status === 200) {
  39. setScreen(2);
  40. } else {
  41. setError(t("register.two.error2"));
  42. }
  43. } catch (error) {
  44. console.log('error', error);
  45. setError(t("register.two.error2"));
  46. } finally {
  47. setLoading(false);
  48. }
  49. }
  50. };
  51. useEffect(() => {
  52. let timer: NodeJS.Timeout;
  53. if (countdown > 0) {
  54. timer = setInterval(() => {
  55. setCountdown((prev) => prev - 1);
  56. }, 1000);
  57. } else {
  58. setLockPhoneInput(false); // Add this line to unlock input when countdown reaches 0
  59. }
  60. return () => {
  61. if (timer) clearInterval(timer);
  62. };
  63. }, [countdown]);
  64. const handleSubmitOtp = async () => {
  65. if (signUpFormData.phone) {
  66. if (canSendOtp) {
  67. setCanSendOtp(false);
  68. setLockPhoneInput(true);
  69. setCountdown(60);
  70. try {
  71. await authenticationService.sendOtpToSignUpPhone(signUpFormData.phone);
  72. setError('');
  73. } catch (error) {
  74. console.log(error);
  75. setError(t("register.two.error3"));
  76. setCanSendOtp(true); // Reset canSendOtp if there's an error
  77. setLockPhoneInput(false); // Unlock phone input if there's an error
  78. }
  79. setTimeout(() => {
  80. setCanSendOtp(true);
  81. setLockPhoneInput(false);
  82. }, 60000);
  83. // setError('');
  84. } else {
  85. setError(t("register.two.error4"));
  86. }
  87. } else {
  88. setError(t("register.two.error5"));
  89. }
  90. };
  91. const otpButtonText = lockPhoneInput ? (
  92. <Text style={{ color: '#fff' }}>{t("register.two.spending")} ({countdown}s)</Text>
  93. ) : (
  94. <Text style={{ color: '#fff' }}>{t("register.two.spend")}</Text>
  95. );
  96. return (
  97. <View style={styles.container}>
  98. <Text style={styles.text}>{t('register.two.label')}</Text>
  99. <PhoneInput
  100. value={signUpFormData?.phone || ''}
  101. onChangeText={(phone: any) =>
  102. setSignUpFormData({
  103. ...signUpFormData,
  104. phone: phone
  105. })
  106. }
  107. placeholder={t('register.two.phone')}
  108. editable={!lockPhoneInput}
  109. extendedStyle={{ opacity: !lockPhoneInput ? 1 : 0.5 }}
  110. />
  111. <View
  112. style={{
  113. display: 'flex',
  114. flexDirection: 'row',
  115. paddingVertical: 10,
  116. gap: 10
  117. }}
  118. >
  119. <NumberInput placeholder={t('register.two.code')} onChangeText={setOtp} extendedStyle={{ flex: 1 }} />
  120. <NormalButton
  121. title={otpButtonText}
  122. onPress={handleSubmitOtp}
  123. extendedStyle={{ flex: 1 / 2, opacity: !lockPhoneInput ? 1 : 0.5 }}
  124. />
  125. </View>
  126. <NormalButton
  127. title={<Text style={{ color: '#fff' }}>{loading ? t('register.two.verifying') : t('register.two.verify')}</Text>}
  128. onPress={() => {
  129. handleVerification();
  130. }}
  131. />
  132. {error && <Text style={styles.errorMessage}>{error}</Text>}
  133. </View>
  134. );
  135. };
  136. const styles = StyleSheet.create({
  137. container: {
  138. flex: 1,
  139. marginHorizontal: 20
  140. },
  141. text: {
  142. fontSize: 20,
  143. paddingBottom: 10
  144. },
  145. errorMessage: {
  146. fontSize: 16,
  147. color: '#ff0033',
  148. fontWeight: '400',
  149. paddingVertical: 10
  150. },
  151. footer: { color: '#02677D', fontSize: 16, paddingVertical: 10 }
  152. });
  153. export default Verification;