Commit e6e4f28c by Tonk

add RegiterSuccess, update register form validate, add timer scroll tab

parent 24a28dab
......@@ -28,6 +28,7 @@ import OnboardingScreen from './screens/Public/OnboardingScreen';
import ForgotPasswordScreen from './screens/Public/ForgotPasswordScreen';
import LoginScreen from './screens/Public/LoginScreen';
import RegisterScreen from './screens/Public/RegisterScreen';
import RegisterSuccess from './screens/Public/RegisterSuccess';
import SendEmailScreen from './screens/Public/SendEmailScreen';
const defaultNavigationOptions = {
......@@ -219,6 +220,7 @@ const IntroStack = createStackNavigator(
Forget: ForgotPasswordScreen,
Register: RegisterScreen,
SendEmail: SendEmailScreen,
Success: RegisterSuccess,
},
{
initialRouteName: 'Login',
......@@ -233,7 +235,7 @@ const AppStack = createSwitchNavigator(
Main: MainStack,
},
{
initialRouteName: 'Intro',
initialRouteName: 'AuthLoading',
}
);
......
import React, { Component } from 'react';
import { Field, reduxForm } from 'redux-form';
import { View } from 'react-native';
import Input from './Input';
import { theme } from '../../constants/Styles';
import GradientBtn from '../GradientBtn';
// validaition
const required = value => (value ? undefined : 'This is a required field.');
const minChar = value => (value && !/(?=.{8,})/i.test(value) ? 'At least 8 characters' : undefined);
const email = value =>
value &&
!/^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/i.test(
value
)
? 'Invalid E-mail'
: undefined;
const lowercase = value =>
value && !/^(?=.*[a-z])/i.test(value) ? 'Password must contain at least 1 lowercase character' : undefined;
const uppercase = value =>
value && !/^(?=.*[A-Z])/i.test(value) ? 'Password must contain at least 1 uppercase character' : undefined;
const number = value =>
value && !/^(?=.*[0-9])/i.test(value) ? 'Password must contain at least 1 numeric character' : undefined;
const special = value =>
value && !/^(?=.*[!@#\$%\^&\*])/i.test(value) ? 'Password must contain at least 1 special character' : undefined;
const cfpassword = (value, allValues) => (value !== allValues.password ? 'Password not match' : undefined);
const phoneNum = value => (value && !/^[0][689][0-9]{8}$/i.test(value) ? 'Invalid number' : undefined);
class Register extends Component {
state = {
passVisible: false,
};
render() {
return (
<>
<View style={theme.containerWithVerticalMargin}>
<Field
name="name"
keyboardType="default"
component={Input}
validate={[required]}
placeholder="Name"
/>
<Field
name="surname"
keyboardType="default"
component={Input}
validate={[required]}
placeholder="Surname"
/>
<Field
name="email"
keyboardType="email-address"
component={Input}
validate={[required, email]}
placeholder="E-mail"
/>
<Field
name="password"
keyboardType="default"
component={Input}
validate={[required, minChar, lowercase, uppercase, number, special]}
placeholder={'Password'}
isPass
passVisible={this.state.passVisible}
onPressEye={() => this.setState({ passVisible: !this.state.passVisible })}
/>
<Field
name="cfpassword"
keyboardType="default"
component={Input}
validate={[required, cfpassword]}
placeholder={'Confirm password'}
isPass
passVisible={this.state.passVisible}
onPressEye={() => this.setState({ passVisible: !this.state.passVisible })}
/>
<Field
name="phoneno"
keyboardType="phone-pad"
component={Input}
validate={[required, phoneNum]}
placeholder={'Phone number'}
/>
</View>
{this.props.children}
<GradientBtn onPress={this.props.handleSubmit} title={'continue'} />
</>
);
}
}
const RegisterForm = reduxForm({
form: 'register',
})(Register);
export default RegisterForm;
......@@ -25,7 +25,18 @@ const Row = ({ data }) => (
{data.day.map((item, index) => (
<Text
key={index}
style={[theme.description, { color: item.dayActive ? color.primary : color.grey }]}
style={[
theme.description,
{
color: data.active
? item.dayActive
? color.primary
: color.grey
: item.dayActive
? color.grey
: color.darkGrey,
},
]}
>
{item.day}{' '}
</Text>
......@@ -34,14 +45,17 @@ const Row = ({ data }) => (
</View>
<View style={{ flex: 1 }}>
<Text style={[theme.title, { fontWeight: 'normal' }]}>{data.name}</Text>
<Text style={theme.description}>{data.active ? 'Active' : '???'} </Text>
<Text style={theme.description}>{data.active ? 'Active' : 'Inactive'} </Text>
</View>
<View style={{ flex: 1, alignItems: 'flex-end' }}>
<View style={{ alignItems: 'center' }}>
<Text
style={[
theme.title,
{ color: data.power ? color.success : color.primary, fontWeight: 'normal' },
{
color: data.active ? (data.power ? color.success : color.primary) : color.grey,
fontWeight: 'normal',
},
]}
>
{data.power ? 'ON' : 'OFF'}
......
import React, { Component } from 'react';
import { Fab, Icon, Text } from 'native-base';
import { View, StyleSheet, FlatList, ScrollView, TouchableHighlight, Modal } from 'react-native';
import { Switch, Button } from 'native-base';
import { Switch, Button, Tab, Tabs, ScrollableTab } from 'native-base';
import { HeaderButtons, Item as HeaderItem } from 'react-navigation-header-buttons';
import IoniconsHeaderButton from '../../../components/IoniconsHeaderButton';
import { color, theme } from '../../../constants/Styles';
......@@ -13,9 +13,96 @@ import { height } from '../../../constants/Layout';
import InputField from '../../../components/InputField';
// mock data
const mockData = [
const MultipleMockData = [
{
tabName: 'Main MCB Link',
timer: [
{
time: '6:00',
period: 'AM',
name: 'Slot 1',
active: true,
power: true,
day: [
{ day: 'S', dayActive: true },
{ day: 'M', dayActive: true },
{ day: 'T', dayActive: true },
{ day: 'W', dayActive: true },
{ day: 'T', dayActive: false },
{ day: 'F', dayActive: true },
{ day: 'S', dayActive: true },
],
},
{
time: '7:00',
period: 'AM',
name: 'Slot 2',
active: true,
power: false,
day: [
{ day: 'S', dayActive: true },
{ day: 'M', dayActive: true },
{ day: 'T', dayActive: true },
{ day: 'W', dayActive: true },
{ day: 'T', dayActive: false },
{ day: 'F', dayActive: true },
{ day: 'S', dayActive: false },
],
},
{
time: '8:00',
period: 'AM',
name: 'Slot 3',
active: false,
power: true,
day: [
{ day: 'S', dayActive: false },
{ day: 'M', dayActive: false },
{ day: 'T', dayActive: true },
{ day: 'W', dayActive: false },
{ day: 'T', dayActive: false },
{ day: 'F', dayActive: false },
{ day: 'S', dayActive: false },
],
},
{
time: '9:00',
period: 'AM',
name: 'Slot 4',
active: true,
power: false,
day: [
{ day: 'S', dayActive: true },
{ day: 'M', dayActive: true },
{ day: 'T', dayActive: true },
{ day: 'W', dayActive: true },
{ day: 'T', dayActive: false },
{ day: 'F', dayActive: true },
{ day: 'S', dayActive: false },
],
},
{
time: '8:00',
period: 'PM',
name: 'Slot 5',
active: false,
power: true,
day: [
{ day: 'S', dayActive: false },
{ day: 'M', dayActive: false },
{ day: 'T', dayActive: true },
{ day: 'W', dayActive: false },
{ day: 'T', dayActive: false },
{ day: 'F', dayActive: false },
{ day: 'S', dayActive: false },
],
},
],
},
{
tabName: 'MCB Link 1',
timer: [
{
id: 1,
time: '6:00',
period: 'AM',
name: 'Slot 1',
......@@ -32,7 +119,6 @@ const mockData = [
],
},
{
id: 2,
time: '7:00',
period: 'AM',
name: 'Slot 2',
......@@ -49,7 +135,6 @@ const mockData = [
],
},
{
id: 3,
time: '8:00',
period: 'PM',
name: 'Slot 3',
......@@ -65,6 +150,167 @@ const mockData = [
{ day: 'S', dayActive: false },
],
},
],
},
{
tabName: 'MCB Link 2',
timer: [
{
time: '6:00',
period: 'AM',
name: 'Slot 1',
active: false,
power: true,
day: [
{ day: 'S', dayActive: true },
{ day: 'M', dayActive: true },
{ day: 'T', dayActive: true },
{ day: 'W', dayActive: true },
{ day: 'T', dayActive: false },
{ day: 'F', dayActive: true },
{ day: 'S', dayActive: true },
],
},
{
time: '7:00',
period: 'AM',
name: 'Slot 2',
active: false,
power: false,
day: [
{ day: 'S', dayActive: true },
{ day: 'M', dayActive: true },
{ day: 'T', dayActive: true },
{ day: 'W', dayActive: true },
{ day: 'T', dayActive: false },
{ day: 'F', dayActive: true },
{ day: 'S', dayActive: false },
],
},
{
time: '8:00',
period: 'PM',
name: 'Slot 3',
active: false,
power: true,
day: [
{ day: 'S', dayActive: false },
{ day: 'M', dayActive: false },
{ day: 'T', dayActive: true },
{ day: 'W', dayActive: false },
{ day: 'T', dayActive: false },
{ day: 'F', dayActive: false },
{ day: 'S', dayActive: false },
],
},
],
},
{
tabName: 'MCB Link 3',
timer: [
{
time: '6:00',
period: 'AM',
name: 'Slot 1',
active: true,
power: true,
day: [
{ day: 'S', dayActive: true },
{ day: 'M', dayActive: true },
{ day: 'T', dayActive: true },
{ day: 'W', dayActive: true },
{ day: 'T', dayActive: false },
{ day: 'F', dayActive: true },
{ day: 'S', dayActive: true },
],
},
{
time: '7:00',
period: 'AM',
name: 'Slot 2',
active: true,
power: false,
day: [
{ day: 'S', dayActive: true },
{ day: 'M', dayActive: true },
{ day: 'T', dayActive: true },
{ day: 'W', dayActive: true },
{ day: 'T', dayActive: false },
{ day: 'F', dayActive: true },
{ day: 'S', dayActive: false },
],
},
{
time: '8:00',
period: 'PM',
name: 'Slot 3',
active: false,
power: true,
day: [
{ day: 'S', dayActive: false },
{ day: 'M', dayActive: false },
{ day: 'T', dayActive: true },
{ day: 'W', dayActive: false },
{ day: 'T', dayActive: false },
{ day: 'F', dayActive: false },
{ day: 'S', dayActive: false },
],
},
],
},
{
tabName: 'MCB Link 4',
timer: [
{
time: '6:00',
period: 'AM',
name: 'Slot 1',
active: true,
power: true,
day: [
{ day: 'S', dayActive: true },
{ day: 'M', dayActive: true },
{ day: 'T', dayActive: true },
{ day: 'W', dayActive: true },
{ day: 'T', dayActive: false },
{ day: 'F', dayActive: true },
{ day: 'S', dayActive: true },
],
},
{
time: '7:00',
period: 'AM',
name: 'Slot 2',
active: true,
power: false,
day: [
{ day: 'S', dayActive: true },
{ day: 'M', dayActive: true },
{ day: 'T', dayActive: true },
{ day: 'W', dayActive: true },
{ day: 'T', dayActive: false },
{ day: 'F', dayActive: true },
{ day: 'S', dayActive: false },
],
},
{
time: '8:00',
period: 'PM',
name: 'Slot 3',
active: false,
power: true,
day: [
{ day: 'S', dayActive: false },
{ day: 'M', dayActive: false },
{ day: 'T', dayActive: true },
{ day: 'W', dayActive: false },
{ day: 'T', dayActive: false },
{ day: 'F', dayActive: false },
{ day: 'S', dayActive: false },
],
},
],
},
];
export default class TimerScreen extends Component {
......@@ -115,18 +361,38 @@ export default class TimerScreen extends Component {
render() {
return (
<>
<Tabs
tabBarUnderlineStyle={{ backgroundColor: 'transparent' }}
renderTabBar={() => <ScrollableTab style={{ backgroundColor: color.white, borderWidth: 0 }} />}
>
{MultipleMockData.map((item, index) => (
<Tab
key={index + item.tabName}
textStyle={[theme.description]}
activeTextStyle={[theme.description, theme.textWhite]}
tabStyle={{ backgroundColor: color.white }}
activeTabStyle={{
backgroundColor: color.primary,
borderRadius: 100,
margin: 10,
}}
heading={item.tabName}
>
<FlatList
data={mockData}
data={item.timer}
ListEmptyComponent={() => (
<View>
<Text style={[theme.normalText, theme.mt2]}>No Data</Text>
</View>
)}
ItemSeparatorComponent={() => <View style={styles.separator} />}
ListFooterComponent={() => mockData.length > 0 && <View style={styles.separator} />}
ListFooterComponent={() => item.timer.length > 0 && <View style={styles.separator} />}
renderItem={({ item, index }) => <SwipeableRow item={item} index={index} />}
keyExtractor={(item, index) => `timer ${index}`}
/>
</Tab>
))}
</Tabs>
<Modal
transparent
......
import React, { Component } from 'react';
import { Container, Text, Content, View } from 'native-base';
import { Container, Text, Content, View, Icon } from 'native-base';
import { theme } from '../../constants/Styles';
import { Form, Field } from 'react-native-validate-form';
import InputField from '../../components/InputField';
......@@ -37,6 +37,11 @@ export default class ForgotPasswordScreen extends Component {
render() {
return (
<Container>
<Icon
name={'arrow-round-back'}
style={{ position: 'absolute', top: '6%', left: '5%' }}
onPress={() => this.props.navigation.goBack()}
/>
<Content style={theme.introContainer}>
<Text style={[theme.title, theme.centerText]}>Forgot Password</Text>
<View style={{ marginTop: 40 }}>
......
import React, { Component } from 'react';
import { Container, Text, CheckBox } from 'native-base';
import { Container, Text, CheckBox, Icon } from 'native-base';
import { color, theme } from '../../constants/Styles';
import { Form, Field } from 'react-native-validate-form';
import InputField from '../../components/InputField';
import { Alert, KeyboardAvoidingView, View } from 'react-native';
import GradientBtn from '../../components/GradientBtn';
// validations
const required = value => (value ? undefined : 'This is a required field.');
const minChar = value => (value && !/^.{6,}$/i.test(value) ? 'At least 6 characters' : undefined);
const email = value =>
value && !/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,5}$/i.test(value)
? 'Please provide a valid email address.'
: undefined;
const phoneNum = value => (value && !/^[0][689][0-9]{8}$/i.test(value) ? 'Invalid number' : undefined);
const cfPassword = value => (value && value == this.password ? 'Password not match' : undefined); //how??
import { KeyboardAvoidingView, View } from 'react-native';
import RegisterForm from '../../components/Form/RegisterForm';
export default class RegisterScreen extends Component {
state = {
errors: [],
isCheck: false,
name: '',
surName: '',
email: '',
password: '',
cfPassword: '',
phoneNum: '',
passVisible: false,
cfPassVisible: false,
};
submitForm() {
let submitResults = this.registerForm.validate();
let errors = [];
submitResults.forEach(item => {
errors.push({ field: item.fieldName, error: item.error });
});
this.setState({ errors: errors });
}
submitSuccess() {
console.log('Submit Success!');
Alert.alert(
'Completed!',
'You have completed your registration',
[
{
text: 'Go to Login',
onPress: () => {
this.props.navigation.navigate('Login');
},
},
],
{ cancelable: false }
);
if (this.state.isCheck == false) {
alert('You have to accept Terms and Conditions!');
} else {
this.props.navigation.navigate('Success');
}
submitFailed() {
console.log('Submit Failed!');
}
submit = values => {
this.submitSuccess();
};
render() {
return (
<Container>
<Icon
name={'arrow-round-back'}
style={{ position: 'absolute', top: '6%', left: '5%' }}
onPress={() => this.props.navigation.goBack()}
/>
<KeyboardAvoidingView style={theme.introContainer} behavior="padding" enabled>
<Text style={theme.title}>Register</Text>
<Form
ref={ref => (this.registerForm = ref)}
validate={true}
submit={this.submitSuccess.bind(this)}
failed={this.submitFailed.bind(this)}
errors={this.state.errors}
style={theme.containerWithVerticalMargin}
>
{/* ---name--- */}
<Field
required
component={InputField}
validations={[required]}
name="name"
value={this.state.name}
onChangeText={val => this.setState({ name: val })}
placeholder="Name"
/>
{/* ---surName--- */}
<Field
required
component={InputField}
validations={[required]}
name="surName"
value={this.state.surName}
onChangeText={val => this.setState({ surName: val })}
placeholder="Surname"
/>
{/* ---email--- */}
<Field
required
component={InputField}
validations={[required, email]}
name="email"
value={this.state.email}
onChangeText={val => this.setState({ email: val })}
placeholder="E-mail"
/>
{/* ---password--- */}
<Field
required
component={InputField}
validations={[required, minChar]}
name="password"
value={this.state.password}
onChangeText={val => this.setState({ password: val })}
placeholder="Password"
isPass={true}
passVisible={this.state.passVisible}
onPressEye={() => this.setState({ passVisible: !this.state.passVisible })}
/>
{/* ---cf password--- */}
<Field
required
component={InputField}
validations={[required, cfPassword, minChar]}
name="cfPassword"
value={this.state.cfPassword}
onChangeText={val => this.setState({ cfPassword: val })}
placeholder="Confirm password"
isPass={true}
passVisible={this.state.cfPassVisible}
onPressEye={() => this.setState({ cfPassVisible: !this.state.cfPassVisible })}
/>
{/* ---phone no--- */}
<Field
required
component={InputField}
validations={[required, phoneNum]}
name="phoneNum"
value={this.state.phoneNum}
onChangeText={val => this.setState({ phoneNum: val })}
placeholder="Phone number"
/>
</Form>
<RegisterForm onSubmit={this.submit}>
<View style={theme.rowContainer}>
<CheckBox
color={color.grey}
......@@ -158,7 +48,7 @@ export default class RegisterScreen extends Component {
<Text style={[theme.description, theme.linkText]}>Terms and Conditions</Text>.
</Text>
</View>
<GradientBtn onPress={this.submitForm.bind(this)} title={'continue'} />
</RegisterForm>
</KeyboardAvoidingView>
</Container>
);
......
import React, { Component } from 'react';
import { View, Text, Image } from 'react-native';
import { theme, color } from '../../constants/Styles';
import GradientBtn from '../../components/GradientBtn';
export default class RegisterSuccess extends Component {
render() {
return (
<View style={theme.introContainer}>
<Text style={[theme.title, theme.textSuccess, theme.centerText]}>Register Successfully</Text>
<Image
style={{
width: 135,
height: 135,
alignSelf: 'center',
marginVertical: 30,
tintColor: color.primary,
}}
source={{
uri: 'https://image.flaticon.com/icons/png/512/91/91848.png',
}}
/>
<Text style={[theme.title, theme.centerText]}>Check your email</Text>
<Text style={[theme.normalText, theme.centerText, theme.mt1]}>
Your registration was successful. {'\n'}Please check your registered email for email verification.
</Text>
<GradientBtn
onPress={() => {
this.props.navigation.navigate('Login');
}}
title={'ok'}
/>
</View>
);
}
}
import React, { Component } from 'react';
import { Container, Text, Content, View, Button } from 'native-base';
import { Image, StyleSheet } from 'react-native';
import { theme } from '../../constants/Styles';
import { theme, color } from '../../constants/Styles';
import GradientBtn from '../../components/GradientBtn';
const styles = StyleSheet.create({
......@@ -23,12 +23,11 @@ export default class SendEmailScreen extends Component {
width: 135,
height: 135,
alignSelf: 'center',
borderRadius: 65,
marginTop: 50,
marginVertical: 30,
tintColor: color.primary,
}}
source={{
uri:
'https://constructioncompanieslebanon.com/wp-content/uploads/2018/02/6ba96ffc82c13a9c4271233ab23e9afe.jpg',
uri: 'https://image.flaticon.com/icons/png/512/91/91848.png',
}}
/>
<Text style={[theme.title, theme.centerText]}>Check you email</Text>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment