Commit da896881 by Nguyễn Thị Thúy

update smart OTP UI

parents 194266f5 d9736648
import React, {Component, useEffect, useState} from 'react';
import {
View,
Text,
TextInput,
StyleSheet,
TouchableOpacity,
Platform,
Alert,
} from 'react-native';
import HeaderBack from '../../components/Header/HeaderBack';
import {
CodeField,
Cursor,
useBlurOnFulfill,
useClearByFocusCell,
} from 'react-native-confirmation-code-field';
import {getFontXD, HEIGHTXD, WIDTHXD} from '../../Config/Functions';
import R from '../../assets/R';
import {TABNAVIGATOR} from '../../routers/ScreenNames';
import {verifyOTPApi} from '../../apis/Functions/users';
import {useNavigation} from '@react-navigation/native';
import I18n from '../../helper/i18/i18n';
import AppText from '../../components/AppText';
import {showLoading, hideLoading} from '../../actions/loadingAction';
import {connect} from 'react-redux';
import {showAlert, TYPE} from '../../components/DropdownAlert';
import CountDown from '../../components/CountDown';
import {verifyOTPApiSmart} from '../../apis/Functions/users';
const CELL_COUNT = 4;
const ConfirmOTPSmart = (propsa) => {
const [value, setValue] = useState('');
const [isReset, setReset] = useState(false);
const navigate = useNavigation();
const ref = useBlurOnFulfill({value, cellCount: CELL_COUNT});
const [props, getCellOnLayoutHandler] = useClearByFocusCell({
value,
setValue,
});
const getOTP = async () => {
propsa.showLoading();
const res = await getOTPApi({
platform: Platform.OS,
otp_by: propsa.route.params.email,
type: 'FORGOT_PASSWORD',
});
propsa.hideLoading();
if (res.data.code == 200) {
setReset(!isReset);
showAlert(TYPE.SUCCESS, I18n.t('Notification'), res.data.message);
} else {
showAlert(TYPE.ERROR, I18n.t('Notification'), res.data.message);
}
};
const confirm = async () => {
if (!value) {
showAlert(TYPE.WARN, I18n.t('Notification'), I18n.t('EnterOTPRequest'));
} else if (value.length != 4) {
showAlert(TYPE.WARN, I18n.t('Notification'), I18n.t('OTPInvalid'));
} else {
propsa.showLoading();
const res = await verifyOTPApiSmart({
platform: Platform.OS,
password: propsa.route.params.password,
password_confirmation: propsa.route.params.password_confirmation,
otp: value,
type: 'FORGOT_PASSWORD',
});
propsa.hideLoading();
if (res.data.code == 200) {
navigate.navigate(TABNAVIGATOR);
} else {
showAlert(TYPE.ERROR, I18n.t('Notification'), res.data.message);
}
}
};
return (
<View style={{flex: 1}}>
<HeaderBack title={'VerifyOTP'} />
<View style={styles.container}>
<View style={{height: 20}} />
<View style={styles.wrap}>
<AppText i18nKey={'Verify_code'} style={styles.txtTitle} />
<View style={styles.containerCode}>
<CodeField
ref={ref}
{...props}
value={value}
onChangeText={setValue}
cellCount={CELL_COUNT}
rootStyle={styles.codeFieldRoot}
keyboardType="number-pad"
textContentType="oneTimeCode"
renderCell={({index, symbol, isFocused}) => (
<View
onLayout={getCellOnLayoutHandler(index)}
key={index}
style={[styles.cellRoot, isFocused && styles.focusCell]}>
<Text style={styles.cellText}>
{symbol || (isFocused ? <Cursor /> : null)}
</Text>
</View>
)}
/>
</View>
</View>
</View>
<View style={styles.footer}>
<TouchableOpacity onPress={confirm} style={styles.btn}>
<AppText i18nKey={'Continue'} style={styles.txtBtn} />
</TouchableOpacity>
<TouchableOpacity style={styles.wrapFooter} onPress={getOTP}>
<Text style={styles.txtNote}>{I18n.t('OTPValidFiveMinute')}</Text>
<AppText i18nKey={'Re_send'} style={styles.txtSend} />
</TouchableOpacity>
<CountDown isReset={isReset} />
</View>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
paddingVertical: 20,
},
footer: {
height: 200,
justifyContent: 'center',
alignItems: 'center',
},
wrap: {
flex: 1,
paddingTop: 30,
alignItems: 'center',
width: '100%',
paddingHorizontal: 50,
},
containerCode: {
height: 50,
width: '100%',
marginTop: 30,
},
codeFieldRoot: {
marginTop: 20,
},
focusCell: {
borderColor: '#000',
},
cellRoot: {
width: 40,
height: 40,
justifyContent: 'center',
alignItems: 'center',
borderBottomColor: '#ccc',
borderBottomWidth: 1,
},
cellText: {
color: '#000',
fontSize: 36,
textAlign: 'center',
},
focusCell: {
borderBottomColor: '#007AFF',
borderBottomWidth: 2,
},
txtTitle: {
fontSize: getFontXD(52),
color: '#979797',
},
btn: {
width: WIDTHXD(521),
height: HEIGHTXD(120),
borderRadius: 15,
backgroundColor: '#1C6AF6',
justifyContent: 'center',
alignItems: 'center',
},
txtBtn: {
color: R.colors.white,
fontSize: getFontXD(52),
textTransform: 'uppercase',
},
txtSend: {
fontSize: getFontXD(42),
color: '#1C6AF6',
},
wrapFooter: {
marginTop: 30,
flexDirection: 'row',
alignItems: 'center',
},
txtNote: {
color: '#A2A2A2',
fontSize: getFontXD(42),
fontStyle: 'italic',
},
});
const mapStateToProps = (state) => {
return {};
};
export default connect(mapStateToProps, {showLoading, hideLoading})(
ConfirmOTPSmart,
);
import React, {Component, useState} from 'react';
import {View, Text} from 'react-native';
import {CONFIRMOTPSMART} from '../../routers/ScreenNames';
import {useNavigation} from '@react-navigation/native';
import HeaderBack from '../../components/Header/HeaderBack';
import AppText from '../../components/AppText';
import TextField from '../../components/Input/TextField';
import Button from '../../components/Button';
import {connect} from 'react-redux';
import {
getFontXD,
HEIGHTXD,
WIDTHXD,
checkFormatArray,
} from '../../Config/Functions';
import R from '../../assets/R';
import {getOTPApiSmartOTP} from '../../apis/Functions/users';
import {showLoading, hideLoading} from '../../actions/loadingAction';
import I18n from '../../helper/i18/i18n';
import {TYPE, showAlert} from '../../components/DropdownAlert/index';
const SettingOTP = (props) => {
const navigatiton = useNavigation();
const [password, setPassword] = useState('');
const [password_confirmation, setPassword_confirmation] = useState('');
const getOTP = async () => {
const titles = [
I18n.t('PassGetSmartOTP'),
I18n.t('ConfirmPassGetSmartOTP'),
];
const index = checkFormatArray([password, password_confirmation]);
if (index === true) {
if (password == password_confirmation) {
props.showLoading();
const res = await getOTPApiSmartOTP({
platform: Platform.OS,
otp_by: props.user.email,
otp_password: '1234',
type: 'CREATE_OTP_PASSWORD',
});
props.hideLoading();
if (res.data.code == 200) {
navigatiton.navigate(CONFIRMOTPSMART, {
password,
password_confirmation,
});
} else {
showAlert(TYPE.ERROR, I18n.t('Notification'), res.data.message);
}
} else {
showAlert(
TYPE.WARN,
I18n.t('Notification'),
'Mật khẩu không trùng nhau!',
);
}
} else {
showAlert(
TYPE.WARN,
I18n.t('Notification'),
I18n.t('Please_fill_in') + titles[index],
);
}
};
return (
<View style={{flex: 1}}>
<HeaderBack title={'SettingOTP'} />
<View style={{flex: 1, marginHorizontal: 10, marginTop: 20}}>
<View style={{flex: 1}}>
<TextField
onChangeText={(val) => setPassword(val)}
maxLength={4}
isNumber={true}
title={I18n.t('PassGetSmartOTP')}
isPassWord={true}
/>
<TextField
maxLength={4}
isNumber={true}
isPassWord={true}
onChangeText={(val) => setPassword_confirmation(val)}
title={I18n.t('ConfirmPassGetSmartOTP')}
/>
</View>
<View>
<Button onClick={getOTP} title={'Xác nhận'} />
</View>
</View>
</View>
);
};
const mapStateToProps = (state) => {
return {
user: state.userReducer,
};
};
export default connect(mapStateToProps, {showLoading, hideLoading})(SettingOTP);
import React, {Component} from 'react';
import {View, Text, StyleSheet, Image} from 'react-native';
import HeaderBack from '../../components/Header/HeaderBack';
import I18n from '../../helper/i18/i18n';
import AppText from '../../components/AppText';
import {UPDATEOTP} from '../../routers/ScreenNames';
import R from '../../assets/R';
import Icon from 'react-native-vector-icons/AntDesign';
import {HEIGHTXD, WIDTHXD} from '../../Config/Functions';
const DATA = [
{
id: '1',
title: 'ChangeSmartOTP',
Screen: UPDATEOTP,
image: R.images.changeSmart,
},
{
id: '2',
title: 'Rules',
Screen: UPDATEOTP,
image: R.images.rules,
},
{
id: '3',
title: 'FAQs',
Screen: UPDATEOTP,
image: R.images.faq,
},
];
const Item = (props) => {
const {title, image} = props.item;
return (
<View style={styles.container}>
<Image style={styles.imgIcon} source={image} />
<View style={{flex: 1, justifyContent: 'center'}}>
<AppText i18nKey={title} />
</View>
<Icon name={'right'} size={20} color={R.colors.color777} />
</View>
);
};
const SmartOTPConfig = (props) => {
return (
<View style={{flex: 1}}>
<HeaderBack title={'SettingOTP'} />
<View style={{marginVertical: 20, backgroundColor: 'white'}}>
{DATA.map((item) => (
<Item item={item} />
))}
</View>
</View>
);
};
const styles = StyleSheet.create({
container: {
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-between',
paddingHorizontal: 10,
paddingVertical: 10,
borderBottomColor: R.colors.borderGray,
borderBottomWidth: 0.6,
},
imgIcon: {
width: WIDTHXD(62),
height: WIDTHXD(62),
resizeMode: 'contain',
marginRight: 10,
},
});
export default SmartOTPConfig;
import React, {Component} from 'react';
import {View, Text} from 'react-native';
const UpdateOTP = (props) => {
return (
<View>
<Text>UpdateOTP OTP</Text>
</View>
);
};
export default UpdateOTP;
...@@ -71,3 +71,13 @@ export const changeAvatart = async (body) => ...@@ -71,3 +71,13 @@ export const changeAvatart = async (body) =>
PostFormData(url.urlChangeAvatar, body) PostFormData(url.urlChangeAvatar, body)
.then((res) => res) .then((res) => res)
.catch((err) => err); .catch((err) => err);
export const getOTPApiSmartOTP = async (body) =>
PostLogin(url.urlGetSmartOTP, body)
.then((res) => res)
.catch((err) => err);
export const verifyOTPApiSmart = async (body) =>
PostData(url.urlStoreOTPSmart, body)
.then((res) => res)
.catch((err) => err);
export const root = 'http://services.dcvinvest.com/'; export const root = 'http://api.dcvinvest.com/';
export default { export default {
urllogin: root + 'api/auth/customer-login', urllogin: root + 'api/auth/customer-login',
...@@ -63,4 +63,7 @@ export default { ...@@ -63,4 +63,7 @@ export default {
urlCloseCQG: root + 'api/v1/customers/cancel-open-cqg', urlCloseCQG: root + 'api/v1/customers/cancel-open-cqg',
urlUpdateCQG: root + 'api/v1/customers/update-open-cqg', urlUpdateCQG: root + 'api/v1/customers/update-open-cqg',
urlGetUnitList: `${root}api/v1/customers/get-list-unit`, urlGetUnitList: `${root}api/v1/customers/get-list-unit`,
urlGetSmartOTP: root + 'api/v2/customer-get-otp',
urlStoreOTPSmart: root + 'api/v1/customers/store-otp-password',
}; };
...@@ -111,6 +111,13 @@ const images = { ...@@ -111,6 +111,13 @@ const images = {
toolRate: require('./images/toolRate.png'), toolRate: require('./images/toolRate.png'),
toolStopLoss: require('./images/toolStopLoss.png'), toolStopLoss: require('./images/toolStopLoss.png'),
placeholderImage: require('./images/placeholderImage.png'), placeholderImage: require('./images/placeholderImage.png'),
iconSettingGeneral: require('./images/iconSettingGeneral.png'),
iconSmartOTP: require('./images/iconSmartOTP.png'),
rules: require('./images/rules.png'),
changeSmart: require('./images/changeSmart.png'),
faq: require('./images/faq.png'),
}; };
export default images; export default images;
...@@ -37,6 +37,7 @@ import { ...@@ -37,6 +37,7 @@ import {
HISTORY, HISTORY,
CHOOSEMETHOD, CHOOSEMETHOD,
WALLETWITHDRAW, WALLETWITHDRAW,
SMARTOTPCONFIG,
} from '../../routers/ScreenNames'; } from '../../routers/ScreenNames';
import {useNavigation} from '@react-navigation/native'; import {useNavigation} from '@react-navigation/native';
import {connect} from 'react-redux'; import {connect} from 'react-redux';
...@@ -200,7 +201,21 @@ const menus = [ ...@@ -200,7 +201,21 @@ const menus = [
icon: R.images.iconSetting, icon: R.images.iconSetting,
screen: SETTING, screen: SETTING,
active: false, active: false,
children: null, children: [
{
title: 'SettingOTP',
icon: R.images.iconSmartOTP,
screen: SMARTOTPCONFIG,
id: '51',
},
{
id: '52',
title: 'SettingGeneral',
icon: R.images.iconSettingGeneral,
screen: SETTING,
},
],
}, },
]; ];
...@@ -345,7 +360,7 @@ const styles = StyleSheet.create({ ...@@ -345,7 +360,7 @@ const styles = StyleSheet.create({
}, },
imgIcon: { imgIcon: {
width: WIDTHXD(62), width: WIDTHXD(62),
height: HEIGHTXD(52), height: HEIGHTXD(62),
resizeMode: 'contain', resizeMode: 'contain',
}, },
txtTitle: { txtTitle: {
...@@ -373,10 +388,9 @@ const styles = StyleSheet.create({ ...@@ -373,10 +388,9 @@ const styles = StyleSheet.create({
containerItem: { containerItem: {
flexDirection: 'row', flexDirection: 'row',
alignItems: 'center', alignItems: 'center',
marginVertical: 5, marginVertical: 10,
borderRadius: WIDTHXD(75), borderRadius: WIDTHXD(75),
paddingVertical: 10,
paddingHorizontal: 10, paddingHorizontal: 10,
}, },
row: {flexDirection: 'row', flex: 1, alignItems: 'center'}, row: {flexDirection: 'row', flex: 1, alignItems: 'center'},
......
...@@ -12,6 +12,8 @@ const TextField = (props) => { ...@@ -12,6 +12,8 @@ const TextField = (props) => {
value, value,
editable, editable,
placeholder, placeholder,
isPassWord,
} = props; } = props;
return ( return (
...@@ -30,6 +32,7 @@ const TextField = (props) => { ...@@ -30,6 +32,7 @@ const TextField = (props) => {
placeholderTextColor={R.colors.placeHolder} placeholderTextColor={R.colors.placeHolder}
editable={editable != null ? false : true} editable={editable != null ? false : true}
autoCapitalize="none" autoCapitalize="none"
secureTextEntry={isPassWord}
value={value} value={value}
keyboardType={isNumber ? 'number-pad' : 'default'} keyboardType={isNumber ? 'number-pad' : 'default'}
onChangeText={(val) => onChangeText(val)} onChangeText={(val) => onChangeText(val)}
......
...@@ -302,4 +302,16 @@ export default { ...@@ -302,4 +302,16 @@ export default {
EnterSmartOTPPIN: 'Please enter the Smart OTP PIN code', EnterSmartOTPPIN: 'Please enter the Smart OTP PIN code',
ForgotPINCode: 'Forgot PIN code?', ForgotPINCode: 'Forgot PIN code?',
ReactivationSmartOTP: 'Reactivation the Smart OTP', ReactivationSmartOTP: 'Reactivation the Smart OTP',
SettingOTP: 'Setting Smart OTP',
SettingGeneral: 'Setting general',
ChangeSmartOTP: 'Change smart OTP',
Rules: 'Rules',
FAQs: 'FAQs',
PassGetSmartOTP: 'Password get Smart OTP',
ConfirmPassGetSmartOTP: 'Confirm password get Smart OTP',
PopupSettingSmartOTP: 'Do you want setting Smart OTP?',
}; };
...@@ -303,4 +303,16 @@ export default { ...@@ -303,4 +303,16 @@ export default {
EnterSmartOTPPIN: 'Vui lòng nhập mã PIN Smart OTP', EnterSmartOTPPIN: 'Vui lòng nhập mã PIN Smart OTP',
ForgotPINCode: 'Quên mã PIN?', ForgotPINCode: 'Quên mã PIN?',
ReactivationSmartOTP: 'Kích hoạt lại Smart OTP', ReactivationSmartOTP: 'Kích hoạt lại Smart OTP',
SettingOTP: 'Cài đặt Smart OTP',
SettingGeneral: 'Cài đặt chung',
ChangeSmartOTP: 'Đổi mã PIN Smart OTP',
Rules: 'Điều khoản và điều kiện',
FAQs: 'FAQs',
PassGetSmartOTP: 'Mật khẩu lấy Smart OTP',
ConfirmPassGetSmartOTP: 'Xác nhận mật khẩu lấy Smart OTP ',
PopupSettingSmartOTP: 'Bạn có muốn cài đặt Smart OTP?',
}; };
...@@ -78,3 +78,9 @@ export const CONVERTUNIT = 'CONVERTUNIT'; ...@@ -78,3 +78,9 @@ export const CONVERTUNIT = 'CONVERTUNIT';
export const EXCHANGERATE = 'EXCHANGERATE'; export const EXCHANGERATE = 'EXCHANGERATE';
export const SMARTOTP = 'SMARTOTP'; export const SMARTOTP = 'SMARTOTP';
export const ENTER_PASSWORD_SMART_OTP = 'ENTER_PASSWORD_SMART_OTP'; export const ENTER_PASSWORD_SMART_OTP = 'ENTER_PASSWORD_SMART_OTP';
export const SETTINGOTP = 'SETTINGOTP';
export const SMARTOTPCONFIG = 'SMARTOTPCONFIG';
export const UPDATEOTP = 'UPDATEOTP';
export const CONFIRMOTPSMART = 'CONFIRMOTPSMART';
...@@ -55,9 +55,14 @@ import CaculatedProfitLoss from '../Screens/Tool/CalculatorProfitLoss/Calculator ...@@ -55,9 +55,14 @@ import CaculatedProfitLoss from '../Screens/Tool/CalculatorProfitLoss/Calculator
import CaculatedStopLoss from '../Screens/Tool/CaculatedStopLoss'; import CaculatedStopLoss from '../Screens/Tool/CaculatedStopLoss';
import ConvertUnit from '../Screens/Tool/ConvertUnit'; import ConvertUnit from '../Screens/Tool/ConvertUnit';
import ExchangeRate from '../Screens/Tool/ExchangeRate'; import ExchangeRate from '../Screens/Tool/ExchangeRate';
import SmartOTP from '../Screens/SmartOTP/SmartOTP'; import SmartOTPConfig from '../Screens/SmartOTP/SmartOTPConfig';
import EnterPasswordSmartOTP from '../Screens/SmartOTP/EnterPasswordSmartOTP'; import EnterPasswordSmartOTP from '../Screens/SmartOTP/EnterPasswordSmartOTP';
import SmartOTP from '../Screens/SmartOTP/SmartOTP';
import SettigOTP from '../Screens/SmartOTP/SettingSmartOTP';
import UpdateOTP from '../Screens/SmartOTP/UpdateSmartOTP';
import ConfirmOTPSmart from '../Screens/SmartOTP/ConfirmOTPSmart';
import * as ScreenName from './ScreenNames'; import * as ScreenName from './ScreenNames';
const Stack = createStackNavigator(); const Stack = createStackNavigator();
...@@ -79,6 +84,15 @@ function MyStack(props) { ...@@ -79,6 +84,15 @@ function MyStack(props) {
component={CaculatedDeposit} component={CaculatedDeposit}
/> />
<Stack.Screen <Stack.Screen
name={ScreenName.CONFIRMOTPSMART}
component={ConfirmOTPSmart}
/>
<Stack.Screen name={ScreenName.SMARTOTPCONFIG} component={SmartOTPConfig} />
<Stack.Screen name={ScreenName.SETTINGOTP} component={SettigOTP} />
<Stack.Screen name={ScreenName.UPDATEOTP} component={UpdateOTP} />
<Stack.Screen
name={ScreenName.CACULATEDPROFITLOSS} name={ScreenName.CACULATEDPROFITLOSS}
component={CaculatedProfitLoss} component={CaculatedProfitLoss}
/> />
......
...@@ -17,7 +17,11 @@ import Notification from '../Screens/Notification/Notification'; ...@@ -17,7 +17,11 @@ import Notification from '../Screens/Notification/Notification';
import Test from '../Screens/NewFeed/Test'; import Test from '../Screens/NewFeed/Test';
import {useNavigation} from '@react-navigation/native'; import {useNavigation} from '@react-navigation/native';
import Transaction from '../Screens/Transaction/Transaction'; import Transaction from '../Screens/Transaction/Transaction';
import {AccountVerification, PACKETCQG} from '../routers/ScreenNames'; import {
AccountVerification,
PACKETCQG,
SETTINGOTP,
} from '../routers/ScreenNames';
import I18n, {setLocation} from '../helper/i18/i18n'; import I18n, {setLocation} from '../helper/i18/i18n';
import {changeLanguage} from '../actions/language'; import {changeLanguage} from '../actions/language';
import KEY from '../assets/AsynStorage'; import KEY from '../assets/AsynStorage';
...@@ -39,7 +43,7 @@ const TabNavigator = (props) => { ...@@ -39,7 +43,7 @@ const TabNavigator = (props) => {
checkDeepking(); checkDeepking();
setTimeout(() => { setTimeout(() => {
showPopUp(); showPopUp();
}, 3000); }, 4000);
let logoutListener = DeviceEventEmitter.addListener('logout', (e) => { let logoutListener = DeviceEventEmitter.addListener('logout', (e) => {
console.log('run in to logout'); console.log('run in to logout');
logout(navigate); logout(navigate);
...@@ -104,6 +108,15 @@ const TabNavigator = (props) => { ...@@ -104,6 +108,15 @@ const TabNavigator = (props) => {
return confirmAlert(I18n.t('PopupOpenCQG'), () => { return confirmAlert(I18n.t('PopupOpenCQG'), () => {
navigate.navigate(PACKETCQG); navigate.navigate(PACKETCQG);
}); });
} else if (!props.user.smart_otp_status) {
return confirmAlert(
props.language.language == 'vi'
? 'Bạn có muốn cài đặt Smart OTP?'
: 'Do you want setting Smart OTP?',
() => {
navigate.navigate(SETTINGOTP);
},
);
} }
}; };
return ( return (
......
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