aretherecookies-mobile/js/pages/LoginPage.js

212 lines
5.1 KiB
JavaScript
Raw Normal View History

2018-01-01 15:52:03 -06:00
//@flow
import React from 'react';
import { View, Text, TextInput, Button, TouchableOpacity } from 'react-native';
2018-08-25 12:13:09 -05:00
import { withHandlers, compose, withState, lifecycle } from 'recompose';
2018-01-01 15:52:03 -06:00
import { withRouterContext } from '../enhancers/routeEnhancers';
2018-08-25 12:13:09 -05:00
import AuthManager from '../AuthManager';
import theme from '../ui-theme';
import { Divider, Icon } from 'react-native-material-ui';
2020-03-29 19:47:33 +00:00
import { getBackTo } from '../helpers/RouteHelpers';
2020-04-05 13:54:34 -05:00
import ResetPasswordButton from '../components/ResetPasswordButton';
2020-04-26 12:27:24 -05:00
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';
}
};
2018-01-01 15:52:03 -06:00
type Props = {
authUser: () => void,
2018-05-19 12:25:25 -05:00
error: string,
setError: (err: string) => void,
email: string,
2020-04-26 12:27:24 -05:00
setEmail: string => void,
password: string,
2020-04-26 12:27:24 -05:00
setPassword: string => void,
2018-05-19 12:25:25 -05:00
router: {
2018-08-25 10:12:06 -05:00
route: {
location: {
pathname: string,
},
2018-08-19 20:02:43 -05:00
},
2018-05-19 12:25:25 -05:00
history: {
replace: (url: string) => void,
location: {
search: string,
},
},
},
2018-08-19 20:02:43 -05:00
deauthUser: () => void,
createUser: () => void,
isNewUser: boolean,
2020-04-26 12:27:24 -05:00
setIsNewUser: boolean => void,
resetPassword: () => void,
2018-01-01 15:52:03 -06:00
};
const LoginPageComponent = ({
authUser,
deauthUser,
error,
router,
email,
setEmail,
password,
setPassword,
createUser,
isNewUser,
setIsNewUser,
2020-04-05 13:54:34 -05:00
setError,
}: Props) => {
2018-08-19 20:02:43 -05:00
if (/logout/.test(router.route.location.pathname)) {
deauthUser();
return null;
} else {
const submitTitle = isNewUser ? 'Continue' : 'Sign In';
const submitAction = isNewUser ? createUser : authUser;
2018-08-19 20:02:43 -05:00
return (
<View
style={{
flex: 1,
flexDirection: 'column',
alignItems: 'center',
justifyContent: 'flex-start',
backgroundColor: '#fff',
}}>
2020-03-29 19:47:33 +00:00
{error && (
<Text style={{ fontSize: 16, color: '#721c24', backgroundColor: '#f8d7da', padding: 16 }}>
{error}
</Text>
)}
2020-04-26 12:27:24 -05:00
<Text style={{ fontSize: 36, fontWeight: '700', marginTop: 32, marginBottom: 16 }}>
Sign In
</Text>
2020-01-19 22:59:57 -06:00
<View style={{ flexDirection: 'row', padding: 16, paddingBottom: 0 }}>
<View style={{ flex: 1, flexDirection: 'column' }}>
<TextInput
editable={true}
value={email}
placeholder="Email"
onChangeText={setEmail}
style={{
2020-01-19 22:59:57 -06:00
fontSize: 16,
2020-03-29 19:47:33 +00:00
paddingLeft: 0,
}}
/>
<Divider />
</View>
</View>
2020-01-19 22:59:57 -06:00
<View style={{ flexDirection: 'row', padding: 16, paddingBottom: 0 }}>
<View style={{ flex: 1, flexDirection: 'column' }}>
<TextInput
editable={true}
secureTextEntry={true}
value={password}
placeholder="Password"
onChangeText={setPassword}
style={{
2020-01-19 22:59:57 -06:00
fontSize: 16,
2020-03-29 19:47:33 +00:00
paddingLeft: 0,
}}
/>
<Divider />
</View>
</View>
2020-01-19 22:59:57 -06:00
<View style={{ flexDirection: 'row', padding: 16, paddingBottom: 0, paddingTop: 32 }}>
2020-03-29 19:47:33 +00:00
<View style={{ flex: 1, flexDirection: 'column' }}>
2020-04-05 13:54:34 -05:00
<Button
title={submitTitle}
onPress={submitAction}
color={theme.actionButton.speedDialActionIcon.backgroundColor}
/>
</View>
</View>
{!isNewUser && (
<TouchableOpacity
onPress={() => setIsNewUser(true)}
2020-01-19 22:59:57 -06:00
style={{ flexDirection: 'row', marginTop: 16, padding: 16, paddingBottom: 0 }}>
<Text
style={{
flex: 1,
textAlign: 'center',
fontSize: 16,
color: theme.palette.primaryColor,
}}>
Don&apos;t have an account? Sign up!
</Text>
</TouchableOpacity>
)}
2020-04-05 13:54:34 -05:00
<ResetPasswordButton
onSuccess={() => setIsNewUser(false)}
onError={() => setError('Password reset failed')}
/>
2018-01-01 15:52:03 -06:00
</View>
2018-08-19 20:02:43 -05:00
);
}
2018-01-01 15:52:03 -06:00
};
2018-08-25 12:13:09 -05:00
export default compose(
2018-01-01 15:52:03 -06:00
withRouterContext,
2018-05-19 12:25:25 -05:00
withState('error', 'setError', null),
withState('email', 'setEmail', ''),
withState('password', 'setPassword', ''),
withState('isNewUser', 'setIsNewUser', false),
withHandlers({
2020-04-26 12:27:24 -05:00
checkAuth: props => async () => {
const isLoggedIn = await AuthManager.checkIsAuthed();
if (isLoggedIn) {
2020-03-29 19:47:33 +00:00
const backTo = getBackTo(props);
return backTo ? props.router.history.replace(backTo) : props.router.history.goBack();
}
},
}),
withHandlers({
authUser: ({ email, password, setError, checkAuth }) => async () => {
try {
setError(null);
await AuthManager.authenticate({ email, password });
checkAuth();
} catch (err) {
2020-04-26 12:27:24 -05:00
console.log(err);
debugger;
2020-04-05 13:54:34 -05:00
setError('You have entered an invalid email or password. Please try again.');
}
},
}),
2018-01-01 15:52:03 -06:00
withHandlers({
2018-08-19 20:02:43 -05:00
deauthUser: ({ router: { history } }) => () => {
AuthManager.deauthenticate();
history.goBack();
2018-08-19 20:02:43 -05:00
},
2020-04-05 13:54:34 -05:00
createUser: ({ email, password, setError, authUser }) => async () => {
if (!email || !password) {
setError('Please provide email and password and try again.');
return;
}
try {
setError(null);
2020-04-05 13:54:34 -05:00
await AuthManager.createUser({ email, password });
authUser({ email, password });
} catch (err) {
setError('Unable to create user: ' + auth0ErrToStr(err.message));
}
},
2018-08-25 12:13:09 -05:00
}),
lifecycle({
componentDidMount() {
this.props.checkAuth();
2018-08-25 12:13:09 -05:00
},
2018-01-01 15:52:03 -06:00
})
)(LoginPageComponent);