Skip to content

Commit

Permalink
Jsaem2 7 user is able to signup (#18)
Browse files Browse the repository at this point in the history
* JSAEM2-7,basic feature finished.

1.basic signup page
2.user can provide their email, password and confirm password
3.validate email address
4.validate password
5.validate password and confirm password

* JSAEM-2_7, link to sign up page in personal page by click button

user can go to personal page and click sign up button to log in.

* JSAEM-2_7, add redux store user information and token, switch page after sign up successfully

* JSAEM-2_7, modify accroding to pr comments

* JSA-2_7,revert personal page, it will display  after user reigstered successfully

* JSAEM2_7,modify router name

* JSAEM2-7,change to port with dotenv

* JSAEM2-7,use dotenv for configuration and modify password rules, now user should use at least one special character for password

* JSAEM2-7,change babel config to LF form.

* JSAEM2-7,delete unneccssary blank and modfiy variable name

* JSAEM2-7,update password validation and modify import.

* JSAEM2_7, add username in redux ,simpifly function params and navigator

* JSAEM2-7,change password rule to only at least 8 characters.

* JSAEM2-7,modify mainheader

* JSAEM2-7,modify login css

* JSAEM2-7,modify signup page UI and add logout button

* JSAEM2-7,remove header of navigator

* JSAEM2-7,modify with backend changes

* JSAEM2-7,modify wit backend changes

* JSAEM2-7,remove tjhrow error

* JSAEM2-7,modify naming

* JSAEM2-7,fixed according to  comments

* JSAEM2-7, naming problem.

* JSAEM2-7, fixing naming problem

* JSAEM2-7,naming problem

* JSAEM2-7,modify navifgation and add loader

* JSAEM2-7, fix bug

* JSAEM2-7, auto capitalize first letter
  • Loading branch information
aaabbbcc1995 authored and ikarasz committed Jan 14, 2020
1 parent 3c6f6d9 commit eda6868
Show file tree
Hide file tree
Showing 17 changed files with 1,243 additions and 911 deletions.
5 changes: 4 additions & 1 deletion babel.config.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
module.exports = (api) => {
api.cache(true);
return {
presets: ['babel-preset-expo'],
presets: [
'babel-preset-expo',
'module:react-native-dotenv',
],
};
};
1,636 changes: 746 additions & 890 deletions package-lock.json

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,16 @@
"react": "16.9.0",
"react-dom": "16.9.0",
"react-native": "https://github.com/expo/react-native/archive/sdk-35.0.0.tar.gz",
"react-native-dotenv": "^0.2.0",
"react-native-elements": "^1.2.7",
"react-native-gesture-handler": "~1.3.0",
"react-native-modal-datetime-picker": "^7.6.1",
"react-native-reanimated": "~1.2.0",
"react-native-safe-area-context": "~0.3.6",
"react-native-screens": "~1.0.0-alpha.23",
"react-native-web": "^0.11.7",
"react-navigation": "^4.0.10",
"react-navigation-hooks": "^1.1.0",
"react-navigation-stack": "^1.10.3",
"react-navigation-tabs": "^2.6.2",
"react-redux": "^7.1.3",
Expand Down
1 change: 1 addition & 0 deletions src/Common/Color.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,6 @@ export default {
green: ['#2fc899', '#78ef93'],
purple: ['#a765cf', '#f8b6cc'],
orange: ['#ef6d6b', '#feaa74'],
gray: ['#ababab', '#d1d1d1'],
},
};
15 changes: 7 additions & 8 deletions src/Common/MainHeader.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,31 +5,30 @@ import { Button } from 'react-native-elements';
import styles from './themeStyle';

export default function MainHeader(props) {
const { title, onPressBtn, btnName } = props;
const { title, btnType } = props;
return (
<View style={styles.mainHeader}>
<View style={{ flex: 1 }}>
<View style={{ flex: 1, alignItems: 'flex-start', marginBottom: -10 }}>
<Button type="clear" />
</View>
<Text style={[styles.headerFont, { flex: 1 }]}>{title}</Text>
<View style={{
flex: 1, alignItems: 'flex-end',
flex: 1, alignContent: 'flex-end', marginBottom: -10, justifyContent: 'flex-end', flexDirection: 'row', alignItems: 'flex-end',
}}
>
<Button onPress={onPressBtn} icon={{ name: btnName }} type="clear" />
{(btnType.length)
? btnType.map((item, index) => <Button key={`btnTypeGroup:${index + 1}`} onPress={item.func} icon={{ name: item.name }} type="clear" />) : <View />}
</View>
</View>
);
}

