otpscreen

mail@pastecode.io avatar
unknown
plain_text
a month ago
14 kB
2
Indexable
Never
import React, { useEffect, useRef, useState } from 'react';
import {
  FlatList,
  ImageBackground,
  Keyboard,
  Platform,
  Pressable,
  SafeAreaView,
  StatusBar,
  StyleSheet,
  Text,
  TextInput,
  View,
} from 'react-native';
import AppIntroSlider from 'react-native-app-intro-slider';
import fonts from '../../assets/fonts';
import { height, width } from '../../constants/constants';
import Images from '../../assets/Images';
import GredientBg from '../../component/common/gredientBg';
import ImageCarousel from '../../component/authentication/ImageCarouselForOnboarding';
import ButtonComponent from '../../component/common/ButtonComponent';
import KeyboardAvoidView from '../../component/common/keyboardAvoidView';
import { useNavigation, useRoute } from '@react-navigation/native';
import { ChevronLeftIcon } from '../../assets/Icons';
import routes from '../../routes/routes';
import { checkOTP, login } from '../../api';
import { ShowSuccessMessage } from '../../component/common/showSuccessMessage';
import { ShowErrorMessage } from '../../component/common/showErrorMessage';
import Loader from '../../component/common/Loader';
import translate_strings from '../../translator/translate_strings';
import { colors } from '../../theme';
import { useDispatch } from 'react-redux';
import { storeUserDetails, storeUserProfileData } from '../../redux/actions/users';
import { NativeSyntheticEvent } from 'react-native';
import { Alert } from 'react-native';
import OtpAutoFillViewManager from 'react-native-otp-auto-fill';
import OtpInputs from 'react-native-otp-inputs';
import messaging from '@react-native-firebase/messaging';
import { ShowInfoMessage } from '../../component/common/showInfoMessage';
import DeviceInfo from 'react-native-device-info';
import { fontSize } from '../../utils/fontUtils';
import SmartechReact from 'smartech-base-react-native';

