mirror of
https://github.com/streetwriters/notesnook.git
synced 2025-12-22 22:49:45 +01:00
partially add login and signup forms
This commit is contained in:
@@ -9,7 +9,7 @@ import Login from '../../views/Login';
|
||||
import Signup from '../../views/Signup';
|
||||
import ForgotPassword from '../../views/ForgotPassword';
|
||||
import {DDS} from '../../../App';
|
||||
import {getElevation} from '../../utils/utils';
|
||||
import {getElevation, w} from '../../utils/utils';
|
||||
import {eSendEvent} from '../../services/eventManager';
|
||||
import {eLoginDialogNavigateBack} from '../../services/events';
|
||||
|
||||
@@ -147,8 +147,8 @@ class LoginDialog extends React.Component {
|
||||
<View
|
||||
style={{
|
||||
...getElevation(DDS.isTab ? 10 : 0),
|
||||
width: DDS.isTab ? '65%' : '100%',
|
||||
height: DDS.isTab ? '90%' : '100%',
|
||||
width: DDS.isTab ? 600 : '100%',
|
||||
height: DDS.isTab ? 500 : '100%',
|
||||
borderRadius: DDS.isTab ? 5 : 0,
|
||||
backgroundColor: colors.bg,
|
||||
padding: 8,
|
||||
|
||||
39
apps/mobile/src/services/validation.js
Normal file
39
apps/mobile/src/services/validation.js
Normal file
@@ -0,0 +1,39 @@
|
||||
import {ToastEvent} from '../utils/utils';
|
||||
|
||||
let regex = /^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/;
|
||||
|
||||
export function validateEmail(email) {
|
||||
if (email && email.length > 0) {
|
||||
//ToastEvent.show('Please enter a valid email address');
|
||||
return regex.test(email);
|
||||
} else {
|
||||
//ToastEvent.show('Please enter email or passoword to login');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
export function validatePass(password) {
|
||||
if (password && password.length <= 0) {
|
||||
//ToastEvent.show('No password provided');
|
||||
|
||||
return false;
|
||||
}
|
||||
if (password && password.length < 8 && password.length > 0) {
|
||||
//ToastEvent.show('Password too short');
|
||||
|
||||
return false;
|
||||
} else if (password && password.length > 8 && password.length > 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
export function validateUsername(username) {
|
||||
let regex = /^[a-z0-9_-]{3,16}$/gim;
|
||||
if (username && username.length > 0) {
|
||||
//ToastEvent.show('Please enter a valid email address');
|
||||
return regex.test(username);
|
||||
} else {
|
||||
//ToastEvent.show('Please enter email or passoword to login');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, {createRef, useEffect} from 'react';
|
||||
import React, {createRef, useEffect, useState} from 'react';
|
||||
import {
|
||||
BackHandler,
|
||||
SafeAreaView,
|
||||
@@ -14,6 +14,8 @@ import {Header} from '../../components/header';
|
||||
import {useTracked} from '../../provider';
|
||||
import {eSendEvent} from '../../services/eventManager';
|
||||
import {eCloseSideMenu} from '../../services/events';
|
||||
import {validateEmail, validatePass} from '../../services/validation';
|
||||
import Icon from 'react-native-vector-icons/Feather';
|
||||
|
||||
export const Login = ({navigation}) => {
|
||||
const [state, dispatch] = useTracked();
|
||||
@@ -90,70 +92,177 @@ export default Login;
|
||||
const renderLogin = (colors, navigation) => {
|
||||
const _email = createRef();
|
||||
const _pass = createRef();
|
||||
const [email, setEmail] = useState('');
|
||||
const [password, setPassword] = useState('');
|
||||
const [invalidEmail, setInvalidEmail] = useState(false);
|
||||
const [invalidPassword, setInvalidPassword] = useState(false);
|
||||
|
||||
return (
|
||||
<View
|
||||
style={{
|
||||
justifyContent: DDS.isTab ? 'center' : 'space-between',
|
||||
justifyContent: 'center',
|
||||
width: '80%',
|
||||
height: '80%',
|
||||
width: DDS.isTab ? '60%' : '100%',
|
||||
alignSelf: 'center',
|
||||
}}>
|
||||
<View>
|
||||
<Text
|
||||
style={{
|
||||
textAlign: 'right',
|
||||
marginHorizontal: 12,
|
||||
fontFamily: WEIGHT.regular,
|
||||
height: 25,
|
||||
textAlignVertical: 'bottom',
|
||||
}}>
|
||||
{invalidEmail ? (
|
||||
<Icon name="alert-circle" size={SIZE.sm} color={colors.errorText} />
|
||||
) : null}
|
||||
|
||||
{invalidEmail ? ' Email is invalid' : ''}
|
||||
</Text>
|
||||
|
||||
<TextInput
|
||||
ref={_email}
|
||||
onFocus={() => {
|
||||
if (!invalidEmail) {
|
||||
_email.current.setNativeProps({
|
||||
style: {
|
||||
borderColor: colors.navbg,
|
||||
borderColor: colors.accent,
|
||||
},
|
||||
});
|
||||
}
|
||||
}}
|
||||
defaultValue={email}
|
||||
onBlur={() => {
|
||||
if (!validateEmail(email)) {
|
||||
setInvalidEmail(true);
|
||||
_email.current.setNativeProps({
|
||||
style: {
|
||||
color: colors.errorText,
|
||||
borderColor: colors.errorText,
|
||||
},
|
||||
});
|
||||
} else {
|
||||
_email.current.setNativeProps({
|
||||
style: {
|
||||
borderColor: colors.nav,
|
||||
},
|
||||
});
|
||||
}
|
||||
}}
|
||||
textContentType="emailAddress"
|
||||
onChangeText={value => {
|
||||
setEmail(value);
|
||||
if (invalidEmail && validateEmail(email)) {
|
||||
setInvalidEmail(false);
|
||||
_email.current.setNativeProps({
|
||||
style: {
|
||||
color: colors.pri,
|
||||
borderColor: colors.accent,
|
||||
},
|
||||
});
|
||||
}
|
||||
}}
|
||||
onSubmitEditing={() => {
|
||||
if (!validateEmail(email)) {
|
||||
setInvalidEmail(true);
|
||||
_email.current.setNativeProps({
|
||||
style: {
|
||||
color: colors.errorText,
|
||||
},
|
||||
});
|
||||
}
|
||||
}}
|
||||
style={{
|
||||
padding: pv,
|
||||
borderWidth: 1.5,
|
||||
borderColor: colors.nav,
|
||||
marginHorizontal: '5%',
|
||||
marginHorizontal: 12,
|
||||
borderRadius: 5,
|
||||
fontSize: SIZE.md,
|
||||
fontFamily: WEIGHT.regular,
|
||||
marginBottom: 20,
|
||||
}}
|
||||
placeholder="Email"
|
||||
placeholderTextColor={colors.icon}
|
||||
/>
|
||||
|
||||
<Text
|
||||
style={{
|
||||
textAlign: 'right',
|
||||
marginHorizontal: 12,
|
||||
fontFamily: WEIGHT.regular,
|
||||
height: 25,
|
||||
textAlignVertical: 'bottom',
|
||||
}}>
|
||||
{invalidPassword ? (
|
||||
<Icon name="alert-circle" size={SIZE.sm} color={colors.errorText} />
|
||||
) : null}
|
||||
|
||||
{invalidPassword ? ' Password is invalid' : ''}
|
||||
</Text>
|
||||
<TextInput
|
||||
ref={_pass}
|
||||
onFocus={() => {
|
||||
if (!invalidPassword) {
|
||||
_pass.current.setNativeProps({
|
||||
style: {
|
||||
borderColor: colors.navbg,
|
||||
borderColor: colors.accent,
|
||||
},
|
||||
});
|
||||
}
|
||||
}}
|
||||
defaultValue={password}
|
||||
onBlur={() => {
|
||||
if (!validatePass(password)) {
|
||||
setInvalidPassword(true);
|
||||
_pass.current.setNativeProps({
|
||||
style: {
|
||||
color: colors.errorText,
|
||||
borderColor: colors.errorText,
|
||||
},
|
||||
});
|
||||
} else {
|
||||
_pass.current.setNativeProps({
|
||||
style: {
|
||||
borderColor: colors.nav,
|
||||
},
|
||||
});
|
||||
}
|
||||
}}
|
||||
onChangeText={value => {
|
||||
setPassword(value);
|
||||
|
||||
if (invalidPassword && validatePass(password)) {
|
||||
setInvalidPassword(false);
|
||||
_pass.current.setNativeProps({
|
||||
style: {
|
||||
color: colors.pri,
|
||||
borderColor: colors.accent,
|
||||
},
|
||||
});
|
||||
}
|
||||
}}
|
||||
onSubmitEditing={() => {
|
||||
if (!validatePass(password)) {
|
||||
setInvalidPassword(true);
|
||||
_pass.current.setNativeProps({
|
||||
style: {
|
||||
color: colors.errorText,
|
||||
},
|
||||
});
|
||||
}
|
||||
}}
|
||||
style={{
|
||||
padding: pv,
|
||||
borderWidth: 1.5,
|
||||
borderColor: colors.nav,
|
||||
marginHorizontal: '5%',
|
||||
marginHorizontal: 12,
|
||||
borderRadius: 5,
|
||||
fontSize: SIZE.md,
|
||||
fontFamily: WEIGHT.regular,
|
||||
marginBottom: 20,
|
||||
marginBottom: 25,
|
||||
}}
|
||||
secureTextEntry={true}
|
||||
placeholder="Password"
|
||||
placeholderTextColor={colors.icon}
|
||||
/>
|
||||
@@ -164,7 +273,7 @@ const renderLogin = (colors, navigation) => {
|
||||
padding: pv,
|
||||
backgroundColor: colors.accent,
|
||||
borderRadius: 5,
|
||||
marginHorizontal: '5%',
|
||||
marginHorizontal: 12,
|
||||
marginBottom: 10,
|
||||
alignItems: 'center',
|
||||
}}>
|
||||
@@ -178,15 +287,35 @@ const renderLogin = (colors, navigation) => {
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
|
||||
<View
|
||||
style={{
|
||||
width: '100%',
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'center',
|
||||
paddingHorizontal: 12,
|
||||
}}>
|
||||
<TouchableOpacity
|
||||
onPress={() => {
|
||||
navigation.navigate('Signup');
|
||||
}}
|
||||
activeOpacity={opacity}
|
||||
style={{}}>
|
||||
<Text
|
||||
style={{
|
||||
fontSize: SIZE.sm,
|
||||
fontFamily: WEIGHT.bold,
|
||||
color: colors.accent,
|
||||
}}>
|
||||
Create a New Account
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
<TouchableOpacity
|
||||
onPress={() => {
|
||||
navigation.navigate('ForgotPassword');
|
||||
}}
|
||||
activeOpacity={opacity}
|
||||
style={{
|
||||
alignItems: 'flex-end',
|
||||
marginHorizontal: '5%',
|
||||
}}>
|
||||
style={{}}>
|
||||
<Text
|
||||
style={{
|
||||
fontSize: SIZE.sm,
|
||||
@@ -197,31 +326,6 @@ const renderLogin = (colors, navigation) => {
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
|
||||
<View
|
||||
style={{
|
||||
width: '100%',
|
||||
position: DDS.isTab ? 'absolute' : 'relative',
|
||||
bottom: '0%',
|
||||
}}>
|
||||
<TouchableOpacity
|
||||
onPress={() => {
|
||||
navigation.navigate('Signup');
|
||||
}}
|
||||
activeOpacity={opacity}
|
||||
style={{
|
||||
alignItems: 'center',
|
||||
width: '100%',
|
||||
}}>
|
||||
<Text
|
||||
style={{
|
||||
fontSize: SIZE.sm,
|
||||
fontFamily: WEIGHT.bold,
|
||||
color: colors.accent,
|
||||
}}>
|
||||
Create a New Account
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, {createRef, useEffect} from 'react';
|
||||
import React, {createRef, useEffect, useState} from 'react';
|
||||
import {SafeAreaView, Text, TouchableOpacity, View} from 'react-native';
|
||||
import {TextInput} from 'react-native-gesture-handler';
|
||||
import {useIsFocused} from 'react-navigation-hooks';
|
||||
@@ -8,7 +8,12 @@ import {Header} from '../../components/header';
|
||||
import {useTracked} from '../../provider';
|
||||
import {eSubscribeEvent, eUnSubscribeEvent} from '../../services/eventManager';
|
||||
import {eLoginDialogNavigateBack} from '../../services/events';
|
||||
|
||||
import {
|
||||
validateUsername,
|
||||
validateEmail,
|
||||
validatePass,
|
||||
} from '../../services/validation';
|
||||
import Icon from 'react-native-vector-icons/Feather';
|
||||
export const Signup = ({navigation}) => {
|
||||
const [state, dispatch] = useTracked();
|
||||
const {colors, isLoginNavigator} = state;
|
||||
@@ -65,70 +70,261 @@ export default Signup;
|
||||
const renderSignup = colors => {
|
||||
const _email = createRef();
|
||||
const _pass = createRef();
|
||||
const _username = createRef();
|
||||
const [email, setEmail] = useState('');
|
||||
const [password, setPassword] = useState('');
|
||||
const [username, setUsername] = useState('');
|
||||
const [invalidEmail, setInvalidEmail] = useState(false);
|
||||
const [invalidPassword, setInvalidPassword] = useState(false);
|
||||
const [invalidUsername, setInvalidUsername] = useState(false);
|
||||
|
||||
return (
|
||||
<View
|
||||
style={{
|
||||
justifyContent: DDS.isTab ? 'center' : 'space-between',
|
||||
justifyContent: 'center',
|
||||
width: '80%',
|
||||
height: '80%',
|
||||
width: DDS.isTab ? '60%' : '100%',
|
||||
alignSelf: 'center',
|
||||
}}>
|
||||
<View>
|
||||
<Text
|
||||
style={{
|
||||
textAlign: 'right',
|
||||
marginHorizontal: 12,
|
||||
fontFamily: WEIGHT.regular,
|
||||
height: 25,
|
||||
textAlignVertical: 'bottom',
|
||||
}}>
|
||||
{invalidUsername ? (
|
||||
<Icon name="alert-circle" size={SIZE.sm} color={colors.errorText} />
|
||||
) : null}
|
||||
|
||||
{invalidUsername ? ' Username has invalid characters' : ''}
|
||||
</Text>
|
||||
|
||||
<TextInput
|
||||
ref={_email}
|
||||
ref={_username}
|
||||
onFocus={() => {
|
||||
_email.current.setNativeProps({
|
||||
if (!invalidUsername) {
|
||||
_username.current.setNativeProps({
|
||||
style: {
|
||||
borderColor: colors.navbg,
|
||||
borderColor: colors.accent,
|
||||
},
|
||||
});
|
||||
}
|
||||
}}
|
||||
defaultValue={username}
|
||||
onBlur={() => {
|
||||
_email.current.setNativeProps({
|
||||
if (!validateUsername(username)) {
|
||||
setInvalidUsername(true);
|
||||
_username.current.setNativeProps({
|
||||
style: {
|
||||
color: colors.errorText,
|
||||
borderColor: colors.errorText,
|
||||
},
|
||||
});
|
||||
} else {
|
||||
_username.current.setNativeProps({
|
||||
style: {
|
||||
borderColor: colors.nav,
|
||||
},
|
||||
});
|
||||
}
|
||||
}}
|
||||
textContentType="username"
|
||||
onChangeText={value => {
|
||||
setUsername(value);
|
||||
|
||||
if (invalidUsername && validateUsername(username)) {
|
||||
setInvalidUsername(false);
|
||||
_username.current.setNativeProps({
|
||||
style: {
|
||||
color: colors.pri,
|
||||
borderColor: colors.accent,
|
||||
},
|
||||
});
|
||||
}
|
||||
}}
|
||||
onSubmitEditing={() => {
|
||||
if (!validateUsername(username)) {
|
||||
setInvalidUsername(true);
|
||||
_username.current.setNativeProps({
|
||||
style: {
|
||||
color: colors.errorText,
|
||||
},
|
||||
});
|
||||
}
|
||||
}}
|
||||
style={{
|
||||
padding: pv,
|
||||
borderWidth: 1.5,
|
||||
borderColor: colors.nav,
|
||||
marginHorizontal: '5%',
|
||||
marginHorizontal: 12,
|
||||
borderRadius: 5,
|
||||
fontSize: SIZE.md,
|
||||
fontFamily: WEIGHT.regular,
|
||||
}}
|
||||
placeholder="Username (a-z _- 0-9)"
|
||||
placeholderTextColor={colors.icon}
|
||||
/>
|
||||
|
||||
<Text
|
||||
style={{
|
||||
textAlign: 'right',
|
||||
marginHorizontal: 12,
|
||||
fontFamily: WEIGHT.regular,
|
||||
height: 25,
|
||||
textAlignVertical: 'bottom',
|
||||
}}>
|
||||
{invalidEmail ? (
|
||||
<Icon name="alert-circle" size={SIZE.sm} color={colors.errorText} />
|
||||
) : null}
|
||||
|
||||
{invalidEmail ? ' Email is invalid' : ''}
|
||||
</Text>
|
||||
|
||||
<TextInput
|
||||
ref={_email}
|
||||
onFocus={() => {
|
||||
if (!invalidEmail) {
|
||||
_email.current.setNativeProps({
|
||||
style: {
|
||||
borderColor: colors.accent,
|
||||
},
|
||||
});
|
||||
}
|
||||
}}
|
||||
defaultValue={email}
|
||||
onBlur={() => {
|
||||
if (!validateEmail(email)) {
|
||||
setInvalidEmail(true);
|
||||
_email.current.setNativeProps({
|
||||
style: {
|
||||
color: colors.errorText,
|
||||
borderColor: colors.errorText,
|
||||
},
|
||||
});
|
||||
} else {
|
||||
_email.current.setNativeProps({
|
||||
style: {
|
||||
borderColor: colors.nav,
|
||||
},
|
||||
});
|
||||
}
|
||||
}}
|
||||
textContentType="emailAddress"
|
||||
onChangeText={value => {
|
||||
setEmail(value);
|
||||
if (invalidEmail && validateEmail(email)) {
|
||||
setInvalidEmail(false);
|
||||
_email.current.setNativeProps({
|
||||
style: {
|
||||
color: colors.pri,
|
||||
borderColor: colors.accent,
|
||||
},
|
||||
});
|
||||
}
|
||||
}}
|
||||
onSubmitEditing={() => {
|
||||
if (!validateEmail(email)) {
|
||||
setInvalidEmail(true);
|
||||
_email.current.setNativeProps({
|
||||
style: {
|
||||
color: colors.errorText,
|
||||
},
|
||||
});
|
||||
}
|
||||
}}
|
||||
style={{
|
||||
padding: pv,
|
||||
borderWidth: 1.5,
|
||||
borderColor: colors.nav,
|
||||
marginHorizontal: 12,
|
||||
borderRadius: 5,
|
||||
fontSize: SIZE.md,
|
||||
fontFamily: WEIGHT.regular,
|
||||
marginBottom: 20,
|
||||
}}
|
||||
placeholder="Email"
|
||||
placeholderTextColor={colors.icon}
|
||||
/>
|
||||
|
||||
<Text
|
||||
style={{
|
||||
textAlign: 'right',
|
||||
marginHorizontal: 12,
|
||||
fontFamily: WEIGHT.regular,
|
||||
height: 25,
|
||||
textAlignVertical: 'bottom',
|
||||
}}>
|
||||
{invalidPassword ? (
|
||||
<Icon name="alert-circle" size={SIZE.sm} color={colors.errorText} />
|
||||
) : null}
|
||||
|
||||
{invalidPassword ? ' Password too short' : ''}
|
||||
</Text>
|
||||
<TextInput
|
||||
ref={_pass}
|
||||
onFocus={() => {
|
||||
if (!invalidPassword) {
|
||||
_pass.current.setNativeProps({
|
||||
style: {
|
||||
borderColor: colors.navbg,
|
||||
borderColor: colors.accent,
|
||||
},
|
||||
});
|
||||
}
|
||||
}}
|
||||
defaultValue={password}
|
||||
onBlur={() => {
|
||||
if (!validatePass(password)) {
|
||||
setInvalidPassword(true);
|
||||
_pass.current.setNativeProps({
|
||||
style: {
|
||||
color: colors.errorText,
|
||||
borderColor: colors.errorText,
|
||||
},
|
||||
});
|
||||
} else {
|
||||
_pass.current.setNativeProps({
|
||||
style: {
|
||||
borderColor: colors.nav,
|
||||
},
|
||||
});
|
||||
}
|
||||
}}
|
||||
onChangeText={value => {
|
||||
setPassword(value);
|
||||
|
||||
if (invalidPassword && validatePass(password)) {
|
||||
setInvalidPassword(false);
|
||||
_pass.current.setNativeProps({
|
||||
style: {
|
||||
color: colors.pri,
|
||||
borderColor: colors.accent,
|
||||
},
|
||||
});
|
||||
}
|
||||
}}
|
||||
onSubmitEditing={() => {
|
||||
if (!validatePass(password)) {
|
||||
setInvalidPassword(true);
|
||||
_pass.current.setNativeProps({
|
||||
style: {
|
||||
color: colors.errorText,
|
||||
},
|
||||
});
|
||||
}
|
||||
}}
|
||||
style={{
|
||||
padding: pv,
|
||||
borderWidth: 1.5,
|
||||
borderColor: colors.nav,
|
||||
marginHorizontal: '5%',
|
||||
marginHorizontal: 12,
|
||||
borderRadius: 5,
|
||||
fontSize: SIZE.md,
|
||||
fontFamily: WEIGHT.regular,
|
||||
marginBottom: 20,
|
||||
marginBottom: 25,
|
||||
}}
|
||||
secureTextEntry={true}
|
||||
placeholder="Password"
|
||||
placeholderTextColor={colors.icon}
|
||||
/>
|
||||
@@ -139,7 +335,7 @@ const renderSignup = colors => {
|
||||
padding: pv,
|
||||
backgroundColor: colors.accent,
|
||||
borderRadius: 5,
|
||||
marginHorizontal: '5%',
|
||||
marginHorizontal: 12,
|
||||
marginBottom: 10,
|
||||
alignItems: 'center',
|
||||
}}>
|
||||
|
||||
Reference in New Issue
Block a user