`src\screens\auth\SigninScreen.tsx`
## SignIn
```js
import { Link } from '@react-navigation/native';
import React, { useEffect, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { FormProvider, useForm } from 'react-hook-form';
import { yupResolver } from '@hookform/resolvers/yup';
import * as yup from 'yup';
import { Alert, Image, StyleSheet, Text, TouchableOpacity, View } from 'react-native';
import ThemedText from '../../components/ThemedText';
import InputFormItem from '../../components/formItems/InputFormItem';
import CustomButton from '../../components/CustomButton';
import yupFormSchemas from '../../shared/yup/yupFormSchemas';
import ReactNativeBiometrics from 'react-native-biometrics';
import AuthService from '../../modules/service/authService';
import Message from '../../shared/message';
import { BiometricsToken } from '../../modules/biometricsToken';
import { AuthToken } from '../../modules/authToken';
import { AuthTokenTenant } from '../../modules/authTokenTenant';
import AuthCurrentTenant from '../../modules/authCurrentTenant';
import AsyncStorage from '@react-native-async-storage/async-storage';
import { ScrollView } from 'react-native-gesture-handler';
const schema = yup.object().shape({
email: yupFormSchemas.email('Email', {
required: true,
}),
password: yupFormSchemas.string('Password', {
required: true,
min: 6,
}),
});
const Signin = ({ navigation }: any) => {
const [isLoading, setIsLoading] = useState(false);
const { t } = useTranslation();
const [isBiometricsSet, SetIsBiometricsSet] = useState(false);
const rnBiometrics = new ReactNativeBiometrics({
allowDeviceCredentials: true,
});
const form = useForm({
resolver: yupResolver(schema),
});
const handleOpenBiometrics = async () => {
const resultObject = await rnBiometrics.simplePrompt({
promptMessage: 'Confirm Authorization',
});
const { success } = resultObject;
if (success) {
await BiometricsToken.set(true);
SetIsBiometricsSet(true);
} else {
biometricsStatusLocal();
}
};
const biometricsStatusLocal = async () => {
try {
const biometricsStatus = await BiometricsToken.get();
if (!biometricsStatus) {
Alert.alert(
'Set up Biometrics',
'Do you want to enable biometric authentication?',
[
{
text: 'No',
onPress: async () => {
await BiometricsToken.set(false);
SetIsBiometricsSet(true);
},
},
{
text: 'Yes',
onPress: async () => {
handleOpenBiometrics();
},
},
],
{ cancelable: false },
);
}
} catch (error) {
console.error(
'Error fetching biometrics status from AsyncStorage:',
error,
);
Message.error('Error fetching biometrics status from AsyncStorage');
}
};
const handleTryAnotherApp = async () => {
await AuthTokenTenant.clear();
await AuthCurrentTenant.clear();
navigation.reset({
index: 0,
routes: [{ name: 'Scanner' }],
});
};
const handleSignin = async (data: any) => {
setIsLoading(true);
try {
const responseData = await AuthService.signinWithEmailAndPassword(
data.email,
data.password,
);
await AuthToken.set(responseData);
const userData = await AuthService.fetchMe();
await AsyncStorage.setItem('me', JSON.stringify(userData));
await biometricsStatusLocal();
Message.success('', 'Sign-in Successful');
} catch (error) {
Message.error("Sorry, we don't recognize your credentials");
} finally {
setIsLoading(false);
}
};
useEffect(() => {
if (isBiometricsSet) {
navigation.navigate('Drawer');
}
}, [isBiometricsSet]);
return (
{t('Welcome to React Native!')}
{t('createAnAccount')}
{t('signup')}
navigation.navigate('ForgetPassword')}
disabled={isLoading}>
{t('forgetPassword')}
{t('tryAnotherApp')}
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
margin: 20,
},
title: {
marginBottom: 15,
},
createAccount: {
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
marginTop: 12,
},
createAccountText: {
color: '#666',
marginRight: 6,
},
});
export default Signin;
```
`src\screens\auth\SignupScreen.tsx`
## Signup
```js
import { Link } from '@react-navigation/native';
import React, { useState } from 'react';
import { useTranslation } from 'react-i18next';
import { FormProvider, useForm } from 'react-hook-form';
import { yupResolver } from '@hookform/resolvers/yup';
import * as yup from 'yup';
import { View, StyleSheet, Text, Image } from 'react-native';
import InputFormItem from '../../components/formItems/InputFormItem';
import ThemedText from '../../components/ThemedText';
import CustomButton from '../../components/CustomButton';
import AuthService from '../../modules/service/authService';
import Message from '../../shared/message';
import { AuthToken } from '../../modules/authToken';
import AsyncStorage from '@react-native-async-storage/async-storage';
import { ScrollView } from 'react-native-gesture-handler';
const schema = yup.object().shape({
email: yup
.string()
.email('Invalid email format')
.required('Email is required'),
password: yup
.string()
.min(6, 'Password must be at least 6 characters')
.required('Password is required'),
confirmPassword: yup
.string()
.oneOf([yup.ref('password'), null], 'Passwords must match')
.required('Confirm Password is required'),
});
const SignupPage = ({ navigation }: any) => {
const [isLoading, setIsLoading] = useState(false);
const { t } = useTranslation();
const form = useForm({
resolver: yupResolver(schema),
});
const handleSignup = async (data: any) => {
setIsLoading(true);
try {
const responseData = await AuthService.registerWithEmailAndPassword(data.email, data.password)
await AuthToken.set(responseData);
const userData = await AuthService.fetchMe();
await AsyncStorage.setItem('me', JSON.stringify(userData));
navigation.navigate('Drawer');
Message.success('Signup successful');
} catch (error) {
Message.error(error.message, 'Error fetching data');
} finally {
setIsLoading(false);
}
};
return (
{t('Welcome to React Native!')}
{t('haveAccount')}
{t('signin')}
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
padding: 20,
},
title: {
marginBottom: 15,
},
footerText: {
marginTop: 20,
textAlign: 'center',
color: '#666',
},
navigateSignIn: {
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
marginTop: 12,
},
navigateSignInText: {
color: '#666',
marginRight: 6,
},
});
export default SignupPage;
```