Skip to content

Instantly share code, notes, and snippets.

@hlspablo
Created June 25, 2021 21:16
Show Gist options
  • Save hlspablo/2fad524f7aee96b96e3104cdfd5ff21f to your computer and use it in GitHub Desktop.
Save hlspablo/2fad524f7aee96b96e3104cdfd5ff21f to your computer and use it in GitHub Desktop.
import React, { useCallback, useEffect, useState } from 'react';
import {
ContinueButtonContainer,
ContinueText,
ImageTopCenterWrapper,
ImageTopView,
ImageTopViewShadow,
MainView,
MainContainer,
StepContainer,
MainContentContainer,
MyInputContainer,
styles,
SubHeaderText,
ResendText,
BackIconContainer,
AutoValidationText,
AlignCenter,
} from './styles';
import { SafeAreaView } from '@components/SafeAreView';
import FastImage from 'react-native-fast-image';
import { ShadowSheet } from '@app/styles';
import Stepper from '@components/Stepper';
import { KeyboardAvoidingView, StatusBar, Platform, LogBox, TouchableOpacity } from 'react-native';
import { Icon } from 'react-native-elements';
import { s, vs, ms, mvs } from 'react-native-size-matters';
import { useForm, Controller } from 'react-hook-form';
import { yupResolver } from '@hookform/resolvers/yup';
import * as yup from 'yup';
import ActionButton from '@components/Buttons/ActionButton';
import { useNavigation, useRoute } from '@react-navigation/native';
import MaskedInput from '@components/MaskedInput';
import { StepThreeNavigationProps, StepThreeScreenProps } from '@app/types/navigation';
import { DEFAULT_CONTRY_CODE } from '@app/config/Config';
import auth, { FirebaseAuthTypes } from '@react-native-firebase/auth';
import FlashMessage, { showMessage } from 'react-native-flash-message';
type FormData = {
code: string;
};
const schema = yup.object().shape({
code: yup.number().min(6, 'O código tem 6 digitos').required('Informe o código'),
});
export default function StepThreeScreen(): JSX.Element {
const [loading, setLoading] = useState(false);
const [verificationId, setVerificationId] = useState('');
const [showCodeInput, setShowCodeInput] = useState(false);
const navigation = useNavigation<StepThreeNavigationProps>();
const route = useRoute<StepThreeScreenProps>();
const {
control,
handleSubmit,
setError,
getValues,
formState: { errors },
} = useForm<FormData>({
resolver: yupResolver(schema),
});
const showCodeSentMessage = () => {
showMessage({
type: 'success',
icon: 'success',
message: 'Código SMS enviado',
floating: true,
duration: 5000,
titleStyle: {
fontFamily: 'SFUIText-Semibold',
fontSize: ms(18),
paddingTop: 5,
paddingBottom: 5,
},
});
};
const createCredentialAndSignIn = useCallback(
async (code: string) => {
if (verificationId) {
const authCredential = auth.PhoneAuthProvider.credential(verificationId, code);
try {
setLoading(true);
const userCredential = await auth().signInWithCredential(authCredential);
console.log(userCredential);
} catch (error) {
console.log(error);
} finally {
setLoading(false);
}
}
},
[verificationId],
);
const sendCodeAndWatch = useCallback(() => {
const cellphone = route.params.cellphone;
const authProvider = auth()
.verifyPhoneNumber(DEFAULT_CONTRY_CODE + cellphone)
.on('state_changed', (phoneAuthSnapshot) => {
if (phoneAuthSnapshot.state === 'timeout') {
// TODO Timeout - Android Only
} else if (phoneAuthSnapshot.state === 'sent') {
setShowCodeInput(true);
showCodeSentMessage();
setVerificationId(phoneAuthSnapshot.verificationId);
setLoading(false);
} else if (phoneAuthSnapshot.state === 'verified') {
if (phoneAuthSnapshot.code) {
setShowCodeInput(false);
setVerificationId(phoneAuthSnapshot.verificationId);
createCredentialAndSignIn(phoneAuthSnapshot.code);
}
} else if (phoneAuthSnapshot.state === 'error') {
// TODO Errors
}
});
}, [route.params.cellphone, createCredentialAndSignIn]);
useEffect(() => {
setLoading(true);
sendCodeAndWatch();
}, [sendCodeAndWatch]);
const onSubmit = async (data: any) => {
createCredentialAndSignIn(getValues('code'));
};
const resendCode = async (event: any) => {};
return (
<SafeAreaView edges={['bottom']}>
<StatusBar barStyle="dark-content" translucent backgroundColor="transparent" />
<KeyboardAvoidingView behavior={Platform.OS === 'ios' ? 'padding' : 'height'} style={styles.container}>
<MainView>
<ImageTopCenterWrapper>
<ImageTopViewShadow style={ShadowSheet.shadows6}>
<ImageTopView>
<FastImage
source={require('@assets/images/startup/stepthree_2.jpg')}
style={{ flex: 1 }}
resizeMode={FastImage.resizeMode.cover}
/>
</ImageTopView>
</ImageTopViewShadow>
</ImageTopCenterWrapper>
<BackIconContainer>
<Icon
raised
reverse
name="chevron-back-sharp"
type="ionicon"
size={ms(20)}
color="#ffffff"
reverseColor="#000000"
onPress={() => navigation.goBack()}
/>
</BackIconContainer>
<MainContainer>
<MainContentContainer>
{showCodeInput ? (
<>
<SubHeaderText>
Para concluir com segurança, digite o código de 6 dígitos enviado por SMS
</SubHeaderText>
<MyInputContainer>
<Controller
name="code"
control={control}
render={({ field: { onChange, onBlur, value } }) => (
<MaskedInput
type={'custom'}
options={{
mask: '999999',
}}
labelText="Código"
value={value}
onBlur={onBlur}
keyboardType="numeric"
onChangeText={(text) => onChange(text)}
placeholder="Código de 6 dígitos"
errorMessage={errors.code?.message}
/>
)}
/>
</MyInputContainer>
<TouchableOpacity onPress={resendCode}>
<ResendText>Reenviar código</ResendText>
</TouchableOpacity>
</>
) : (
<AlignCenter>
<AutoValidationText>Enviando SMS</AutoValidationText>
<Icon name="sms" type="material-icons" size={ms(35)} color="#09b44d" />
</AlignCenter>
)}
</MainContentContainer>
<StepContainer>
<Stepper currentIndex={2} maxSteps={3} />
</StepContainer>
</MainContainer>
</MainView>
<ActionButton text="Concluir" onPress={handleSubmit(onSubmit)} loading={loading} />
</KeyboardAvoidingView>
<FlashMessage
position="top"
style={{
marginTop: 20,
}}
/>
</SafeAreaView>
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment