aretherecookies-mobile/js/pages/LoginPage.js
2019-06-29 17:04:22 +00:00

242 lines
5.7 KiB
JavaScript

//@flow
import React from 'react';
import { View, Text, TextInput, Button, TouchableOpacity } from 'react-native';
import { withHandlers, compose, withState, lifecycle } from 'recompose';
import { withRouterContext } from '../enhancers/routeEnhancers';
import AuthManager from '../AuthManager';
import theme from '../ui-theme';
import { Divider, Icon } from 'react-native-material-ui';
const auth0ErrToStr = message => {
if (typeof message === 'string') {
return message;
}
if (message && message.rules && message.rules.length > 0) {
return 'Password must be at least 8 characters and contain at least 1 letter, number, and symbol';
}
};
type Props = {
authUser: () => void,
error: string,
setError: (err: string) => void,
email: string,
setEmail: string => void,
password: string,
setPassword: string => void,
router: {
route: {
location: {
pathname: string,
},
},
history: {
replace: (url: string) => void,
location: {
search: string,
},
},
},
deauthUser: () => void,
createUser: () => void,
isNewUser: boolean,
setIsNewUser: boolean => void,
username: string,
setUsername: string => void,
resetPassword: () => void,
};
const LoginPageComponent = ({
authUser,
deauthUser,
error,
router,
email,
setEmail,
password,
setPassword,
createUser,
isNewUser,
setIsNewUser,
username,
setUsername,
resetPassword,
}: Props) => {
if (/logout/.test(router.route.location.pathname)) {
deauthUser();
return null;
} else {
const submitTitle = isNewUser ? 'Continue' : 'Sign In';
const submitAction = isNewUser ? createUser : authUser;
return (
<View
style={{
flex: 1,
flexDirection: 'column',
alignItems: 'center',
justifyContent: 'flex-start',
padding: 20,
borderWidth: 1,
borderColor: 'pink',
}}>
{error && <Text style={{ fontSize: 16, color: 'red', fontWeight: 'bold' }}>{error}</Text>}
<Text style={{ fontSize: 64, fontWeight: '600' }}>Sign In</Text>
<View style={{ flexDirection: 'row', marginTop: 20 }}>
<View style={{ flex: 1, flexDirection: 'column' }}>
<TextInput
editable={true}
value={email}
placeholder="Email"
onChangeText={setEmail}
style={{
fontSize: 18,
}}
/>
<Divider />
</View>
</View>
{isNewUser && (
<View style={{ flexDirection: 'row', marginTop: 20 }}>
<View style={{ flex: 1, flexDirection: 'column' }}>
<TextInput
editable={true}
value={username}
placeholder="Username"
onChangeText={setUsername}
style={{
fontSize: 18,
}}
/>
<Divider />
</View>
</View>
)}
<View style={{ flexDirection: 'row', marginTop: 20 }}>
<View style={{ flex: 1, flexDirection: 'column' }}>
<TextInput
editable={true}
secureTextEntry={true}
value={password}
placeholder="Password"
onChangeText={setPassword}
style={{
fontSize: 18,
}}
/>
<Divider />
</View>
</View>
<View style={{ flexDirection: 'row', marginTop: 20 }}>
<View style={{ flex: 1, flexDirection: 'column', paddingTop: 20 }}>
<Button title={submitTitle} onPress={submitAction} color={theme.palette.primaryColor} />
</View>
</View>
{!isNewUser && (
<TouchableOpacity
onPress={() => setIsNewUser(true)}
style={{ flexDirection: 'row', marginTop: 20, padding: 20 }}>
<Text
style={{
flex: 1,
textAlign: 'center',
fontSize: 16,
color: theme.palette.primaryColor,
}}>
Don&apos;t have an account? Sign up!
</Text>
</TouchableOpacity>
)}
<TouchableOpacity
onPress={resetPassword}
style={{
flexDirection: 'row',
marginTop: 0,
padding: 20,
alignItems: 'center',
justifyContent: 'center',
}}>
<Text
style={{
textAlign: 'center',
fontSize: 16,
color: theme.palette.primaryColor,
marginRight: 5,
}}>
Forgot your pasword?
</Text>
<Icon name="launch" color={theme.palette.primaryColor} size={18} />
</TouchableOpacity>
</View>
);
}
};
export default compose(
withRouterContext,
withState('error', 'setError', null),
withState('email', 'setEmail', ''),
withState('password', 'setPassword', ''),
withState('username', 'setUsername', ''),
withState('isNewUser', 'setIsNewUser', false),
withHandlers({
checkAuth: ({ router }) => async () => {
const isLoggedIn = await AuthManager.checkIsAuthed();
if (isLoggedIn) {
router.history.goBack();
}
},
}),
withHandlers({
authUser: ({ email, password, setError, checkAuth }) => async () => {
try {
setError(null);
await AuthManager.authenticate({ email, password });
checkAuth();
} catch (err) {
setError('Login Failed! Please check the username and password and try again.');
}
},
}),
withHandlers({
deauthUser: ({ router: { history } }) => () => {
AuthManager.deauthenticate();
history.goBack();
},
createUser: ({ email, password, username, setError, authUser }) => async () => {
if (!email || !password || !username) {
setError('Please provide username, email, and password and try again.');
return;
}
try {
setError(null);
await AuthManager.createUser({ email, password, username });
authUser({ email, password });
} catch (err) {
setError('Unable to create user: ' + auth0ErrToStr(err.message));
}
},
resetPassword: ({ setError, setIsNewUser }) => async () => {
try {
await AuthManager.resetPassword();
setIsNewUser(false);
} catch (error) {
setError('Password reset failed');
}
},
}),
lifecycle({
componentDidMount() {
this.props.checkAuth();
},
})
)(LoginPageComponent);