const OtpScreen = ({ }) => {
  const [, setCurrentIndex] = useState(0);
  const [activeIndex, setActiveIndex] = useState(0);
  const scrollRef = useRef();
  const route = useRoute();
  const navigation = useNavigation();
  const dispatch = useDispatch();
  const [loading, setLoading] = useState(false);
  const slides = [{ image: [Images.detox1, Images.diet1, Images.yoga1] }];
  const [otp, setOtp] = useState('');
  const otpInputRefs = [useRef(), useRef(), useRef(), useRef()];
  const otpRef = useRef();
  const [counter, setCounter] = useState(45);

  useEffect(() => {
    const timer =
      counter > 0 && setInterval(() => setCounter(counter - 1), 1000);
    return () => clearInterval(timer);
  }, [counter]);

  const handleResendOTP = async () => {
    const data = {
      country_code: '+91',
      mobile_number: route?.params?.phoneNumber,
      fcm_token: route?.params?.fcmToken,
      device_type: Platform.OS,
    };

    login(data).then(res => {
      setLoading(false);
      if (res?.data?.status) {
        ShowSuccessMessage(res?.data?.message);
        setCounter(45);
      } else {
        ShowErrorMessage('something went wrong');
      }
    });
  };

  // eslint-disable-next-line react/no-unstable-nested-components
  function RenderCarouselIndicator({ imageData }) {
    return (
      <View style={styles?.carsoulIndicatorContainer}>
        <FlatList
          numColumns={10}
          data={imageData}
          renderItem={({ item, index }) => {
            let active = activeIndex === index;
            return (
              <View
                style={{
                  width: active ? width / 15 : 5,
                  height: 5,
                  backgroundColor: colors.cE8E8E8,
                  borderRadius: 100,
                  overflow: 'hidden',
                  margin: 5,
                }}>
                {active ? <GredientBg /> : null}
              </View>
            );
          }}
        />
      </View>
    );
  }

  // eslint-disable-next-line react/no-unstable-nested-components
  function RenderItems({ item, index }) {
    return (
      <>
        <View style={{ flex: 1 }}>
          <ImageCarousel data={item?.image} activeIndex={setActiveIndex} />
          <Pressable
            onPress={() => navigation.goBack()}
            style={styles.backBtnContainer}>
            <ChevronLeftIcon width={width / 15} height={width / 15} />
          </Pressable>
          <ImageBackground
            style={styles?.imgBgOpacityContainer}
            source={Images.white_opacity}>
            <RenderCarouselIndicator imageData={item?.image} />
            <Text style={styles?.titleText}>
              {translate_strings.otpScreen.otpVerification}
            </Text>
          </ImageBackground>
        </View>
      </>
    );
  }

  useEffect(() => {
    if (otp.length == 4) {
      onVerify();
    }
  }, [otp]);

  async function onVerify() {
    const manufacturer = await DeviceInfo.getManufacturer();
    const modal = await DeviceInfo.getModel();
    const systemVersion = await DeviceInfo.getSystemVersion();
    setLoading(true);
    const data = {
      country_code: '+91',
      mobile_number: route?.params?.phoneNumber,
      otp: otp,
      fcm_token: route?.params?.fcmToken,
      language: 'en',
      timezone: 'Asia/Kolkata',
      device_type: Platform.OS,
      device_manufacturing: manufacturer,
      device_model: modal,
      device_system_version: systemVersion,
    };
    checkOTP(data).then(res => {
      setLoading(false);
      if (res?.data?.status) {
        ShowSuccessMessage(res?.data?.message);
        const userData = res?.data?.data;
        dispatch(storeUserDetails(userData));
        dispatch(storeUserProfileData(userData));

        if(userData?.survey_purpose==undefined && userData?.is_first_time){
          navigation?.replace(routes.assessmentGoal);
          return;
        }

        // Will use for Netcore Event
        // SmartechReact.login('91' + route?.params?.phoneNumber);
      } else {
        ShowErrorMessage(res?.data?.message);
      }
    }).catch(err => {
      setLoading(false);
      if (err?.response?.status == 404) {
        ShowErrorMessage('Invalid OTP');
      }
    });
  }

  const handleComplete = ({
    nativeEvent: { code },
  }: NativeSyntheticEvent<{ code: string }>) => {
    handleChange(code);
  };

  // This is only needed once to get the Android Signature key for SMS body
  const handleOnAndroidSignature = ({
    nativeEvent: { code },
  }: NativeSyntheticEvent<{ code: string }>) => { };
  const handleChange = (code: string) => {
    setOtp(code);
  };

  return (
    <SafeAreaView style={styles.container}>
      {/* <StatusBar backgroundColor={'transparent'} barStyle={'dark-content'} /> */}
      <KeyboardAvoidView>
        <AppIntroSlider
          data={slides}
          renderItem={RenderItems}
          showSkipButton={true}
          ref={scrollRef}
          onSlideChange={index => setCurrentIndex(index)}
          pagingEnabled
          renderPagination={() => null}
        />

        <Text onPress={() => navigation?.goBack()} style={styles.otpSendText}>
          {translate_strings.otpScreen.otpSendText}{' '}
          <Text style={styles.editPhonenumber}>+91 {route.params.phoneNumber}{' '}
          </Text>
          <Text style={styles.purpleUnderlineText}>Edit</Text>
        </Text>

        <OtpAutoFillViewManager
          onComplete={handleComplete}
          onAndroidSignature={handleOnAndroidSignature}
          style={styles.box}
          length={4} // Define the length of OTP code. This is a must.
        />

        {Platform.OS == 'android' ? (
          <OtpInputs
            clearTextOnFocus
            style={styles.otpInputContainer}
            inputContainerStyles={styles.inputContainerStyles}
            defaultValue={otp}
            inputStyles={styles.inputStyle}
            handleChange={text => handleChange(text)}
            keyboardType="phone-pad"
            numberOfInputs={4}
            ref={otpRef}
            autofillFromClipboard
            selectTextOnFocus={false}
          />
        ) : (
          <>
            <View>
              <FlatList
                style={styles.layerFlatlist}
                horizontal
                data={Array(4)}
                renderItem={({ item, index }) => {
                  return <View style={styles.layerContainer}></View>;
                }}
              />
            </View>
            <TextInput
              onChangeText={text => handleChange(text)}
              inputMode="numeric"
              maxLength={4}
              keyboardType="number-pad"
              style={styles.textInputOtpInput}
            />
          </>
        )}

        <View style={styles.rowTextContainer}>
          {counter != 0 ? (
            <Text style={styles.counterText}>{`00:${counter}`}</Text>
          ) : null}
          {counter == 0 ? (
            <Text onPress={() => handleResendOTP()} style={styles.purpleUnderlineText}>{' ' + translate_strings.otpScreen.resendOtp}</Text>
          ) : null}
        </View>

        <ButtonComponent
          testId={'verifyOtp'}
          isActive={otp.length === 4}
          title={translate_strings.otpScreen.verifty}
          onPress={() => onVerify()}
        />
      </KeyboardAvoidView>
      <Loader status={loading} />
    </SafeAreaView>
  );
};
const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: colors.white,
  },
  imgBGContainer: {
    width: width,
    height: height / 1.5,
    justifyContent: 'flex-end',
    resizeMode: 'stretch',
  },
  imgBgOpacityContainer: {
    width: width,
    height: width,
    alignItems: 'center',
    justifyContent: 'flex-end',
    position: 'absolute',
    bottom: 0,
  },
  titleText: {
    fontFamily: fonts.PoppinsSemiBold,
    color: colors.black,
    fontSize: fontSize.fs28,
    textAlign: 'left',
    alignSelf: 'flex-start',
    marginLeft: 20,
  },
  textIndicator: {
    fontFamily: fonts.PoppinsRegular,
    color: colors.c666666,
  },
  carsoulIndicatorContainer: {
    height: 21,
    alignItems: 'center',
    justifyContent: 'center',
    paddingTop: 3,
    paddingHorizontal: 5,
    marginBottom: width / 10,
    borderRadius: 100,
    backgroundColor: colors?.white,
  },
  textStyle: {
    fontFamily: fonts.PoppinsRegular,
    color: colors.c666666,
    paddingHorizontal: 20,
    fontSize: fontSize.fs11,
    marginTop: 10,
  },
  otpSendText: {
    fontFamily: fonts.PoppinsRegular,
    color: colors.c666666,
    paddingHorizontal: 20,
    fontSize: fontSize.fs13,
    marginVertical: 10,
  },
  purpleUnderlineText: {
    fontFamily: fonts.PoppinsSemiBold,
    color: colors.purple,
    textDecorationLine: 'underline',
    marginVertical: 10,
    marginLeft: 5,
  },
  rowTextContainer: {
    flexDirection: 'row',
    alignItems: 'center',
    alignSelf: 'center',
  },
  label: {
    fontSize: fontSize.fs18,
    marginBottom: 10,
  },
  otpContainer: {
    flexDirection: 'row',
    justifyContent: 'center',
  },
  otpInput: {
    width: 40,
    height: 40,
    borderWidth: 1,
    borderRadius: 5,
    fontSize: fontSize.fs18,
    textAlign: 'center',
    marginRight: 10,
  },
  inputStyle: {
    color: colors.black,
    fontSize:fontSize.fs14,
    marginLeft:10
  },
  backBtnContainer: {
    width: width / 10,
    height: width / 10,
    alignItems: 'center',
    justifyContent: 'center',
    position: 'absolute',
    top: 0,
    bottom: 0,
    left: 0,
    right: 0,
    margin: 15,
  },
  box: {
    width: 300,
    height: 55,
    marginVertical: 20,
    borderColor: 'red',
    borderWidth: 1,
    display: 'none',
  },
  flatListContainer: {
    alignSelf: 'center',
    top: width / 7,
  },
  otpBox: {
    width: width / 7,
    height: width / 7,
    borderWidth: 1,
    borderColor: colors.placeHolderTextColor,
    alignItems: 'center',
    justifyContent: 'center',
    textAlign: 'center',
    borderRadius: 12,
    marginHorizontal: 10,
  },
  otpBoxInput: {
    width: width / 1.35,
    height: width / 7,
    justifyContent: 'center',
    textAlign: 'left',
    alignSelf: 'center',
    includeFontPadding: true,
    letterSpacing: Platform.OS == 'ios' ? width / 6 : width / 8,
    paddingLeft: Platform.OS == 'ios' ? 25 : 10,
    color: colors.black,
  },
  counterText: {
    fontFamily: fonts.PoppinsRegular,
    color: colors.c999999,
    fontSize: fontSize.fs14,
  },
  inputContainerStyles: {
    width: width / 7,
    height: width / 7,
    borderWidth: 1,
    borderColor: colors.placeHolderTextColor,
    alignItems: 'center',
    justifyContent: 'center',
    textAlign: 'center',
    borderRadius: 12,
    marginHorizontal: 10,
  },
  otpInputContainer: {
    flexDirection: 'row',
    alignSelf: 'center',
    marginVertical: width / 20,
  },
  layerContainer: {
    width: width / 7,
    height: width / 7,
    borderWidth: 1,
    borderColor: colors.placeHolderTextColor,
    alignItems: 'center',
    justifyContent: 'center',
    textAlign: 'center',
    borderRadius: 12,
    marginHorizontal: 10,
  },
  layerFlatlist: {
    alignSelf: 'center',
    top: width / 7,
  },
  textInputOtpInput: {
    width: width / 1.35,
    height: width / 7,
    justifyContent: 'center',
    textAlign: 'left',
    alignSelf: 'center',
    includeFontPadding: true,
    letterSpacing: Platform.OS == 'ios' ? width / 6 : width / 8,
    paddingLeft: Platform.OS == 'ios' ? 25 : 10,
    color: colors.black,
  },
  editPhonenumber: {
    fontFamily: fonts.PoppinsSemiBold,
    color: colors.secondryColor,
  },
});
export default OtpScreen;
Leave a Comment