mirror of
https://gitlab.com/wheres-the-tp/ui-mobile.git
synced 2026-01-25 04:34:55 -06:00
211 lines
5.1 KiB
JavaScript
211 lines
5.1 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';
|
|
import { getBackTo } from '../helpers/RouteHelpers';
|
|
import ResetPasswordButton from '../components/ResetPasswordButton';
|
|
|
|
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,
|
|
resetPassword: () => void,
|
|
};
|
|
|
|
const LoginPageComponent = ({
|
|
authUser,
|
|
deauthUser,
|
|
error,
|
|
router,
|
|
email,
|
|
setEmail,
|
|
password,
|
|
setPassword,
|
|
createUser,
|
|
isNewUser,
|
|
setIsNewUser,
|
|
setError,
|
|
}: 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',
|
|
backgroundColor: '#fff',
|
|
}}>
|
|
{error && (
|
|
<Text style={{ fontSize: 16, color: '#721c24', backgroundColor: '#f8d7da', padding: 16 }}>
|
|
{error}
|
|
</Text>
|
|
)}
|
|
|
|
<Text style={{ fontSize: 36, fontWeight: '700', marginTop: 32, marginBottom: 16 }}>
|
|
Sign In
|
|
</Text>
|
|
|
|
<View style={{ flexDirection: 'row', padding: 16, paddingBottom: 0 }}>
|
|
<View style={{ flex: 1, flexDirection: 'column' }}>
|
|
<TextInput
|
|
editable={true}
|
|
value={email}
|
|
placeholder="Email"
|
|
onChangeText={setEmail}
|
|
style={{
|
|
fontSize: 16,
|
|
paddingLeft: 0,
|
|
}}
|
|
/>
|
|
<Divider />
|
|
</View>
|
|
</View>
|
|
|
|
<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={{
|
|
fontSize: 16,
|
|
paddingLeft: 0,
|
|
}}
|
|
/>
|
|
<Divider />
|
|
</View>
|
|
</View>
|
|
|
|
<View style={{ flexDirection: 'row', padding: 16, paddingBottom: 0, paddingTop: 32 }}>
|
|
<View style={{ flex: 1, flexDirection: 'column' }}>
|
|
<Button
|
|
title={submitTitle}
|
|
onPress={submitAction}
|
|
color={theme.actionButton.speedDialActionIcon.backgroundColor}
|
|
/>
|
|
</View>
|
|
</View>
|
|
|
|
{!isNewUser && (
|
|
<TouchableOpacity
|
|
onPress={() => setIsNewUser(true)}
|
|
style={{ flexDirection: 'row', marginTop: 16, padding: 16, paddingBottom: 0 }}>
|
|
<Text
|
|
style={{
|
|
flex: 1,
|
|
textAlign: 'center',
|
|
fontSize: 16,
|
|
color: theme.palette.primaryColor,
|
|
}}>
|
|
Don't have an account? Sign up!
|
|
</Text>
|
|
</TouchableOpacity>
|
|
)}
|
|
|
|
<ResetPasswordButton
|
|
onSuccess={() => setIsNewUser(false)}
|
|
onError={() => setError('Password reset failed')}
|
|
/>
|
|
</View>
|
|
);
|
|
}
|
|
};
|
|
|
|
export default compose(
|
|
withRouterContext,
|
|
withState('error', 'setError', null),
|
|
withState('email', 'setEmail', ''),
|
|
withState('password', 'setPassword', ''),
|
|
withState('isNewUser', 'setIsNewUser', false),
|
|
withHandlers({
|
|
checkAuth: props => async () => {
|
|
const isLoggedIn = await AuthManager.checkIsAuthed();
|
|
if (isLoggedIn) {
|
|
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) {
|
|
console.log(err);
|
|
debugger;
|
|
setError('You have entered an invalid email or password. Please try again.');
|
|
}
|
|
},
|
|
}),
|
|
withHandlers({
|
|
deauthUser: ({ router: { history } }) => () => {
|
|
AuthManager.deauthenticate();
|
|
history.goBack();
|
|
},
|
|
createUser: ({ email, password, setError, authUser }) => async () => {
|
|
if (!email || !password) {
|
|
setError('Please provide email and password and try again.');
|
|
return;
|
|
}
|
|
|
|
try {
|
|
setError(null);
|
|
await AuthManager.createUser({ email, password });
|
|
authUser({ email, password });
|
|
} catch (err) {
|
|
setError('Unable to create user: ' + auth0ErrToStr(err.message));
|
|
}
|
|
},
|
|
}),
|
|
lifecycle({
|
|
componentDidMount() {
|
|
this.props.checkAuth();
|
|
},
|
|
})
|
|
)(LoginPageComponent);
|