MainHeader.propTypes = {
title: PropTypes.string,
onPressBtn: PropTypes.func,
btnName: PropTypes.string,
btnType: PropTypes.arrayOf(PropTypes.shape({ name: PropTypes.string, func: PropTypes.func })),
};

MainHeader.defaultProps = {
title: '',
onPressBtn: () => {},
btnName: '',
btnType: [],
};
4 changes: 2 additions & 2 deletions src/Navigator/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@ import { createBottomTabNavigator } from 'react-navigation-tabs';
import TabBarIcon from './TabBarIcon';
import Stats from '../Stats/index';
import TransCreator from '../TransCreator/index';
import Personal from '../Personal/index';
import themeColor from '../Common/Color';
import PersonalNavigation from '../Personal/PersonalStackNavigation';

const AppNavigator = createBottomTabNavigator({
Stats,
Create: TransCreator,
Me: Personal,
Me: PersonalNavigation,
},
{
defaultNavigationOptions: ({ navigation }) => ({
Expand Down
21 changes: 21 additions & 0 deletions src/Personal/Personal.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import React from 'react';
import { useDispatch } from 'react-redux';
import { View, Text, Button } from 'react-native';
import { logout } from './actionCreator';

export default function Personal() {
const dispatch = useDispatch();

const handleLogout = () => {
dispatch(logout());
};

return (
<View>
<Text>
This is Personal page
</Text>
<Button title="Logout" color="#f194ff" onPress={handleLogout} />
</View>
);
}
20 changes: 20 additions & 0 deletions src/Personal/PersonalIndex.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import React from 'react';
import { View, Button } from 'react-native';
import { useNavigation } from 'react-navigation-hooks';
import { useSelector } from 'react-redux';
import RegisterStyle from './registerStyle';
import Personal from './Personal';

export default function PersonalIndex() {
const { navigate } = useNavigation();
const user = useSelector((state) => state.user);

return (
(user.accessToken !== '' && user.accessToken !== undefined)
? <Personal /> : (
<View style={RegisterStyle.container}>
<Button title="Sign up" onPress={() => navigate('Register')} />
</View>
)
);
}
20 changes: 20 additions & 0 deletions src/Personal/PersonalStackNavigation.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { createStackNavigator } from 'react-navigation-stack';
import PersonalIndex from './PersonalIndex';
import Register from './Register';

const MainNavigator = createStackNavigator({
PersonalIndex: {
screen: PersonalIndex,
navigationOptions: {
header: null,
},
},
Register: {
screen: Register,
navigationOptions: {
header: null,
},
},
});

export default MainNavigator;
170 changes: 170 additions & 0 deletions src/Personal/Register.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
import React, { useState, useEffect } from 'react';
import {
View, Text, KeyboardAvoidingView, Platform, ActivityIndicator,
} from 'react-native';
import { Input, Icon } from 'react-native-elements';
import { useDispatch, useSelector } from 'react-redux';
import { useNavigation } from 'react-navigation-hooks';
import MainHeader from '../Common/MainHeader';
import utils from './utils';
import { requestSignup } from './actionCreator';
import SubmitBtn from './SubmitBtn';
import RegisterStyle from './registerStyle';

export default function Register() {
const { navigate } = useNavigation();
const user = useSelector((state) => state.user);
const dispatch = useDispatch();

const [username, setUsername] = useState('');
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [confirmPassword, setConfirmPassword] = useState('');
const [passwordHidden, setPasswordHidden] = useState(true);
const [confirmPasswordHidden, setConfirmPasswordHidden] = useState(true);
const [errorMsgDisplay, setErrorMsgDisplay] = useState(false);

const signUp = (userInfo) => {
dispatch(requestSignup(userInfo));
};

useEffect(() => {
if (user.accessToken) navigate('PersonalIndex');
if (user.message !== '' && user.message !== undefined) {
setErrorMsgDisplay(true);
}
}, [user.accessToken, user.message]);

return (
<>
<View style={{ borderBottomWidth: 2, borderBottomColor: '#f8f8f8' }}>
<MainHeader title="Register" />
</View>
<KeyboardAvoidingView
style={RegisterStyle.registerForm}
behavior="padding"
keyboardVerticalOffset={Platform.OS === 'ios' ? 64 : 20}
enabled
>
<View>
<View style={RegisterStyle.inputSection}>
<Input
placeholder="username"
leftIcon={(
<Icon
name="face"
color="#a8a8a8"
/>
)}
leftIconContainerStyle={RegisterStyle.inputIcon}
label="Your Username"
value={username}
autoCapitalize="none"
onChangeText={(value) => setUsername(value)}
labelStyle={{ color: 'gray' }}
/>
</View>
<View style={RegisterStyle.inputSection}>
<Input
placeholder="[email protected]"
leftIcon={(
<Icon
name="email"
color="#a8a8a8"
/>
)}
leftIconContainerStyle={RegisterStyle.inputIcon}
label="Your Email Address"
textContentType="emailAddress"
value={email}
autoCapitalize="none"
onChangeText={(value) => setEmail(value)}
labelStyle={{ color: 'gray' }}
/>
<Text style={RegisterStyle.note}>
{utils.validateEmail(email) || email === '' ? '' : 'Your email is not correct.' }
</Text>
</View>

<View style={RegisterStyle.inputSection}>
<Input
placeholder="Password"
leftIcon={(
<Icon
name="lock"
color="#a8a8a8"
/>
)}
leftIconContainerStyle={RegisterStyle.inputIcon}
label="Your password"
secureTextEntry={passwordHidden}
value={password}
onChangeText={(value) => setPassword(value)}
labelStyle={{ color: 'gray' }}
rightIcon={(
<Icon
name={`md-eye${passwordHidden ? '-off' : ''}`}
type="ionicon"
color="gray"
onPress={() => setPasswordHidden(!passwordHidden)}
/>
)}
/>
<Text style={RegisterStyle.note}>
{utils.validatePassword(password) || password === ''
? '' : 'Password should be at least 8 characters.'}
</Text>
</View>

<View style={RegisterStyle.inputSection}>
<Input
placeholder="Confirm your password"
leftIcon={(
<Icon
name="lock"
color="#a8a8a8"
/>
)}
leftIconContainerStyle={RegisterStyle.inputIcon}
label="Confirm your password"
secureTextEntry={confirmPasswordHidden}
value={confirmPassword}
onChangeText={(value) => setConfirmPassword(value)}
labelStyle={{ color: 'gray' }}
rightIcon={(
<Icon
name={`md-eye${confirmPasswordHidden ? '-off' : ''}`}
type="ionicon"
color="gray"
onPress={() => setConfirmPasswordHidden(!confirmPasswordHidden)}
/>
)}
/>
<Text style={RegisterStyle.note}>
{password === confirmPassword || confirmPassword === '' ? '' : 'Password is not the same.'}
</Text>
</View>
{
(errorMsgDisplay) ? (
<View style={[RegisterStyle.inputSection, RegisterStyle.errorBox]}>
<Text style={RegisterStyle.errorText}>{user.message}</Text>
</View>
) : (null)
}
<View>
{(user.isInProgress) ? <ActivityIndicator size="large" color="black" />
: (
<SubmitBtn
disabled={utils.validateSignup(username,
password,
confirmPassword,
email) === false}
onPressBtn={() => signUp({ email, password, username })}
/>
)}
</View>
</View>
</KeyboardAvoidingView>
</>
);
}
34 changes: 34 additions & 0 deletions src/Personal/SubmitBtn.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import React from 'react';
import { View } from 'react-native';
import { Button } from 'react-native-elements';
import { LinearGradient } from 'expo-linear-gradient';
import PropTypes from 'prop-types';
import colors from '../Common/Color';
import RegisterStyle from './registerStyle';

export default function SubmitBtn({ disabled, onPressBtn }) {
return (
<View style={disabled ? RegisterStyle.disabledBtnShadow : RegisterStyle.btnShadow}>
<LinearGradient
colors={disabled ? colors.gradientColor.gray : colors.gradientColor.green}
start={[0.1, 0.9]}
end={[0.9, 0.1]}
style={{ borderRadius: 30, padding: 10 }}
>
<Button
title="Sign Up"
disabledTitleStyle={{ color: 'white' }}
titleStyle={{ color: 'white' }}
type="clear"
disabled={disabled}
onPress={() => onPressBtn()}
/>
</LinearGradient>
</View>
);
}

SubmitBtn.propTypes = {
disabled: PropTypes.bool.isRequired,
onPressBtn: PropTypes.func.isRequired,
};
Loading

0 comments on commit eda6868

Please sign in to comment.