Merge pull request #17 from henrydays/Borges

login w/ Jwt email e password
This commit is contained in:
Henrique Dias 2019-01-24 21:57:28 +00:00 committed by GitHub
commit b5e4a9bad4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 287 additions and 119 deletions

View File

@ -1,6 +1,7 @@
/**
* Sample React Native App
* https://github.com/facebook/react-native
* Enei 2019 React Native App
*
* João Borges
*
* @format
* @flow
@ -9,26 +10,58 @@
import React, {Component} from 'react';
import Icon from 'react-native-vector-icons/AntDesign';
import AppIntroSlider from 'react-native-app-intro-slider'
import {Platform, StyleSheet, Text, View, StatusBar} from 'react-native';
import Routes from './Router'
import deviceStorage from '././services/deviceStorage'
import Router from './Router'
import Login from './screens/Login'
import {AsyncStorage, ActivityIndicator} from 'react-native';
import AuthLoadingScreen from "./screens/AuthLoading";
export default class App extends Component {
constructor(props) {
super(props);
this.state = {
showRealApp: false,
firstLogin: null,
jwt: '',
loading: true
};
}
renderApp = () => (
<View style={{flex: 1}}>
<Routes />
</View>
);
newJWT(jwt) {
this.setState({
jwt: jwt
});
}
//componentDidMount() is invoked immediately after a component is mounted
/*componentDidMount() {
AsyncStorage.removeItem('firstLogin');
AsyncStorage.getItem('firstLogin').then((value) => {
console.log('aqui')
if (value == null) {
//setItem (key: string, value: string)
deviceStorage.saveItem('firstLogin', JSON.stringify(true));
}
else {
//this.setState({firstLogin: false});
}
this.setState({loading: false});
})
}*/
//Buttons do Intro Slider
_renderNextButton = () => {
return (
<View style={styles.buttonCircle}>
@ -36,7 +69,7 @@ export default class App extends Component {
name='right'
color='rgba(255, 255, 255, .9)'
size={24}
style={{ backgroundColor: 'transparent' }} />
style={{backgroundColor: 'transparent'}}/>
</View>
);
};
@ -48,38 +81,56 @@ export default class App extends Component {
name='check'
color='rgba(255, 255, 255, .9)'
size={24}
style={{ backgroundColor: 'transparent' }}
style={{backgroundColor: 'transparent'}}
/>
</View>
);
};
_onDone = () => {
this.state({ showRealApp: true });
};
//--Buttons do Intro Slider
render() {
if (this.state.showRealApp) {
return (
this.renderApp()
);
}
else {
return(
<AppIntroSlider
slides={slides}
renderDoneButton={this._renderDoneButton}
renderNextButton={this._renderNextButton}
/>
);
}
console.log('inside render');
return (
<Router />
)
/* if (this.state.loading) {
}
else {
if (this.state.firstLaunch) {
return (
<AppIntroSlider
slides={slides}
renderDoneButton={this._renderDoneButton}
renderNextButton={this._renderNextButton}
onDone={() => this.setState({firstLaunch: false})}
/>
);
}
else if (!this.state.firstLaunch && !this.state.jwt) { //&& !this.state.jwt}
return (
<View style={{flex: 1}}>
<Login/>
</View>
)
}
else { // !this.state.firstLaunch && this.state.jwt
return (
<View style={{flex: 1}}>
<Routes />
</View>
)
}*/
}
}
//Styles
const styles = StyleSheet.create({
container: {
@ -88,16 +139,6 @@ const styles = StyleSheet.create({
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
welcome: {
fontSize: 20,
textAlign: 'center',
margin: 10,
},
instructions: {
textAlign: 'center',
color: '#333333',
marginBottom: 5,
},
buttonCircle: {
width: 40,
@ -114,7 +155,6 @@ const styles = StyleSheet.create({
});
//Introducing Slides
const slides = [
{

View File

@ -14,6 +14,11 @@ export const validation = {
presence: {
message: 'Introduza uma password'
},
},
new_password: {
presence: {
message: 'Introduza uma password'
},
length: {
minimum: {
value: 6,

View File

@ -1,11 +1,46 @@
import React from 'react';
import { createStackNavigator, createAppContainer } from 'react-navigation';
import {
createStackNavigator,
createAppContainer,
createSwitchNavigator,
createBottomTabNavigator
} from 'react-navigation';
import * as Screens from './screens';
import Login from './screens/Login'
import AuthLoadingScreen from './screens/AuthLoading'
const ExplorerApp = createStackNavigator({
Home: { screen: Screens.Home },
Login: { screen: Screens.Login}
const AppStack = createBottomTabNavigator(
{
Home: {
screen: Screens.Home
}
}
);
});
const AuthStack = createStackNavigator(
{
Login: {
screen: Login,
},
},
/*{
headerMode: 'none',
navigationOptions: {
headerVisible: false,
}
}*/
);
export default createAppContainer(createSwitchNavigator(
{
AuthLoading: AuthLoadingScreen,
App: AppStack,
Auth: AuthStack,
},
{
initialRouteName: 'AuthLoading'
})
);
export default createAppContainer(ExplorerApp);

BIN
App/app/assets/img/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.0 KiB

View File

@ -5,6 +5,13 @@ export const UtilStyles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: 'white',
},
containerLoading: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
titleText: {
fontSize: 20,
@ -90,6 +97,14 @@ export const UtilStyles = StyleSheet.create({
},
loginImage: {
justifyContent: 'center',
alignItems: 'center',
alignSelf: 'center',
width: 160,
height: 149.2,
},
//------------------//
inputLabel: {
paddingBottom: 15

View File

@ -0,0 +1,39 @@
import React, {Component} from 'react';
import {
ActivityIndicator,
AsyncStorage,
Button,
StatusBar,
StyleSheet,
View,
} from 'react-native';
import {UtilStyles} from '../assets/styles'
export default class AuthLoadingScreen extends Component {
constructor() {
super();
this._bootstrapAsync();
}
// Fetch the token from storage then navigate to our appropriate place
_bootstrapAsync = async () => {
const token = await AsyncStorage.getItem('userToken');
// This will switch to the App screen or Auth screen and this loading
// screen will be unmounted and thrown away.
this.props.navigation.navigate(token ? 'App' : 'Auth');
};
// Render Loading
render() {
return (
<View style={UtilStyles.containerLoading}>
<ActivityIndicator size='large' color="rgba(000,000,000,1)"/>
<StatusBar barStyle="default" />
</View>
);
}
}

View File

@ -3,22 +3,25 @@ import { Button, View, Text } from 'react-native';
import {RkButton,
RkTheme } from 'react-native-ui-kitten';
import deviceStorage from '../services/deviceStorage';
export class Home extends Component {
static navigationOptions = {
title: 'Home'
};
_deleteToken = () => {
deviceStorage.deleteJWT();
};
render() {
const {navigate} = this.props.navigation;
const { navigate } = this.props.navigation;
return (
<View style={{
flex: 1,
alignItems:'center',
justifyContent:'center'
}}>
<RkButton title="Go to Login screen"
onPress={() => this.props.navigation.navigate('Login')}/>
<View style={{flex:1, alignItems: 'center', alignContent: 'center'}}>
<RkButton onPress= { () => this._deleteToken() }>Apagar Token</RkButton>
</View>
);
}

View File

@ -1,5 +1,5 @@
import React, {Component, Fragment} from 'react'
import {View, Text, TextInput} from 'react-native'
import {View, Text, TextInput, Image, ScrollView} from 'react-native'
import {RkTheme, RkButton, RkTextInput, RkText} from 'react-native-ui-kitten'
import {UtilStyles} from '../assets/styles'
@ -8,10 +8,11 @@ import {Validate} from '../Helpers/Validation'
import axios from 'axios';
import deviceStorage from '../services/deviceStorage';
export class Login extends Component {
static navigationOptions = {
title: ''
export default class Login extends Component {
static navigationOptions = {
header: null,
};
constructor(props) {
@ -19,6 +20,8 @@ export class Login extends Component {
this.state = {
formValid: false,
email: '',
emailError: false,
emailErrorMessage: '',
@ -29,65 +32,101 @@ export class Login extends Component {
loading: false
};
}
_validatelogin = (email, password) => {
let valid = null;
let v = Validate('email', email);
this.setState({emailError: v[0], emailErrorMessage: v[1]});
v = Validate('password', password);
// setState is asynchronous and so trying to work with state directly after a setState
// call won't work as the update won't necessarily have run. Instead you can use the second argument to setState which is a callback
this.setState({passwordError: v[0], passwordErrorMessage: v[1]}, function () {
console.log('Email error: ' + this.state.emailError + ' Pass Error: ' + this.state.passwordError);
});
if (this.state.emailError && this.state.passwordError)
this.setState({formValid: false});
else
this.setState({formValid: true});
};
login() {
const {email, password, formValid} = this.state;
this.setState({loading: true});
this.setState({ error: '', loading: true });
this._validatelogin(email, password);
// NOTE HTTP is insecure, only post to HTTPS in production apps
console.log(formValid);
axios.post("http://localhost:4000/api/v1/sign_up",{
user: {
email: this.state.email,
password: this.state.password,
}
},)
.then((response) => {
// Handle the JWT response here
deviceStorage.saveItem('id_token', response.data.jwt);
})
.catch((error) => {
// Handle returned errors here
});
if (formValid) {
axios.post("https://reqres.in/api/login", {
email: email,
password: password
}) //https://reqres.in/api/login email: email, password: password,
.then(response => {
console.log(response)
// Save Token
deviceStorage.saveItem('userToken', response.data.token);
})
.catch((error) => {
console.log(error)
});
}
}
render() {
const {navigate} = this.props.navigation;
//const { email, password, error, loading } = this.state;
return (
<ScrollView>
<View style={[UtilStyles.section, {backgroundColor: RkTheme.current.colors.input}]}>
<Image style={UtilStyles.loginImage}
source={require('../assets/img/logo.png')}
/>
<View style={[UtilStyles.section, {backgroundColor: RkTheme.current.colors.input}]}>
<View style={UtilStyles.rowContainer}>
<View style={{flex: 1}}>
<RkTextInput rkType='rounded' style={ this.state.emailError ? UtilStyles.errorInput : ''}
placeholder='Login' keyboardType='email-address'
onChangeText={ (email) => {
this.setState({email: email});
let v = Validate('email', email);
this.setState({emailError: v[0], emailErrorMessage: v[1]})
}}
value={this.state.email}
/>
{this.state.emailError && <RkText style={UtilStyles.errorMsg}>{this.state.emailErrorMessage}</RkText>}
<RkTextInput
secureTextEntry={true} style={ this.state.passwordError ? UtilStyles.errorInput : '' }
rkType='rounded' placeholder='Password'
onChangeText={ (password) => {
this.setState({password: password});
let v = Validate('password', password);
this.setState({passwordError: v[0], passwordErrorMessage: v[1]})
}}
/>
{this.state.passwordError && <RkText style={UtilStyles.errorMsg}>{this.state.passwordErrorMessage}</RkText>}
<View style={UtilStyles.rowContainer}>
<View style={{flex: 1}}>
<RkTextInput rkType='rounded' style={this.state.emailError ? UtilStyles.errorInput : ''}
placeholder='Login' keyboardType='email-address'
onChangeText={(email) => {
this.setState({email: email});
}}
value={this.state.email}
/>
{this.state.emailError &&
<RkText style={UtilStyles.errorMsg}>{this.state.emailErrorMessage}</RkText>}
<RkTextInput
secureTextEntry={true} style={this.state.passwordError ? UtilStyles.errorInput : ''}
rkType='rounded' placeholder='Password'
onChangeText={(pass) => {
this.setState({password: pass});
}}
value={this.state.password}
/>
{this.state.passwordError &&
<RkText style={UtilStyles.errorMsg}>{this.state.passwordErrorMessage}</RkText>}
</View>
</View>
<RkButton style={{marginTop: 30}} rkType='rounded xlarge' onPress={() => this.login()}>
Login
</RkButton>
</View>
<RkButton rkType='rounded xlarge' onPress={() => this.login()}>
Login
</RkButton>
</View>
</ScrollView>
);
}

View File

@ -1,2 +1 @@
export * from './Home';
export * from './Login';
export * from './Home';

View File

@ -5,16 +5,16 @@ const deviceStorage = {
async saveItem(key, value) {
try {
await AsyncStorage.setItem(key, value);
console.log('saved')
} catch (error) {
console.log(`Erro a guardar! \n${error.message}`);
}
},
//Carregar token
async loadJWT() {
try {
const value = await AsyncStorage.getItem('id_token');
const value = await AsyncStorage.getItem('userToken');
if (value !== null) {
this.setState({
jwt: value,
@ -33,22 +33,15 @@ const deviceStorage = {
//Apagar Token
async deleteJWT() {
try{
await AsyncStorage.removeItem('id_token')
.then(
() => {
this.setState({
jwt: ''
})
}
);
try {
await AsyncStorage.removeItem('userToken');
} catch (error) {
console.log(`Erro a ler token \n${error.message}`);
}
}
};
export default deviceStorage;