diff --git a/salamander-app/.gitignore b/salamander-app/.gitignore index 73e9e945749da10000301c265cc32b465dcf25c0..83c683305fa62ff5b9e91a7e815c06a32e06c3e5 100644 --- a/salamander-app/.gitignore +++ b/salamander-app/.gitignore @@ -8,6 +8,6 @@ npm-debug.* *.mobileprovision *.orig.* web-build/ - +.idea # macOS .DS_Store diff --git a/salamander-app/APIkit.js b/salamander-app/APIkit.js new file mode 100644 index 0000000000000000000000000000000000000000..fdbee3d4a8c59573819879305dcf3dfd9c508d24 --- /dev/null +++ b/salamander-app/APIkit.js @@ -0,0 +1,18 @@ +import axios from 'axios'; + +// Create axios client, pre-configured with baseURL +let APIKit = axios.create({ + baseURL: 'http://10.22.205.170:5000', + timeout: 10000, + headers: {'Content-Type': 'multipart/form-data'} +}); + +// Set JSON Web Token in Client to be included in all calls +export const setClientToken = token => { + APIKit.interceptors.request.use(function(config) { + config.headers.Authorization = `Bearer ${token}`; + return config; + }); +}; + +export default APIKit; \ No newline at end of file diff --git a/salamander-app/App.js b/salamander-app/App.js index dd1e312ecff51cc001085c94ad871f4207490c89..606e48415ee7de07a9af8dfee4345c7031b87646 100644 --- a/salamander-app/App.js +++ b/salamander-app/App.js @@ -13,13 +13,9 @@ export default function App() { const authContext = React.useMemo(() => { return { - signIn: () => { + signInApp: () => { setIsLoading(false); - setUserToken('asdf'); - }, - signUp: () => { - setIsLoading(false); - setUserToken('asdf'); + setUserToken(true); }, signOut: () => { setIsLoading(false); @@ -39,3 +35,4 @@ export default function App() { ); } + diff --git a/salamander-app/components/MyTextField.js b/salamander-app/components/MyTextField.js index 20478f9bedeb886397526ae01820ed9d606b404e..c8f7ca958284d037c5f6c4ca2bf17c0b72822ffe 100644 --- a/salamander-app/components/MyTextField.js +++ b/salamander-app/components/MyTextField.js @@ -3,7 +3,6 @@ import { TextInput } from 'react-native-paper'; import { StyleSheet } from 'react-native' const MyTextField = (props) => { - const [text, setText] = React.useState(''); return ( <TextInput @@ -12,8 +11,8 @@ const MyTextField = (props) => { secureTextEntry={props.secureTextEntry} mode={props.mode} placeholder={props.placeholder} - value={text} - onChangeText={text => setText(text)} + value={props.text} + onChangeText={props.onChangeText} /> ); }; diff --git a/salamander-app/screens/ProfileScreen.js b/salamander-app/screens/ProfileScreen.js index 348f0775f0bd3fc657039dedc2a21545a0512c7e..21a5b42a8706cfc8b2bdad916413c905a787208a 100644 --- a/salamander-app/screens/ProfileScreen.js +++ b/salamander-app/screens/ProfileScreen.js @@ -1,6 +1,8 @@ -import React from 'react' +import React, { useState, useEffect } from 'react' import { StyleSheet, Text, View, ScrollView } from 'react-native' import { Divider } from 'react-native-paper'; +import AsyncStorage from '@react-native-async-storage/async-storage'; +import { useAsyncStorage } from '@react-native-async-storage/async-storage'; import MyTouchableOpacity from '../components/MyTouchableOpacity'; import { AuthContext } from '../constants/context'; @@ -9,14 +11,26 @@ const ProfileScreen = ({ navigation }) => { const { signOut } = React.useContext(AuthContext); + const [value, setValue] = React.useState({}); + + const readItemFromStorage = async () => { + const jsonValue = await AsyncStorage.getItem('@user') + let user = JSON.parse(jsonValue); + setValue(user); + }; + + useEffect(() => { + readItemFromStorage(); + }, []); + return ( <ScrollView> <View style={styles.container}> <Text style={styles.text}>Personal Data</Text> <Divider /> - <MyTouchableOpacity title="Name" placeholder="Ola Nordmann" icon="chevron-right" onPress={() => navigation.push("ChangeName")} /> + <MyTouchableOpacity title="Name" placeholder={value.name} icon="chevron-right" onPress={() => navigation.push("ChangeName")} /> <Divider /> - <MyTouchableOpacity title="Email" placeholder="ola@nordmann.com" icon="chevron-right" onPress={() => navigation.push("ChangeEmailVerify")} /> + <MyTouchableOpacity title="Email" placeholder={value.email} icon="chevron-right" onPress={() => navigation.push("ChangeEmailVerify")} /> <Divider /> <MyTouchableOpacity title="Password" icon="chevron-right" onPress={() => navigation.push("ChangePasswordVerify")} /> <Divider /> diff --git a/salamander-app/screens/SignInScreen.js b/salamander-app/screens/SignInScreen.js index 269e5c917259f9f1252d28f4929553f907436cf1..15d04ceba5d70c0ddb1c0365b2dcaf091f854c4f 100644 --- a/salamander-app/screens/SignInScreen.js +++ b/salamander-app/screens/SignInScreen.js @@ -1,13 +1,47 @@ import React from 'react' import { StyleSheet, Text, View, Image, ScrollView } from 'react-native' +import AsyncStorage from '@react-native-async-storage/async-storage'; import MyButton from '../components/MyButton' import { AuthContext } from '../constants/context' import MyTextField from '../components/MyTextField' +import APIKit, {setClientToken} from '../APIkit'; const SignInScreen = ({ navigation }) => { - const { signIn } = React.useContext(AuthContext); + const { signInApp } = React.useContext(AuthContext); + + const [email, setEmail] = React.useState(''); + const [password, setPassword] = React.useState(''); + + function signIn() { + let bodyFormData = new FormData(); + bodyFormData.append("email", email) + bodyFormData.append("password", password) + + APIKit.post('/login', bodyFormData) + .then(function (response) { + if (response.data.access_token) { + setClientToken(response.data.access_token); + signInApp(response.data.access_token); + storeData(response.data); + } + console.log(response.data); + }) + .catch(function (response) { + //handle error + console.log(response); + }); + } + + const storeData = async (value) => { + try { + const jsonValue = JSON.stringify(value) + await AsyncStorage.setItem('@user', jsonValue) + } catch (e) { + // saving error + } + } return ( <ScrollView style={styles.scrollView}> @@ -18,8 +52,8 @@ const SignInScreen = ({ navigation }) => { source={require('../assets/images/ninaLogo.png')} /> </View> - <MyTextField style={styles.textfield} mode='outlined' placeholder='Email' label='Email'/> - <MyTextField style={styles.textfield} mode='outlined' secureTextEntry={true} placeholder='Password' label='password'/> + <MyTextField style={styles.textfield} mode='outlined' placeholder='Email' label='Email' onChangeText={email => setEmail(email)} value={email} /> + <MyTextField style={styles.textfield} mode='outlined' secureTextEntry={true} placeholder='Password' label='password' onChangeText={password => setPassword(password)} value={password}/> <MyButton style={styles.button} title="Sign In" onPress={() => signIn()} /> <Text style={styles.text} onPress={() => navigation.push("SignUp")}>Don't have a user?</Text> </View> diff --git a/salamander-app/screens/SignUpScreen.js b/salamander-app/screens/SignUpScreen.js index b27efa9029c3eac4644968fa5bff99eb19002c7b..d358716e9198a5872fad758ef32d0474fb9fd851 100644 --- a/salamander-app/screens/SignUpScreen.js +++ b/salamander-app/screens/SignUpScreen.js @@ -1,9 +1,36 @@ -import React from 'react' +import React, { useState } from 'react' import { StyleSheet, Text, View, Image, ScrollView } from 'react-native' import MyTextField from '../components/MyTextField' import MyButton from '../components/MyButton' +import APIKit from '../APIkit'; + const SignUpScreen = ({ navigation }) => { + + const [name, setName] = React.useState(''); + const [email, setEmail] = React.useState(''); + const [password, setPassword] = React.useState(''); + const [confirmPassword, setConfirmPassword] = React.useState(''); + + function signUp() { + let bodyFormData = new FormData(); + bodyFormData.append("name", name) + bodyFormData.append("email", email) + bodyFormData.append("password", password) + bodyFormData.append("confirmPassword", confirmPassword) + + + APIKit.post('/user', bodyFormData) + .then(function (response) { + //handle success + console.log(response.data.message); + }) + .catch(function (response) { + //handle error + console.log(response); + }); + } + return ( <ScrollView style={styles.scrollView}> <View style={styles.container}> @@ -13,11 +40,11 @@ const SignUpScreen = ({ navigation }) => { source={require('../assets/images/ninaLogo.png')} /> </View> - <MyTextField style={styles.textfield} mode='outlined' placeholder='Name' label='Name'/> - <MyTextField style={styles.textfield} mode='outlined' placeholder='Email' label='Email'/> - <MyTextField style={styles.textfield} mode='outlined' secureTextEntry={true} placeholder='Password' label='password'/> - <MyTextField style={styles.textfield} mode='outlined' secureTextEntry={true} placeholder='Confirm Password' label='Confirm Password'/> - <MyButton style={styles.button} title="Sign Up" onPress={() => console.log("Pressed")} /> + <MyTextField style={styles.textfield} mode='outlined' placeholder='Name' label='Name' onChangeText={name => setName(name)} value={name} /> + <MyTextField style={styles.textfield} mode='outlined' placeholder='Email' label='Email' onChangeText={email => setEmail(email)} value={email} /> + <MyTextField style={styles.textfield} mode='outlined' secureTextEntry={true} placeholder='Password' label='password' onChangeText={password => setPassword(password)} value={password} /> + <MyTextField style={styles.textfield} mode='outlined' secureTextEntry={true} placeholder='Confirm Password' label='Confirm Password' onChangeText={confirmPassword => setConfirmPassword(confirmPassword)} value={confirmPassword} /> + <MyButton style={styles.button} title="Sign Up" onPress={() => signUp()} /> <Text style={styles.text} onPress={() => navigation.push("SignIn")}>Already have a user?</Text> </View> </ScrollView> @@ -28,31 +55,31 @@ export default SignUpScreen const styles = StyleSheet.create({ container: { - flex: 1, + flex: 1, backgroundColor: "lightblue", - justifyContent: 'center', + justifyContent: 'center', padding: 40 - }, + }, textfield: { - margin: 2, - }, + margin: 2, + }, button: { - marginTop: 15, + marginTop: 15, margin: 50 - }, + }, text: { - alignSelf: "center", + alignSelf: "center", marginTop: 15, fontSize: 15 - }, + }, logo: { width: 190, height: 100, }, image: { - alignItems: "center", + alignItems: "center", paddingBottom: 15 - }, + }, scrollView: { backgroundColor: 'lightblue', }