unioil-loyalty-rn-app/app/screens/mpin/index.js

361 lines
15 KiB
JavaScript

import * as React from 'react';
import { View, Image, Text, TouchableOpacity, StyleSheet, StatusBar, Modal, ScrollView, AppState, Platform, Alert } from 'react-native';
import { connect } from "react-redux";
import { CustomPincode } from '../../components/pincodeinput';
import { ContactOptionsWithParams } from '../../components/contact.action';
import { RFValue } from 'react-native-responsive-fontsize';
import { openModal } from '../../redux/actions/AlertActions';
import Crypto from '../../components/crypto.js';
import NetInfo from "../../components/netstatus";
import DeviceInfo from 'react-native-device-info';
import Assets from '../../components/assets.manager.js';
import Theme from '../../components/theme.style.js';
import Icon from '../../components/icons.js';
import DB from '../../components/storage/';
import Elements from '../../components/elements.js';
import REQUEST from '../../components/api/';
import CustomSafeArea from '../../components/safeArea.component';
class Mpin extends React.Component {
constructor(props) {
super(props)
this.flag_register = false
}
state = {
mpin: this.props.route?.params?.mpin,
mobile_number: this.props.route?.params?.mobile_number,
isValid: false,
showModal: false,
loading: false,
userDetails: null,
appState: AppState.currentState,
openOptions: false
}
componentDidMount() {
this.appStateSubscription = AppState.addEventListener('change', this._handleAppStateChange);
this.fetchUserProfile();
// this.getPromoDiscountNotifications()
}
componentWillUnmount() {
if (this.appStateSubscription) {
this.appStateSubscription.remove();
}
}
_handleAppStateChange = (nextAppState) => {
if (this.state.appState.match(/inactive|background/) && nextAppState === 'active') {
this.registerToken()
// this.getPromoDiscountNotifications()
}
this.setState({ appState: nextAppState })
}
fetchUserProfile = async () => {
const USER_PROFILE = await DB.profile();
if (USER_PROFILE != undefined) {
let deciphermpin = null
try {
let hash = USER_PROFILE.data.customer_number.substring(0, 8)
deciphermpin = Crypto.decrypt(USER_PROFILE.data.mpin, hash)
} catch (error) {
console.log(error)
}
this.setState({ mpin: deciphermpin, mobile_number: USER_PROFILE.data.mobile, userDetails: USER_PROFILE })
}
DB.set('enter_mpin', 'true', success => { }, error => { })
}
registerToken = async () => {
NetInfo.netstatus(async isConnected => {
if (isConnected) {
const USERPROFILE = await DB.profile()
const fcmToken = await DB.get('fcmToken')
const isTokenRegister = await DB.get('is_token_register')
if (fcmToken == undefined || fcmToken == null) return
if (isTokenRegister == 'true') return
if (this.flag_register) return
this.flag_register = true
REQUEST("fcm_register", "post", {}, {}, {
token: fcmToken,
c_number: USERPROFILE.data.card_number
}, function (res) {
let isRegister = res.newFcmToken.c_number != undefined && res.newFcmToken.token != undefined ? 'true' : 'false'
this.flag_register = isRegister == 'true' ? true : false
DB.set('is_token_register', isRegister, onSuccess => { }, onError => { })
}, function (err) {
Alert.alert("Information", `\n${err.message}`);
this.flag_register = false
DB.set('is_token_register', 'false', onSuccess => { }, onError => { })
}, "FCM", "Register")
}
})
}
getPromoDiscountNotifications = async () => {
const USERPROFILE = await DB.profile()
const fcmToken = await DB.get('fcmToken')
REQUEST("account_fcm", "get",
{}, {
noID: true,
value: `${USERPROFILE.data.card_number}/${fcmToken}`
}, {},
async (res) => {
let notifications = JSON.parse(res.notifs)
if (notifications.length > 0) {
let newNotifications = notifications.map((notif, index) => {
notif.visible = true
return notif
})
let jsonNotifs = JSON.stringify(newNotifications)
await DB.set('notifications', jsonNotifs, onSuccess => { }, onError => console.log(onError))
}
}, function (err) {
Alert.alert("Information", `\n${err.message}`);
}, "FCM", "Register")
}
validateMpin = () => {
this.flag_register = false
this.props.navigation.reset({
index: 0,
routes: [{ name: 'Main' }],
});
}
changeNumber = async () => {
await DB.reset()
this.props.navigation.reset({
index: 0,
routes: [{ name: 'Login' }],
});
}
stripString = (regex, regexReplace, string, replaceString) => {
let validMobileNumber = regex.test(string);
if (!validMobileNumber) {
return null
}
return string.replace(regexReplace, replaceString)
}
sendCode = () => {
NetInfo.netstatus(isConnected => {
if (isConnected) {
this.setState({ loading: true, showModal: false })
this.requestSendCode(success => {
this.setState({ loading: false })
this.flag_register = false
this.props.navigation.navigate("Otp", {
lcard_uuid: this.state.userDetails.data.lcard_uuid,
mobile_number: Theme.formatter.MBNF(this.state.userDetails.data.mobile, 63),
cardnumber: this.state.userDetails.data.card_number
})
}, err => {
Alert.alert("Information", `\n${err.message}`);
this.setState({ loading: false })
})
} else {
Elements.nointernet2(this.props)
}
})
}
requestSendCode = async (successCallback, errorCallback) => {
let params = `lcard_uuid=${this.state.userDetails.data.lcard_uuid}&mobile=${Theme.formatter.PMBL(this.state.userDetails.data.mobile)}&is_resend=false`;
await REQUEST("requestOTP", "get", {}, params, {},
function (res) {
successCallback(res)
}, function (error) {
errorCallback(error)
}, "OTP", "Request"
)
}
recoverMPINModal = () => {
return (
<Modal
animationType="none"
transparent={true}
visible={this.state.showModal}>
<TouchableOpacity activeOpacity={1} onPress={() => this.setState({ showModal: false })} style={styles.centeredView}>
<View style={[styles.modalView, { backgroundColor: this.props.app_theme?.theme.dark ? this.props.app_theme?.theme.colors.border : Theme.colors.white }]}>
<View style={{ flexDirection: 'row', marginBottom: 25 }}>
<View style={{ flex: 1, justifyContent: 'center' }}>
<Text style={{ fontSize: 20, fontFamily: 'arial', color: this.props.app_theme?.theme.colors.text }}>MPIN Recovery</Text>
</View>
<TouchableOpacity onPress={() => this.setState({ showModal: false })}>
<Icon.Entypo name='cross' size={30} style={{ color: "gray" }} />
</TouchableOpacity>
</View>
<View style={{ width: '100%', marginBottom: 35, paddingRight: 10 }}>
<Text numberOfLines={3} adjustsFontSizeToFit style={{ fontSize: 17, fontFamily: 'arial', color: this.props.app_theme?.theme.dark ? this.props.app_theme?.theme.colors.text : Theme.colors.darkGray }}>To reset your MPIN, enter the 4-digit code that will be sent to your number and answer the security questions that follow.</Text>
</View>
<View style={{ alignItems: 'center', width: '100%' }}>
<TouchableOpacity onPress={() => this.sendCode()} style={{ width: '100%', padding: 15, borderRadius: 10, backgroundColor: Theme.colors.primary }}>
<Text style={{ alignSelf: 'center', color: '#fff', fontSize: 16 }}>Send Code</Text>
</TouchableOpacity>
</View>
</View>
</TouchableOpacity>
</Modal>
)
}
render() {
return (
<CustomSafeArea>
{Platform.OS === "android" && <StatusBar translucent={false} backgroundColor={Theme.colors.primary} />}
{/* <ScrollView */}
{/* contentContainerStyle={{flex: 1}} */}
{/* automaticallyAdjustContentInsets={true}> */}
{this.recoverMPINModal()}
<View style={styles.container}>
<View>
<View style={styles.logoContainer}>
<Image source={Assets.logo.unioil} style={styles.logo} />
</View>
<View style={styles.contactContainer}>
<Text style={[styles.contactLabel, { color: this.props.app_theme?.theme.colors.text }]}>+{Theme.formatter.CPN(this.state.mobile_number != undefined ? this.state.mobile_number : "")}</Text>
<TouchableOpacity onPress={() => this.props.openModal({
open: true,
title: "Change Number",
body: "Are you sure you want to change your logged in mobile number?",
yesCB: this.changeNumber,
theme: this.props.app_theme
})} style={styles.changeButton}>
<Text style={styles.changeButtonLabel}>Change</Text>
</TouchableOpacity>
</View>
<Text style={[styles.mpinLabel, { color: this.props.app_theme?.theme.colors.text }]}>Enter Your 4-Digit MPIN</Text>
</View>
<View>
<CustomPincode
isDeleteButton={true}
buttonDeletePosition={'right'}
defaultPin={this.state.mpin}
pinLength={4}
pointsLength={4}
buttonDeleteElement={
<View style={{ alignItems: 'center', justifyContent: 'center' }}>
<Icon.Entypo name='erase' size={30} style={{ color: "gray" }} />
</View>
}
completeCallback={(inputtedPin, isValid, callbackClear) => {
if (isValid) {
this.validateMpin()
}
// If you want clear your pincode data
if (inputtedPin) callbackClear()
}} />
</View>
<View style={{ flex: 1 }}>
<View style={{ flex: 1, justifyContent: 'flex-end', paddingBottom: 10 }}>
<TouchableOpacity onPress={() => this.setState({ showModal: true })}>
<Text style={{ color: Theme.colors.primary, fontSize: 15, fontFamily: 'Arial', textAlign: 'center' }}>Forgot MPIN?</Text>
</TouchableOpacity>
<TouchableOpacity onPress={() => this.setState({ openOptions: true })} style={{ marginVertical: 10 }}>
<Text style={{ color: this.props.app_theme?.theme.colors.text, fontSize: 15, fontFamily: 'Arial', textAlign: 'center' }}>Contact Us</Text>
</TouchableOpacity>
<Text style={{ color: this.props.app_theme?.theme.colors.text, fontSize: 15, fontFamily: 'Arial', textAlign: 'center' }}>v{DeviceInfo.getReadableVersion()}</Text>
</View>
</View>
</View>
<ContactOptionsWithParams
params={{ cardnumber: this.state.userDetails?.data.card_number }}
isOpen={this.state.openOptions}
onClose={() => this.setState({ openOptions: false })}
/>
{/* </ScrollView> */}
</CustomSafeArea>
)
}
}
const mapStateToProps = (state) => {
return {
app_theme: state.appThemeReducer.theme
}
}
const mapDispatchToProps = {
openModal
}
export default connect(mapStateToProps, mapDispatchToProps)(Mpin)
const styles = StyleSheet.create({
container: {
flex: 1,
},
logoContainer: {
width: '100%',
height: 90,
alignSelf: 'center',
justifyContent: 'center',
marginTop: 30
},
logo: {
width: '100%',
height: Theme.screen.w * .24,
resizeMode: 'contain',
tintColor: Theme.colors.primary
},
contactContainer: {
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'center',
padding: 8
},
contactLabel: {
color: Theme.colors.black,
fontSize: RFValue(14, Theme.screen.h),
fontFamily: 'Arial',
textAlign: 'center'
},
changeButton: {
backgroundColor: Theme.colors.primary,
paddingLeft: 8,
paddingRight: 8,
marginHorizontal: 5,
marginLeft: 15,
paddingVertical: 2,
borderRadius: 5
},
changeButtonLabel: {
color: Theme.colors.white,
fontSize: RFValue(13, Theme.screen.h),
fontFamily: 'Arial',
textAlign: 'center'
},
mpinLabel: {
color: Theme.colors.black,
fontSize: RFValue(15, Theme.screen.h),
fontFamily: 'Arial',
textAlign: 'center'
},
centeredView: {
flex: 1,
justifyContent: "center",
backgroundColor: '#00000090',
},
modalView: {
margin: 25,
backgroundColor: "white",
borderRadius: 15,
padding: 20,
alignItems: "center",
shadowColor: "#000",
shadowOffset: {
width: 0,
height: 2
},
shadowOpacity: 0.25,
shadowRadius: 4,
elevation: 5
},
})