Compare commits
No commits in common. "5aa3afd38351f9daf5ea12b3729c593a1ec372c3" and "5bf1e7586bd32faa3d0af8755eafc0b4fdf113ad" have entirely different histories.
5aa3afd383
...
5bf1e7586b
7 changed files with 73 additions and 417 deletions
|
|
@ -1,143 +1,15 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import ConnectionManager, {ERROR_TYPE} from "../../managers/ConnectionManager";
|
import ConnectionManager, {ERROR_TYPE} from "../../managers/ConnectionManager";
|
||||||
import * as SecureStore from 'expo-secure-store';
|
|
||||||
|
|
||||||
let fetch = require('isomorphic-fetch'); // fetch is not implemented in nodeJS but in react-native
|
|
||||||
|
|
||||||
|
const fetch = require('isomorphic-fetch'); // fetch is not implemented in nodeJS but in react-native
|
||||||
const c = ConnectionManager.getInstance();
|
const c = ConnectionManager.getInstance();
|
||||||
|
|
||||||
test("connect bad credentials", () => {
|
test("connect bad credentials", () => {
|
||||||
jest.spyOn(global, 'fetch').mockImplementationOnce(() => {
|
return expect(c.connect('truc', 'chose'))
|
||||||
return Promise.resolve({
|
|
||||||
json: () => {
|
|
||||||
return {
|
|
||||||
state: false,
|
|
||||||
message: 'Adresse mail ou mot de passe incorrect',
|
|
||||||
token: ''
|
|
||||||
}
|
|
||||||
},
|
|
||||||
})
|
|
||||||
});
|
|
||||||
return expect(c.connect('email', 'password'))
|
|
||||||
.rejects.toBe(ERROR_TYPE.BAD_CREDENTIALS);
|
.rejects.toBe(ERROR_TYPE.BAD_CREDENTIALS);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("connect good credentials", () => {
|
test("connect good credentials", () => {
|
||||||
jest.spyOn(global, 'fetch').mockImplementationOnce(() => {
|
return expect(c.connect('vergnet@etud.insa-toulouse.fr', 'Coucoù512'))
|
||||||
return Promise.resolve({
|
.resolves.toBe('test');
|
||||||
json: () => {
|
|
||||||
return {
|
|
||||||
state: true,
|
|
||||||
message: 'Connexion confirmée',
|
|
||||||
token: 'token'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
})
|
|
||||||
});
|
|
||||||
jest.spyOn(SecureStore, 'setItemAsync').mockImplementationOnce(() => {
|
|
||||||
return Promise.resolve(true);
|
|
||||||
});
|
|
||||||
return expect(c.connect('email', 'password')).resolves.toBeTruthy();
|
|
||||||
});
|
|
||||||
|
|
||||||
test("connect good credentials, fail save token", () => {
|
|
||||||
jest.spyOn(global, 'fetch').mockImplementationOnce(() => {
|
|
||||||
return Promise.resolve({
|
|
||||||
json: () => {
|
|
||||||
return {
|
|
||||||
state: true,
|
|
||||||
message: 'Connexion confirmée',
|
|
||||||
token: 'token'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
})
|
|
||||||
});
|
|
||||||
jest.spyOn(SecureStore, 'setItemAsync').mockImplementationOnce(() => {
|
|
||||||
return Promise.reject(false);
|
|
||||||
});
|
|
||||||
return expect(c.connect('email', 'password')).rejects.toBe(ERROR_TYPE.SAVE_TOKEN);
|
|
||||||
});
|
|
||||||
|
|
||||||
test("connect connection error", () => {
|
|
||||||
jest.spyOn(global, 'fetch').mockImplementationOnce(() => {
|
|
||||||
return Promise.reject();
|
|
||||||
});
|
|
||||||
return expect(c.connect('email', 'password'))
|
|
||||||
.rejects.toBe(ERROR_TYPE.CONNECTION_ERROR);
|
|
||||||
});
|
|
||||||
|
|
||||||
test("connect bogus response 1", () => {
|
|
||||||
jest.spyOn(global, 'fetch').mockImplementationOnce(() => {
|
|
||||||
return Promise.resolve({
|
|
||||||
json: () => {
|
|
||||||
return {
|
|
||||||
thing: true,
|
|
||||||
wrong: '',
|
|
||||||
}
|
|
||||||
},
|
|
||||||
})
|
|
||||||
});
|
|
||||||
return expect(c.connect('email', 'password'))
|
|
||||||
.rejects.toBe(ERROR_TYPE.CONNECTION_ERROR);
|
|
||||||
});
|
|
||||||
|
|
||||||
test("connect bogus response 2", () => {
|
|
||||||
jest.spyOn(global, 'fetch').mockImplementationOnce(() => {
|
|
||||||
return Promise.resolve({
|
|
||||||
json: () => {
|
|
||||||
return {
|
|
||||||
state: true,
|
|
||||||
message: '',
|
|
||||||
}
|
|
||||||
},
|
|
||||||
})
|
|
||||||
});
|
|
||||||
return expect(c.connect('email', 'password'))
|
|
||||||
.rejects.toBe(ERROR_TYPE.CONNECTION_ERROR);
|
|
||||||
});
|
|
||||||
|
|
||||||
test("connect bogus response 3", () => {
|
|
||||||
jest.spyOn(global, 'fetch').mockImplementationOnce(() => {
|
|
||||||
return Promise.resolve({
|
|
||||||
json: () => {
|
|
||||||
return {
|
|
||||||
state: false,
|
|
||||||
message: '',
|
|
||||||
}
|
|
||||||
},
|
|
||||||
})
|
|
||||||
});
|
|
||||||
return expect(c.connect('email', 'password'))
|
|
||||||
.rejects.toBe(ERROR_TYPE.BAD_CREDENTIALS);
|
|
||||||
});
|
|
||||||
|
|
||||||
test("connect bogus response 4", () => {
|
|
||||||
jest.spyOn(global, 'fetch').mockImplementationOnce(() => {
|
|
||||||
return Promise.resolve({
|
|
||||||
json: () => {
|
|
||||||
return {
|
|
||||||
message: '',
|
|
||||||
token: '',
|
|
||||||
}
|
|
||||||
},
|
|
||||||
})
|
|
||||||
});
|
|
||||||
return expect(c.connect('email', 'password'))
|
|
||||||
.rejects.toBe(ERROR_TYPE.CONNECTION_ERROR);
|
|
||||||
});
|
|
||||||
|
|
||||||
test("connect bogus response 5", () => {
|
|
||||||
jest.spyOn(global, 'fetch').mockImplementationOnce(() => {
|
|
||||||
return Promise.resolve({
|
|
||||||
json: () => {
|
|
||||||
return {
|
|
||||||
state: true,
|
|
||||||
message: 'Connexion confirmée',
|
|
||||||
token: ''
|
|
||||||
}
|
|
||||||
},
|
|
||||||
})
|
|
||||||
});
|
|
||||||
return expect(c.connect('email', 'password'))
|
|
||||||
.rejects.toBe(ERROR_TYPE.CONNECTION_ERROR);
|
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -3,17 +3,16 @@
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import {Dimensions, FlatList, Image, Platform, StyleSheet, View} from 'react-native';
|
import {Dimensions, FlatList, Image, Platform, StyleSheet, View} from 'react-native';
|
||||||
import i18n from "i18n-js";
|
import i18n from "i18n-js";
|
||||||
import {openBrowser} from "../utils/WebBrowser";
|
import * as WebBrowser from 'expo-web-browser';
|
||||||
import SidebarDivider from "./SidebarDivider";
|
import SidebarDivider from "./SidebarDivider";
|
||||||
import SidebarItem from "./SidebarItem";
|
import SidebarItem from "./SidebarItem";
|
||||||
import {TouchableRipple, withTheme} from "react-native-paper";
|
import {TouchableRipple} from "react-native-paper";
|
||||||
|
|
||||||
const deviceWidth = Dimensions.get("window").width;
|
const deviceWidth = Dimensions.get("window").width;
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
navigation: Object,
|
navigation: Object,
|
||||||
state: Object,
|
state: Object,
|
||||||
theme: Object,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
type State = {
|
type State = {
|
||||||
|
|
@ -23,7 +22,7 @@ type State = {
|
||||||
/**
|
/**
|
||||||
* Component used to render the drawer menu content
|
* Component used to render the drawer menu content
|
||||||
*/
|
*/
|
||||||
class SideBar extends React.PureComponent<Props, State> {
|
export default class SideBar extends React.PureComponent<Props, State> {
|
||||||
|
|
||||||
dataSet: Array<Object>;
|
dataSet: Array<Object>;
|
||||||
|
|
||||||
|
|
@ -32,7 +31,6 @@ class SideBar extends React.PureComponent<Props, State> {
|
||||||
};
|
};
|
||||||
|
|
||||||
getRenderItem: Function;
|
getRenderItem: Function;
|
||||||
colors: Object;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate the dataset
|
* Generate the dataset
|
||||||
|
|
@ -128,7 +126,6 @@ class SideBar extends React.PureComponent<Props, State> {
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
this.getRenderItem = this.getRenderItem.bind(this);
|
this.getRenderItem = this.getRenderItem.bind(this);
|
||||||
this.colors = props.theme.colors;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -141,7 +138,7 @@ class SideBar extends React.PureComponent<Props, State> {
|
||||||
if (item.link === undefined)
|
if (item.link === undefined)
|
||||||
this.props.navigation.navigate(item.route);
|
this.props.navigation.navigate(item.route);
|
||||||
else
|
else
|
||||||
openBrowser(item.link, this.colors.primary);
|
WebBrowser.openBrowserAsync(item.link);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -221,5 +218,3 @@ const styles = StyleSheet.create({
|
||||||
marginTop: Platform.OS === "android" ? -3 : undefined
|
marginTop: Platform.OS === "android" ? -3 : undefined
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
export default withTheme(SideBar);
|
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,8 @@
|
||||||
// @flow
|
// @flow
|
||||||
|
|
||||||
import * as SecureStore from 'expo-secure-store';
|
|
||||||
|
|
||||||
export const ERROR_TYPE = {
|
export const ERROR_TYPE = {
|
||||||
BAD_CREDENTIALS: 0,
|
BAD_CREDENTIALS: 0,
|
||||||
CONNECTION_ERROR: 1,
|
CONNECTION_ERROR: 1
|
||||||
SAVE_TOKEN: 2,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const AUTH_URL = "https://www.amicale-insat.fr/api/password";
|
const AUTH_URL = "https://www.amicale-insat.fr/api/password";
|
||||||
|
|
@ -30,20 +27,6 @@ export default class ConnectionManager {
|
||||||
ConnectionManager.instance;
|
ConnectionManager.instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
async saveLogin(email: string, token: string) {
|
|
||||||
this.#token = token;
|
|
||||||
this.#email = email;
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
SecureStore.setItemAsync('token', token)
|
|
||||||
.then(() => {
|
|
||||||
resolve(true);
|
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
reject(false);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
async connect(email: string, password: string) {
|
async connect(email: string, password: string) {
|
||||||
let data = {
|
let data = {
|
||||||
email: email,
|
email: email,
|
||||||
|
|
@ -59,31 +42,24 @@ export default class ConnectionManager {
|
||||||
body: JSON.stringify(data)
|
body: JSON.stringify(data)
|
||||||
}).then(async (response) => response.json())
|
}).then(async (response) => response.json())
|
||||||
.then((data) => {
|
.then((data) => {
|
||||||
if (this.isResponseValid(data)) {
|
console.log(data);
|
||||||
if (data.state) {
|
if (this.isResponseValid(data))
|
||||||
this.saveLogin(email, data.token)
|
resolve({success: data.success, token: data.token});
|
||||||
.then(() => {
|
else
|
||||||
resolve(true);
|
|
||||||
})
|
|
||||||
.catch(() => {
|
|
||||||
reject(ERROR_TYPE.SAVE_TOKEN);
|
|
||||||
});
|
|
||||||
} else
|
|
||||||
reject(ERROR_TYPE.BAD_CREDENTIALS);
|
reject(ERROR_TYPE.BAD_CREDENTIALS);
|
||||||
} else
|
|
||||||
reject(ERROR_TYPE.CONNECTION_ERROR);
|
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
|
console.log(error);
|
||||||
reject(ERROR_TYPE.CONNECTION_ERROR);
|
reject(ERROR_TYPE.CONNECTION_ERROR);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
isResponseValid(response: Object) {
|
isResponseValid(response: Object) {
|
||||||
let valid = response !== undefined && response.state !== undefined;
|
return response !== undefined
|
||||||
if (valid && response.state)
|
&& response.success !== undefined
|
||||||
valid = valid && response.token !== undefined && response.token !== '';
|
&& response.success
|
||||||
return valid;
|
&& response.token !== undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,9 +12,6 @@
|
||||||
},
|
},
|
||||||
"jest": {
|
"jest": {
|
||||||
"preset": "react-native",
|
"preset": "react-native",
|
||||||
"transformIgnorePatterns": [
|
|
||||||
"node_modules/(?!(jest-)?react-native|react-clone-referenced-element|@react-native-community|expo(nent)?|@expo(nent)?/.*|react-navigation|@react-navigation/.*|@unimodules/.*|unimodules|sentry-expo|native-base)"
|
|
||||||
],
|
|
||||||
"setupFilesAfterEnv": [
|
"setupFilesAfterEnv": [
|
||||||
"jest-extended"
|
"jest-extended"
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,9 @@
|
||||||
// @flow
|
// @flow
|
||||||
|
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import {
|
import {Keyboard, KeyboardAvoidingView, StyleSheet, TouchableWithoutFeedback, View} from "react-native";
|
||||||
Alert,
|
import {Button, Text, TextInput, Title} from 'react-native-paper';
|
||||||
Keyboard,
|
|
||||||
KeyboardAvoidingView,
|
|
||||||
ScrollView,
|
|
||||||
StyleSheet,
|
|
||||||
TouchableWithoutFeedback,
|
|
||||||
View
|
|
||||||
} from "react-native";
|
|
||||||
import {Avatar, Button, Card, HelperText, Text, TextInput, withTheme} from 'react-native-paper';
|
|
||||||
import ConnectionManager from "../../managers/ConnectionManager";
|
import ConnectionManager from "../../managers/ConnectionManager";
|
||||||
import {openBrowser} from "../../utils/WebBrowser";
|
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
navigation: Object,
|
navigation: Object,
|
||||||
|
|
@ -21,239 +12,79 @@ type Props = {
|
||||||
type State = {
|
type State = {
|
||||||
email: string,
|
email: string,
|
||||||
password: string,
|
password: string,
|
||||||
isEmailValidated: boolean,
|
|
||||||
isPasswordValidated: boolean,
|
|
||||||
loading: boolean,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const ICON_AMICALE = require('../../assets/amicale.png');
|
|
||||||
|
|
||||||
const RESET_PASSWORD_LINK = "https://www.amicale-insat.fr/password/reset";
|
export default class LoginScreen extends React.Component<Props, State> {
|
||||||
|
|
||||||
const emailRegex = /^.+@.+\..+$/;
|
|
||||||
|
|
||||||
class LoginScreen extends React.Component<Props, State> {
|
|
||||||
|
|
||||||
state = {
|
state = {
|
||||||
email: '',
|
email: '',
|
||||||
password: '',
|
password: '',
|
||||||
isEmailValidated: false,
|
|
||||||
isPasswordValidated: false,
|
|
||||||
loading: false,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
colors: Object;
|
|
||||||
|
|
||||||
onEmailChange: Function;
|
onEmailChange: Function;
|
||||||
onPasswordChange: Function;
|
onPasswordChange: Function;
|
||||||
validateEmail: Function;
|
|
||||||
validatePassword: Function;
|
|
||||||
onSubmit: Function;
|
|
||||||
onEmailSubmit: Function;
|
|
||||||
onResetPasswordClick: Function;
|
|
||||||
|
|
||||||
passwordInputRef: Object;
|
constructor() {
|
||||||
|
super();
|
||||||
constructor(props) {
|
|
||||||
super(props);
|
|
||||||
this.onEmailChange = this.onInputChange.bind(this, true);
|
this.onEmailChange = this.onInputChange.bind(this, true);
|
||||||
this.onPasswordChange = this.onInputChange.bind(this, false);
|
this.onPasswordChange = this.onInputChange.bind(this, false);
|
||||||
this.validateEmail = this.validateEmail.bind(this);
|
|
||||||
this.validatePassword = this.validatePassword.bind(this);
|
|
||||||
this.onSubmit = this.onSubmit.bind(this);
|
|
||||||
this.onEmailSubmit = this.onEmailSubmit.bind(this);
|
|
||||||
this.onResetPasswordClick = this.onResetPasswordClick.bind(this);
|
|
||||||
this.colors = props.theme.colors;
|
|
||||||
}
|
|
||||||
|
|
||||||
onResetPasswordClick() {
|
|
||||||
openBrowser(RESET_PASSWORD_LINK, this.colors.primary);
|
|
||||||
}
|
|
||||||
|
|
||||||
validateEmail() {
|
|
||||||
this.setState({isEmailValidated: true});
|
|
||||||
}
|
|
||||||
|
|
||||||
isEmailValid() {
|
|
||||||
return emailRegex.test(this.state.email);
|
|
||||||
}
|
|
||||||
|
|
||||||
shouldShowEmailError() {
|
|
||||||
return this.state.isEmailValidated && !this.isEmailValid();
|
|
||||||
}
|
|
||||||
|
|
||||||
validatePassword() {
|
|
||||||
this.setState({isPasswordValidated: true});
|
|
||||||
}
|
|
||||||
|
|
||||||
isPasswordValid() {
|
|
||||||
return this.state.password !== '';
|
|
||||||
}
|
|
||||||
|
|
||||||
shouldShowPasswordError() {
|
|
||||||
return this.state.isPasswordValidated && !this.isPasswordValid();
|
|
||||||
}
|
|
||||||
|
|
||||||
shouldEnableLogin() {
|
|
||||||
return this.isEmailValid() && this.isPasswordValid();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onInputChange(isEmail: boolean, value: string) {
|
onInputChange(isEmail: boolean, value: string) {
|
||||||
if (isEmail) {
|
if (isEmail)
|
||||||
this.setState({
|
this.setState({email: value});
|
||||||
email: value,
|
else
|
||||||
isEmailValidated: false,
|
this.setState({password: value});
|
||||||
});
|
|
||||||
} else {
|
|
||||||
this.setState({
|
|
||||||
password: value,
|
|
||||||
isPasswordValidated: false,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onEmailSubmit() {
|
|
||||||
this.passwordInputRef.focus();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onSubmit() {
|
onSubmit() {
|
||||||
if (this.shouldEnableLogin()) {
|
console.log('pressed');
|
||||||
this.setState({loading: true});
|
|
||||||
ConnectionManager.getInstance().connect(this.state.email, this.state.password)
|
ConnectionManager.getInstance().connect(this.state.email, this.state.password)
|
||||||
.then((data) => {
|
.then((data) => {
|
||||||
console.log(data);
|
console.log(data);
|
||||||
Alert.alert('COOL', 'ÇA MARCHE');
|
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
Alert.alert('ERREUR', 'MDP OU MAIL INVALIDE');
|
|
||||||
})
|
|
||||||
.finally(() => {
|
|
||||||
this.setState({loading: false});
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
getFormInput() {
|
|
||||||
return (
|
|
||||||
<View>
|
|
||||||
<TextInput
|
|
||||||
label='Email'
|
|
||||||
mode='outlined'
|
|
||||||
value={this.state.email}
|
|
||||||
onChangeText={this.onEmailChange}
|
|
||||||
onBlur={this.validateEmail}
|
|
||||||
onSubmitEditing={this.onEmailSubmit}
|
|
||||||
error={this.shouldShowEmailError()}
|
|
||||||
textContentType={'emailAddress'}
|
|
||||||
autoCapitalize={'none'}
|
|
||||||
autoCompleteType={'email'}
|
|
||||||
autoCorrect={false}
|
|
||||||
keyboardType={'email-address'}
|
|
||||||
returnKeyType={'next'}
|
|
||||||
secureTextEntry={false}
|
|
||||||
/>
|
|
||||||
<HelperText
|
|
||||||
type="error"
|
|
||||||
visible={this.shouldShowEmailError()}
|
|
||||||
>
|
|
||||||
EMAIL INVALID
|
|
||||||
</HelperText>
|
|
||||||
<TextInput
|
|
||||||
ref={(ref) => {
|
|
||||||
this.passwordInputRef = ref;
|
|
||||||
}}
|
|
||||||
label='Password'
|
|
||||||
mode='outlined'
|
|
||||||
value={this.state.password}
|
|
||||||
onChangeText={this.onPasswordChange}
|
|
||||||
onBlur={this.validatePassword}
|
|
||||||
onSubmitEditing={this.onSubmit}
|
|
||||||
error={this.shouldShowPasswordError()}
|
|
||||||
textContentType={'password'}
|
|
||||||
autoCapitalize={'none'}
|
|
||||||
autoCompleteType={'password'}
|
|
||||||
autoCorrect={false}
|
|
||||||
keyboardType={'default'}
|
|
||||||
returnKeyType={'done'}
|
|
||||||
secureTextEntry={true}
|
|
||||||
/>
|
|
||||||
<HelperText
|
|
||||||
type="error"
|
|
||||||
visible={this.shouldShowPasswordError()}
|
|
||||||
>
|
|
||||||
PLS ENTER PASSWORD
|
|
||||||
</HelperText>
|
|
||||||
</View>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
getMainCard() {
|
|
||||||
return (
|
|
||||||
<Card style={styles.card}>
|
|
||||||
<Card.Title
|
|
||||||
title="COUCOU"
|
|
||||||
subtitle="ENTREZ VOS IDENTIFIANTS"
|
|
||||||
left={(props) => <Avatar.Image
|
|
||||||
{...props}
|
|
||||||
source={ICON_AMICALE}
|
|
||||||
style={{backgroundColor: 'transparent'}}/>}
|
|
||||||
/>
|
|
||||||
<Card.Content>
|
|
||||||
{this.getFormInput()}
|
|
||||||
<Card.Actions>
|
|
||||||
<Button
|
|
||||||
icon="send"
|
|
||||||
mode="contained"
|
|
||||||
disabled={!this.shouldEnableLogin()}
|
|
||||||
loading={this.state.loading}
|
|
||||||
onPress={this.onSubmit}
|
|
||||||
style={{marginLeft: 'auto'}}>
|
|
||||||
LOGIN
|
|
||||||
</Button>
|
|
||||||
</Card.Actions>
|
|
||||||
</Card.Content>
|
|
||||||
</Card>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
getSecondaryCard() {
|
|
||||||
return (
|
|
||||||
<Card style={styles.card}>
|
|
||||||
<Card.Content>
|
|
||||||
<Text>MDP OUBLIÉ ? t'es pas doué</Text>
|
|
||||||
<View style={styles.btnContainer}>
|
|
||||||
<Button
|
|
||||||
icon="reload"
|
|
||||||
mode="contained"
|
|
||||||
onPress={this.onResetPasswordClick}
|
|
||||||
style={{marginLeft: 'auto'}}>
|
|
||||||
RESET MDP
|
|
||||||
</Button>
|
|
||||||
</View>
|
|
||||||
<Text>PAS DE COMPTE ? DOMMAGE PASSE À L'AMICALE</Text>
|
|
||||||
</Card.Content>
|
|
||||||
</Card>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<KeyboardAvoidingView
|
<KeyboardAvoidingView
|
||||||
behavior={"height"}
|
behavior={"padding"}
|
||||||
contentContainerStyle={styles.container}
|
contentContainerStyle={styles.container}
|
||||||
style={styles.container}
|
style={styles.container}
|
||||||
enabled
|
|
||||||
keyboardVerticalOffset={100}
|
|
||||||
>
|
>
|
||||||
<ScrollView>
|
|
||||||
<TouchableWithoutFeedback onPress={Keyboard.dismiss}>
|
<TouchableWithoutFeedback onPress={Keyboard.dismiss}>
|
||||||
<View>
|
<View style={styles.inner}>
|
||||||
{this.getMainCard()}
|
<Title>COUCOU</Title>
|
||||||
{this.getSecondaryCard()}
|
<Text>entrez vos identifiants</Text>
|
||||||
|
<TextInput
|
||||||
|
label='Email'
|
||||||
|
mode='outlined'
|
||||||
|
value={this.state.email}
|
||||||
|
onChangeText={this.onEmailChange}
|
||||||
|
/>
|
||||||
|
<TextInput
|
||||||
|
label='Password'
|
||||||
|
mode='outlined'
|
||||||
|
value={this.state.password}
|
||||||
|
onChangeText={this.onPasswordChange}
|
||||||
|
/>
|
||||||
|
<View style={styles.btnContainer}>
|
||||||
|
<Button icon="send" onPress={() => this.onSubmit()}>
|
||||||
|
LOGIN
|
||||||
|
</Button>
|
||||||
|
</View>
|
||||||
|
<Text>Pas de compte, dommage !</Text>
|
||||||
|
<View style={styles.btnContainer}>
|
||||||
|
<Button icon="send" onPress={() => console.log('Pressed')}>
|
||||||
|
Créer un compte
|
||||||
|
</Button>
|
||||||
|
</View>
|
||||||
</View>
|
</View>
|
||||||
</TouchableWithoutFeedback>
|
</TouchableWithoutFeedback>
|
||||||
</ScrollView>
|
|
||||||
</KeyboardAvoidingView>
|
</KeyboardAvoidingView>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -261,12 +92,11 @@ class LoginScreen extends React.Component<Props, State> {
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
const styles = StyleSheet.create({
|
||||||
container: {
|
container: {
|
||||||
flex: 1,
|
flex: 1
|
||||||
flexDirection: 'column',
|
|
||||||
justifyContent: 'center',
|
|
||||||
},
|
},
|
||||||
card: {
|
inner: {
|
||||||
margin: 10,
|
padding: 24,
|
||||||
|
flex: 1,
|
||||||
},
|
},
|
||||||
header: {
|
header: {
|
||||||
fontSize: 36,
|
fontSize: 36,
|
||||||
|
|
@ -274,9 +104,6 @@ const styles = StyleSheet.create({
|
||||||
},
|
},
|
||||||
textInput: {},
|
textInput: {},
|
||||||
btnContainer: {
|
btnContainer: {
|
||||||
marginTop: 5,
|
marginTop: 12
|
||||||
marginBottom: 10,
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
export default withTheme(LoginScreen);
|
|
||||||
|
|
|
||||||
|
|
@ -4,13 +4,13 @@ import * as React from 'react';
|
||||||
import {View} from 'react-native';
|
import {View} from 'react-native';
|
||||||
import i18n from "i18n-js";
|
import i18n from "i18n-js";
|
||||||
import DashboardItem from "../components/EventDashboardItem";
|
import DashboardItem from "../components/EventDashboardItem";
|
||||||
|
import * as WebBrowser from 'expo-web-browser';
|
||||||
import WebSectionList from "../components/WebSectionList";
|
import WebSectionList from "../components/WebSectionList";
|
||||||
import {Text, withTheme} from 'react-native-paper';
|
import {Text, withTheme} from 'react-native-paper';
|
||||||
import FeedItem from "../components/FeedItem";
|
import FeedItem from "../components/FeedItem";
|
||||||
import SquareDashboardItem from "../components/SquareDashboardItem";
|
import SquareDashboardItem from "../components/SquareDashboardItem";
|
||||||
import PreviewEventDashboardItem from "../components/PreviewEventDashboardItem";
|
import PreviewEventDashboardItem from "../components/PreviewEventDashboardItem";
|
||||||
import {stringToDate} from "../utils/Planning";
|
import {stringToDate} from "../utils/Planning";
|
||||||
import {openBrowser} from "../utils/WebBrowser";
|
|
||||||
// import DATA from "../dashboard_data.json";
|
// import DATA from "../dashboard_data.json";
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -70,7 +70,7 @@ class HomeScreen extends React.Component<Props> {
|
||||||
}
|
}
|
||||||
|
|
||||||
onTutorInsaClick() {
|
onTutorInsaClick() {
|
||||||
openBrowser("https://www.etud.insa-toulouse.fr/~tutorinsa/", this.colors.primary);
|
WebBrowser.openBrowserAsync("https://www.etud.insa-toulouse.fr/~tutorinsa/");
|
||||||
}
|
}
|
||||||
|
|
||||||
onProximoClick() {
|
onProximoClick() {
|
||||||
|
|
@ -402,7 +402,7 @@ class HomeScreen extends React.Component<Props> {
|
||||||
}
|
}
|
||||||
|
|
||||||
openLink(link: string) {
|
openLink(link: string) {
|
||||||
openBrowser(link, this.colors.primary);
|
WebBrowser.openBrowserAsync(link);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
// @flow
|
|
||||||
|
|
||||||
import * as React from 'react';
|
|
||||||
import * as WebBrowser from 'expo-web-browser';
|
|
||||||
|
|
||||||
export function openBrowser(url: string, color: string) {
|
|
||||||
WebBrowser.openBrowserAsync(url, {
|
|
||||||
toolbarColor: color,
|
|
||||||
enableBarCollapsing: true,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
Loading…
Reference in a new issue