mirror of
https://gitlab.com/wheres-the-tp/ui-mobile.git
synced 2026-01-25 07:34:55 -06:00
242 lines
5.7 KiB
JavaScript
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'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);
|