├── .expo-shared
└── assets.json
├── .gitignore
├── App.js
├── app.json
├── app
├── DrawerNaviagtor.js
├── MainNavigator.js
├── api
│ └── client.js
├── components
│ ├── AppForm.js
│ ├── FormContainer.js
│ ├── FormHeader.js
│ ├── FormInput.js
│ ├── FormSelectorBtn.js
│ ├── FormSubmitButton.js
│ ├── Home.js
│ ├── ImageUpload.js
│ ├── LoginForm.js
│ ├── SignupForm.js
│ ├── Tasks.js
│ └── UserProfile.js
├── context
│ └── LoginProvider.js
└── utils
│ └── methods.js
├── assets
├── adaptive-icon.png
├── favicon.png
├── icon.png
└── splash.png
├── babel.config.js
├── package-lock.json
└── package.json
/.expo-shared/assets.json:
--------------------------------------------------------------------------------
1 | {
2 | "12bb71342c6255bbf50437ec8f4441c083f47cdb74bd89160c15e4f43e52a1cb": true,
3 | "40b842e832070c58deac6aa9e08fa459302ee3f9da492c7e77d93d2fbf4a56fd": true
4 | }
5 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 | .expo/
3 | npm-debug.*
4 | *.jks
5 | *.p8
6 | *.p12
7 | *.key
8 | *.mobileprovision
9 | *.orig.*
10 | web-build/
11 |
12 | # macOS
13 | .DS_Store
14 |
--------------------------------------------------------------------------------
/App.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { NavigationContainer } from '@react-navigation/native';
3 |
4 | import MainNavigator from './app/MainNavigator';
5 | import LoginProvider from './app/context/LoginProvider';
6 |
7 | export default function App() {
8 | return (
9 |
10 |
11 |
12 |
13 |
14 | );
15 | }
16 |
--------------------------------------------------------------------------------
/app.json:
--------------------------------------------------------------------------------
1 | {
2 | "expo": {
3 | "name": "react-native-form",
4 | "slug": "react-native-form",
5 | "version": "1.0.0",
6 | "orientation": "portrait",
7 | "icon": "./assets/icon.png",
8 | "splash": {
9 | "image": "./assets/splash.png",
10 | "resizeMode": "contain",
11 | "backgroundColor": "#ffffff"
12 | },
13 | "updates": {
14 | "fallbackToCacheTimeout": 0
15 | },
16 | "assetBundlePatterns": [
17 | "**/*"
18 | ],
19 | "ios": {
20 | "supportsTablet": true
21 | },
22 | "android": {
23 | "adaptiveIcon": {
24 | "foregroundImage": "./assets/adaptive-icon.png",
25 | "backgroundColor": "#FFFFFF"
26 | }
27 | },
28 | "web": {
29 | "favicon": "./assets/favicon.png"
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/app/DrawerNaviagtor.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { View, Text, TouchableOpacity, Image } from 'react-native';
3 | import {
4 | createDrawerNavigator,
5 | DrawerContentScrollView,
6 | DrawerItemList,
7 | } from '@react-navigation/drawer';
8 |
9 | import Home from './components/Home';
10 | import Tasks from './components/Tasks';
11 | import { useLogin } from './context/LoginProvider';
12 |
13 | const Drawer = createDrawerNavigator();
14 |
15 | const CustomDrawer = props => {
16 | const { setIsLoggedIn, profile } = useLogin();
17 | return (
18 |
19 |
20 |
30 |
31 | {profile.fullname}
32 | {profile.email}
33 |
34 |
42 |
43 |
44 |
45 | setIsLoggedIn(false)}
55 | >
56 | Log Out
57 |
58 |
59 | );
60 | };
61 |
62 | const DrawerNavigator = () => {
63 | return (
64 | }
75 | >
76 |
77 |
78 |
79 | );
80 | };
81 |
82 | export default DrawerNavigator;
83 |
--------------------------------------------------------------------------------
/app/MainNavigator.js:
--------------------------------------------------------------------------------
1 | import React, { useContext } from 'react';
2 | import { createStackNavigator } from '@react-navigation/stack';
3 |
4 | import AppForm from './components/AppForm';
5 | import ImageUpload from './components/ImageUpload';
6 | import UserProfile from './components/UserProfile';
7 | import { useLogin } from './context/LoginProvider';
8 | import DrawerNavigator from './DrawerNaviagtor';
9 |
10 | const Stack = createStackNavigator();
11 |
12 | const StackNavigator = () => {
13 | return (
14 |
15 |
16 |
17 |
18 |
19 | );
20 | };
21 |
22 | const MainNavigator = () => {
23 | const { isLoggedIn } = useLogin();
24 | return isLoggedIn ? : ;
25 | };
26 | export default MainNavigator;
27 |
--------------------------------------------------------------------------------
/app/api/client.js:
--------------------------------------------------------------------------------
1 | import axios from 'axios';
2 |
3 | export default axios.create({ baseURL: 'http://192.168.0.108:8000' });
4 |
--------------------------------------------------------------------------------
/app/components/AppForm.js:
--------------------------------------------------------------------------------
1 | import React, { useRef, useState } from 'react';
2 | import {
3 | ScrollView,
4 | StyleSheet,
5 | View,
6 | Animated,
7 | Dimensions,
8 | } from 'react-native';
9 |
10 | import FormHeader from './FormHeader';
11 | import FormSelectorBtn from './FormSelectorBtn';
12 | import SignupForm from './SignupForm';
13 | import LoginForm from './LoginForm';
14 |
15 | const { width } = Dimensions.get('window');
16 |
17 | export default function AppForm({ navigation }) {
18 | const animation = useRef(new Animated.Value(0)).current;
19 | const scrollView = useRef();
20 |
21 | const rightHeaderOpacity = animation.interpolate({
22 | inputRange: [0, width],
23 | outputRange: [1, 0],
24 | });
25 |
26 | const leftHeaderTranslateX = animation.interpolate({
27 | inputRange: [0, width],
28 | outputRange: [0, 40],
29 | });
30 | const rightHeaderTranslateY = animation.interpolate({
31 | inputRange: [0, width],
32 | outputRange: [0, -20],
33 | });
34 | const loginColorInterpolate = animation.interpolate({
35 | inputRange: [0, width],
36 | outputRange: ['rgba(27,27,51,1)', 'rgba(27,27,51,0.4)'],
37 | });
38 | const signupColorInterpolate = animation.interpolate({
39 | inputRange: [0, width],
40 | outputRange: ['rgba(27,27,51,0.4)', 'rgba(27,27,51,1)'],
41 | });
42 |
43 | return (
44 |
45 |
46 |
54 |
55 |
62 | scrollView.current.scrollTo({ x: 0 })}
67 | />
68 | scrollView.current.scrollTo({ x: width })}
73 | />
74 |
75 |
86 |
87 |
88 |
89 |
90 |
91 |
92 | );
93 | }
94 |
95 | const styles = StyleSheet.create({
96 | container: {
97 | flex: 1,
98 | backgroundColor: '#fff',
99 | alignItems: 'center',
100 | justifyContent: 'center',
101 | },
102 | borderLeft: {
103 | borderTopLeftRadius: 8,
104 | borderBottomLeftRadius: 8,
105 | },
106 | borderRight: {
107 | borderTopRightRadius: 8,
108 | borderBottomRightRadius: 8,
109 | },
110 | });
111 |
--------------------------------------------------------------------------------
/app/components/FormContainer.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import {
3 | View,
4 | StyleSheet,
5 | Dimensions,
6 | KeyboardAvoidingView,
7 | Platform,
8 | } from 'react-native';
9 |
10 | const FormContainer = ({ children }) => {
11 | return (
12 |
17 | {children}
18 |
19 | );
20 | };
21 |
22 | const styles = StyleSheet.create({
23 | container: {
24 | width: Dimensions.get('window').width,
25 | paddingHorizontal: 20,
26 | },
27 | });
28 |
29 | export default FormContainer;
30 |
--------------------------------------------------------------------------------
/app/components/FormHeader.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { View, StyleSheet, Text, Animated } from 'react-native';
3 |
4 | const FormHeader = ({
5 | leftHeading,
6 | rightHeading,
7 | subHeading,
8 | leftHeaderTranslateX = 40,
9 | rightHeaderTranslateY = -20,
10 | rightHeaderOpacity = 0,
11 | }) => {
12 | return (
13 | <>
14 |
15 |
21 | {leftHeading}
22 |
23 |
32 | {rightHeading}
33 |
34 |
35 | {subHeading}
36 | >
37 | );
38 | };
39 |
40 | const styles = StyleSheet.create({
41 | container: {
42 | flexDirection: 'row',
43 | justifyContent: 'center',
44 | alignItems: 'center',
45 | },
46 | heading: { fontSize: 30, fontWeight: 'bold', color: '#1b1b33' },
47 | subHeading: { fontSize: 18, color: '#1b1b33', textAlign: 'center' },
48 | });
49 |
50 | export default FormHeader;
51 |
--------------------------------------------------------------------------------
/app/components/FormInput.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { View, StyleSheet, Text, TextInput } from 'react-native';
3 |
4 | const FormInput = props => {
5 | const { placeholder, label, error } = props;
6 | return (
7 | <>
8 |
15 | {label}
16 | {error ? (
17 | {error}
18 | ) : null}
19 |
20 |
21 | >
22 | );
23 | };
24 |
25 | const styles = StyleSheet.create({
26 | input: {
27 | borderWidth: 1,
28 | borderColor: '#1b1b33',
29 | height: 35,
30 | borderRadius: 8,
31 | fontSize: 16,
32 | paddingLeft: 10,
33 | marginBottom: 20,
34 | },
35 | });
36 |
37 | export default FormInput;
38 |
--------------------------------------------------------------------------------
/app/components/FormSelectorBtn.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import {
3 | View,
4 | StyleSheet,
5 | TouchableWithoutFeedback,
6 | Text,
7 | Animated,
8 | } from 'react-native';
9 |
10 | const FormSelectorBtn = ({ title, backgroundColor, style, onPress }) => {
11 | return (
12 |
13 |
14 | {title}
15 |
16 |
17 | );
18 | };
19 |
20 | const styles = StyleSheet.create({
21 | container: {
22 | height: 45,
23 | width: '50%',
24 | backgroundColor: '#1b1b33',
25 | justifyContent: 'center',
26 | alignItems: 'center',
27 | },
28 | title: { color: 'white', fontSize: 16 },
29 | });
30 |
31 | export default FormSelectorBtn;
32 |
--------------------------------------------------------------------------------
/app/components/FormSubmitButton.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { View, StyleSheet, TouchableOpacity, Text } from 'react-native';
3 |
4 | const FormSubmitButton = ({ title, submitting, onPress }) => {
5 | const backgroundColor = submitting
6 | ? 'rgba(27,27,51,0.4)'
7 | : 'rgba(27,27,51,1)';
8 |
9 | return (
10 |
14 | {title}
15 |
16 | );
17 | };
18 |
19 | const styles = StyleSheet.create({
20 | container: {
21 | height: 45,
22 | borderRadius: 8,
23 | justifyContent: 'center',
24 | alignItems: 'center',
25 | },
26 | });
27 |
28 | export default FormSubmitButton;
29 |
--------------------------------------------------------------------------------
/app/components/Home.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { View, StyleSheet, Text } from 'react-native';
3 |
4 | const Home = () => {
5 | return (
6 |
7 | Home
8 |
9 | );
10 | };
11 |
12 | const styles = StyleSheet.create({
13 | container: {
14 | flex: 1,
15 | justifyContent: 'center',
16 | alignItems: 'center',
17 | },
18 | });
19 |
20 | export default Home;
21 |
--------------------------------------------------------------------------------
/app/components/ImageUpload.js:
--------------------------------------------------------------------------------
1 | import React, { useState } from 'react';
2 | import { View, StyleSheet, TouchableOpacity, Text, Image } from 'react-native';
3 | import * as ImagePicker from 'expo-image-picker';
4 | import { StackActions } from '@react-navigation/native';
5 |
6 | import client from '../api/client';
7 |
8 | const ImageUpload = props => {
9 | const [profileImage, setProfileImage] = useState('');
10 | const [progress, setProgress] = useState(0);
11 | const { token } = props.route.params;
12 |
13 | const openImageLibrary = async () => {
14 | const { status } = await ImagePicker.requestMediaLibraryPermissionsAsync();
15 |
16 | if (status !== 'granted') {
17 | alert('Sorry, we need camera roll permissions to make this work!');
18 | }
19 |
20 | if (status === 'granted') {
21 | const response = await ImagePicker.launchImageLibraryAsync({
22 | mediaTypes: ImagePicker.MediaTypeOptions.Images,
23 | allowsEditing: true,
24 | });
25 |
26 | if (!response.cancelled) {
27 | setProfileImage(response.uri);
28 | }
29 | }
30 | };
31 |
32 | const uploadProfileImage = async () => {
33 | const formData = new FormData();
34 | formData.append('profile', {
35 | name: new Date() + '_profile',
36 | uri: profileImage,
37 | type: 'image/jpg',
38 | });
39 |
40 | try {
41 | const res = await client.post('/upload-profile', formData, {
42 | headers: {
43 | Accept: 'application/json',
44 | 'Content-Type': 'multipart/form-data',
45 | authorization: `JWT ${token}`,
46 | },
47 | });
48 |
49 | if (res.data.success) {
50 | props.navigation.dispatch(StackActions.replace('UserProfile'));
51 | }
52 | } catch (error) {
53 | console.log(error.message);
54 | }
55 | };
56 |
57 | return (
58 |
59 |
60 |
64 | {profileImage ? (
65 |
69 | ) : (
70 | Upload Profile Image
71 | )}
72 |
73 | Skip
74 | {profileImage ? (
75 |
82 | Upload
83 |
84 | ) : null}
85 |
86 |
87 | );
88 | };
89 |
90 | const styles = StyleSheet.create({
91 | container: {
92 | flex: 1,
93 | justifyContent: 'center',
94 | alignItems: 'center',
95 | },
96 | uploadBtnContainer: {
97 | height: 125,
98 | width: 125,
99 | borderRadius: 125 / 2,
100 | justifyContent: 'center',
101 | alignItems: 'center',
102 | borderStyle: 'dashed',
103 | borderWidth: 1,
104 | overflow: 'hidden',
105 | },
106 | uploadBtn: {
107 | textAlign: 'center',
108 | fontSize: 16,
109 | opacity: 0.3,
110 | fontWeight: 'bold',
111 | },
112 | skip: {
113 | textAlign: 'center',
114 | padding: 10,
115 | fontSize: 16,
116 | fontWeight: 'bold',
117 | textTransform: 'uppercase',
118 | letterSpacing: 2,
119 | opacity: 0.5,
120 | },
121 | });
122 |
123 | export default ImageUpload;
124 |
--------------------------------------------------------------------------------
/app/components/LoginForm.js:
--------------------------------------------------------------------------------
1 | import React, { useState } from 'react';
2 | import { View, StyleSheet, Text, TextInput } from 'react-native';
3 | import client from '../api/client';
4 | import { useLogin } from '../context/LoginProvider';
5 | import { isValidEmail, isValidObjField, updateError } from '../utils/methods';
6 | import FormContainer from './FormContainer';
7 | import FormInput from './FormInput';
8 | import FormSubmitButton from './FormSubmitButton';
9 |
10 | const LoginForm = () => {
11 | const { setIsLoggedIn, setProfile } = useLogin();
12 | const [userInfo, setUserInfo] = useState({
13 | email: '',
14 | password: '',
15 | });
16 |
17 | const [error, setError] = useState('');
18 |
19 | const { email, password } = userInfo;
20 |
21 | const handleOnChangeText = (value, fieldName) => {
22 | setUserInfo({ ...userInfo, [fieldName]: value });
23 | };
24 |
25 | const isValidForm = () => {
26 | if (!isValidObjField(userInfo))
27 | return updateError('Required all fields!', setError);
28 |
29 | if (!isValidEmail(email)) return updateError('Invalid email!', setError);
30 |
31 | if (!password.trim() || password.length < 8)
32 | return updateError('Password is too short!', setError);
33 |
34 | return true;
35 | };
36 |
37 | const submitForm = async () => {
38 | if (isValidForm()) {
39 | try {
40 | const res = await client.post('/sign-in', { ...userInfo });
41 |
42 | if (res.data.success) {
43 | setUserInfo({ email: '', password: '' });
44 | setProfile(res.data.user);
45 | setIsLoggedIn(true);
46 | }
47 |
48 | console.log(res.data);
49 | } catch (error) {
50 | console.log(error);
51 | }
52 | }
53 | };
54 |
55 | return (
56 |
57 | {error ? (
58 |
59 | {error}
60 |
61 | ) : null}
62 | handleOnChangeText(value, 'email')}
65 | label='Email'
66 | placeholder='example@email.com'
67 | autoCapitalize='none'
68 | />
69 | handleOnChangeText(value, 'password')}
72 | label='Password'
73 | placeholder='********'
74 | autoCapitalize='none'
75 | secureTextEntry
76 | />
77 |
78 |
79 | );
80 | };
81 |
82 | const styles = StyleSheet.create({});
83 |
84 | export default LoginForm;
85 |
--------------------------------------------------------------------------------
/app/components/SignupForm.js:
--------------------------------------------------------------------------------
1 | import React, { useState } from 'react';
2 | import { View, StyleSheet, Text } from 'react-native';
3 |
4 | import { isValidEmail, isValidObjField, updateError } from '../utils/methods';
5 | import FormContainer from './FormContainer';
6 | import FormInput from './FormInput';
7 | import FormSubmitButton from './FormSubmitButton';
8 | import { StackActions } from '@react-navigation/native';
9 |
10 | import { Formik } from 'formik';
11 | import * as Yup from 'yup';
12 |
13 | import client from '../api/client';
14 |
15 | const validationSchema = Yup.object({
16 | fullname: Yup.string()
17 | .trim()
18 | .min(3, 'Invalid name!')
19 | .required('Name is required!'),
20 | email: Yup.string().email('Invalid email!').required('Email is required!'),
21 | password: Yup.string()
22 | .trim()
23 | .min(8, 'Password is too short!')
24 | .required('Password is required!'),
25 | confirmPassword: Yup.string().equals(
26 | [Yup.ref('password'), null],
27 | 'Password does not match!'
28 | ),
29 | });
30 |
31 | const SignupForm = ({ navigation }) => {
32 | const userInfo = {
33 | fullname: '',
34 | email: '',
35 | password: '',
36 | confirmPassword: '',
37 | };
38 |
39 | const [error, setError] = useState('');
40 |
41 | const { fullname, email, password, confirmPassword } = userInfo;
42 |
43 | const handleOnChangeText = (value, fieldName) => {
44 | setUserInfo({ ...userInfo, [fieldName]: value });
45 | };
46 |
47 | const isValidForm = () => {
48 | // we will accept only if all of the fields have value
49 | if (!isValidObjField(userInfo))
50 | return updateError('Required all fields!', setError);
51 | // if valid name with 3 or more characters
52 | if (!fullname.trim() || fullname.length < 3)
53 | return updateError('Invalid name!', setError);
54 | // only valid email id is allowed
55 | if (!isValidEmail(email)) return updateError('Invalid email!', setError);
56 | // password must have 8 or more characters
57 | if (!password.trim() || password.length < 8)
58 | return updateError('Password is less then 8 characters!', setError);
59 | // password and confirm password must be the same
60 | if (password !== confirmPassword)
61 | return updateError('Password does not match!', setError);
62 |
63 | return true;
64 | };
65 |
66 | const sumbitForm = () => {
67 | if (isValidForm()) {
68 | // submit form
69 | console.log(userInfo);
70 | }
71 | };
72 |
73 | const signUp = async (values, formikActions) => {
74 | const res = await client.post('/create-user', {
75 | ...values,
76 | });
77 |
78 | if (res.data.success) {
79 | const signInRes = await client.post('/sign-in', {
80 | email: values.email,
81 | password: values.password,
82 | });
83 | if (signInRes.data.success) {
84 | navigation.dispatch(
85 | StackActions.replace('ImageUpload', {
86 | token: signInRes.data.token,
87 | })
88 | );
89 | }
90 | }
91 |
92 | formikActions.resetForm();
93 | formikActions.setSubmitting(false);
94 | };
95 |
96 | return (
97 |
98 |
103 | {({
104 | values,
105 | errors,
106 | touched,
107 | isSubmitting,
108 | handleChange,
109 | handleBlur,
110 | handleSubmit,
111 | }) => {
112 | const { fullname, email, password, confirmPassword } = values;
113 | return (
114 | <>
115 |
123 |
132 |
142 |
152 |
157 | >
158 | );
159 | }}
160 |
161 |
162 | );
163 | };
164 |
165 | const styles = StyleSheet.create({});
166 |
167 | export default SignupForm;
168 |
--------------------------------------------------------------------------------
/app/components/Tasks.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { View, StyleSheet, Text } from 'react-native';
3 |
4 | const Tasks = () => {
5 | return (
6 |
7 | Tasks
8 |
9 | );
10 | };
11 |
12 | const styles = StyleSheet.create({
13 | container: {
14 | flex: 1,
15 | justifyContent: 'center',
16 | alignItems: 'center',
17 | },
18 | });
19 |
20 | export default Tasks;
21 |
--------------------------------------------------------------------------------
/app/components/UserProfile.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { View, StyleSheet, Text } from 'react-native';
3 |
4 | const UserProfile = () => {
5 | return (
6 |
7 | Profile
8 |
9 | );
10 | };
11 |
12 | const styles = StyleSheet.create({
13 | container: {
14 | flex: 1,
15 | alignItems: 'center',
16 | justifyContent: 'center',
17 | },
18 | });
19 |
20 | export default UserProfile;
21 |
--------------------------------------------------------------------------------
/app/context/LoginProvider.js:
--------------------------------------------------------------------------------
1 | import React, { createContext, useContext, useState } from 'react';
2 |
3 | const LoginContext = createContext();
4 |
5 | const LoginProvider = ({ children }) => {
6 | const [isLoggedIn, setIsLoggedIn] = useState(false);
7 | const [profile, setProfile] = useState({});
8 |
9 | return (
10 |
13 | {children}
14 |
15 | );
16 | };
17 |
18 | export const useLogin = () => useContext(LoginContext);
19 |
20 | export default LoginProvider;
21 |
--------------------------------------------------------------------------------
/app/utils/methods.js:
--------------------------------------------------------------------------------
1 | export const isValidObjField = obj => {
2 | return Object.values(obj).every(value => value.trim());
3 | };
4 |
5 | export const updateError = (error, stateUpdater) => {
6 | stateUpdater(error);
7 | setTimeout(() => {
8 | stateUpdater('');
9 | }, 2500);
10 | };
11 |
12 | export const isValidEmail = value => {
13 | const regx = /^([A-Za-z0-9_\-\.])+\@([A-Za-z0-9_\-\.])+\.([A-Za-z]{2,4})$/;
14 | return regx.test(value);
15 | };
16 |
--------------------------------------------------------------------------------
/assets/adaptive-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ndpniraj/react-native-auth-app-front-end/e434cf65d8a931632cd1f0b3e35ff47e32dd6634/assets/adaptive-icon.png
--------------------------------------------------------------------------------
/assets/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ndpniraj/react-native-auth-app-front-end/e434cf65d8a931632cd1f0b3e35ff47e32dd6634/assets/favicon.png
--------------------------------------------------------------------------------
/assets/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ndpniraj/react-native-auth-app-front-end/e434cf65d8a931632cd1f0b3e35ff47e32dd6634/assets/icon.png
--------------------------------------------------------------------------------
/assets/splash.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ndpniraj/react-native-auth-app-front-end/e434cf65d8a931632cd1f0b3e35ff47e32dd6634/assets/splash.png
--------------------------------------------------------------------------------
/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = function(api) {
2 | api.cache(true);
3 | return {
4 | presets: ['babel-preset-expo'],
5 | };
6 | };
7 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "main": "node_modules/expo/AppEntry.js",
3 | "scripts": {
4 | "start": "expo start",
5 | "android": "expo start --android",
6 | "ios": "expo start --ios",
7 | "web": "expo start --web",
8 | "eject": "expo eject"
9 | },
10 | "dependencies": {
11 | "@react-native-community/masked-view": "0.1.10",
12 | "@react-navigation/drawer": "^5.12.5",
13 | "@react-navigation/native": "^5.9.4",
14 | "@react-navigation/stack": "^5.14.5",
15 | "axios": "^0.21.1",
16 | "expo": "~41.0.1",
17 | "expo-image-picker": "~10.1.4",
18 | "expo-status-bar": "~1.0.4",
19 | "formik": "^2.2.6",
20 | "react": "16.13.1",
21 | "react-dom": "16.13.1",
22 | "react-native": "https://github.com/expo/react-native/archive/sdk-41.0.0.tar.gz",
23 | "react-native-gesture-handler": "~1.10.2",
24 | "react-native-reanimated": "~2.1.0",
25 | "react-native-safe-area-context": "3.2.0",
26 | "react-native-screens": "~3.0.0",
27 | "react-native-web": "~0.13.12",
28 | "yup": "^0.32.9"
29 | },
30 | "devDependencies": {
31 | "@babel/core": "^7.9.0"
32 | },
33 | "private": true
34 | }
35 |
--------------------------------------------------------------------------------