Android_Retail/src/Pages/BookingScreen/Components/BookingFunctionality/CustomerOTP.jsx

483 lines
18 KiB
JavaScript

import { shallowEqual, useSelector } from 'react-redux';
import {
changeCustomerID,
ChangeSelectedCustDisable,
changeSelectedCustId,
changeSelectedOption,
PreferenceData,
} from '../../../../Features/BookingScreen/BookingData/BookingData';
import { useCallback, useEffect, useState } from 'react';
import {
changeKioskCustomerMobileNo,
globalKioskCustomerMobileNo,
} from '../../../../Features/Kiosk/kiosk.js';
import { HiOutlineBackspace } from 'react-icons/hi';
import { useDispatch } from 'react-redux';
import { isIndianMobile } from '../../../../utils/calculations.js';
import { IoIosWarning } from 'react-icons/io';
import './CustomerOTP.scss';
import { Messages } from '../../../../Components/Notifications/Messages.jsx';
import { DefaultModal } from '../../../../Components/Modal/DefaultModal.jsx';
import {
checkLastOrderTimeLimit,
sendupiotp,
} from '../../../../Features/UpiDetails/UpiDetails.js';
import { StoredSessionData } from '../../../../Features/ThemeChange/ThemeChange.js';
import { getAddCustomerDetails, postAddCustomerDetails } from '../../../../Features/BookingScreen/Customer/addCustomer.js';
const CustomerMobileNumberModal = ({ open, HandleCloseModal }) => {
const SettingDataSelector = useSelector(PreferenceData);
const CustomerMobileNumber = useSelector(globalKioskCustomerMobileNo);
const SessionData = useSelector(StoredSessionData, shallowEqual);
const dispatch = useDispatch();
const [number, setNumber] = useState(
CustomerMobileNumber ? CustomerMobileNumber : ''
);
const [messageType, setMessageType] = useState(null);
const [messageData, setMessageData] = useState(null);
const [canResend, setCanResend] = useState(true);
const [otpInput, setOtpInput] = useState(['', '', '', '']);
const [otpIndex, setOtpIndex] = useState(0);
const [otpSent, setOtpSent] = useState(false);
const [otpVerifed, setOtpVerified] = useState(false);
const [otpNumber, setOTPNumber] = useState(null);
const [maxLimitExceeded, setMaxLimitExceeded] = useState(null);
const [maxLimitExceededMessage, setMaxLimitExceededMessage] = useState(null);
const isOtpEnabled = SettingDataSelector?.[0]?.SettingDtlDetails?.find(
(setting) =>
setting?.SettingIdName?.toLowerCase() === 'kioskotp' &&
setting?.SettingValue === 'Y'
);
const isTimeLimitEnabled = SettingDataSelector?.[0]?.SettingDtlDetails?.find(
(setting) =>
(setting?.SettingIdName?.toLowerCase() === 'hours' ||
setting?.SettingIdName?.toLowerCase() === 'minutes') &&
setting?.SettingValue === 'Y'
);
useEffect(() => {
isIndianMobile(number) && fetchCustomerDetails(number);
}, [number]);
useEffect(() => {
if (otpInput.every((input) => input !== '')) {
verifyOtp();
}
}, [otpInput]);
const fetchCustomerDetails = async (number) => {
const response = await dispatch(
getAddCustomerDetails({
MobileNo: number,
AppId: SessionData.AppId,
CompId: SessionData.CompId,
BranchId: SessionData.BranchId,
})
)?.unwrap();
if (response?.data?.statusCode === 1) {
console.log(
'response?.data?.CustomerId',
response?.data,
response?.data?.data?.[0]?.CustId
);
dispatch(changeCustomerID(response?.data?.data?.[0]?.CustId));
let custvalues = {
value: number,
label: response?.data?.data?.[0]?.CustName || number,
CustId: response?.data?.data?.[0]?.CustId,
...response?.data?.data?.[0],
};
// {value: '8428086416', label: 'mohan', CustId: 'CUST1-281-437-74', CustName: 'mohan', Address1: undefined, …}
await dispatch(changeSelectedOption(custvalues));
await dispatch(changeSelectedCustId(response?.data?.data?.[0]?.CustId));
await dispatch(
ChangeSelectedCustDisable(true)
);
}else{
let postdata = {
"CustMobile":number,
"CustomerProfile": null,
"AppId": SessionData.AppId,
"CompId": SessionData.CompId,
"BranchId": SessionData.BranchId,
"CreatedBy": SessionData.UserId,
"InitialOutStanding": null,
"OfferType": "P",
"MarriedStatus": "N",
"CustomerAddressDtl": []
}
let response1 = await dispatch(postAddCustomerDetails(postdata)).unwrap();
if (response1?.data?.statusCode == 1) {
dispatch(changeSelectedOption(null));
dispatch(
changeCustomerID(
response1?.data?.CustomerDetails?.[
response1?.data?.CustomerDetails.length - 1
]
)
);
dispatch(
changeSelectedCustId(response1?.data?.CustomerDetails?.[0]?.CustId)
);
dispatch(
ChangeSelectedCustDisable(true)
);
} else{
setMessageData('Invalid mobile No.');
setMessageType('error');
setNumber('');
}
}
};
const setNumberFun = (newValue) => {
setNumber((prevNumber) => {
if (prevNumber.length < 10) {
return prevNumber + newValue;
}
return prevNumber;
});
};
const handleOtpNumber = (num) => {
if (otpIndex > 3) return;
const newOtp = [...otpInput];
newOtp[otpIndex] = num.toString();
setOtpInput(newOtp);
if (otpIndex < 3) {
setOtpIndex(otpIndex + 1);
}
};
const handleOtpBackspace = () => {
if (otpIndex < 0) return;
const newOtp = [...otpInput];
if (newOtp[otpIndex]) {
newOtp[otpIndex] = '';
} else if (otpIndex > 0) {
newOtp[otpIndex - 1] = '';
setOtpIndex(otpIndex - 1);
}
setOtpInput(newOtp);
};
const handleBackspace = () => {
setNumber((prevNumber) => prevNumber.slice(0, -1));
};
const checkLast30MinOrder = async (MobileNo) => {
const response = await dispatch(
checkLastOrderTimeLimit({
MobileNo,
AppId: SessionData.AppId,
CompId: SessionData.CompId,
BranchId: SessionData.BranchId,
})
)?.unwrap();
return response?.data;
};
const sendOTP = async () => {
const valid = isIndianMobile(number);
if (valid) {
if (isTimeLimitEnabled) {
const withinTimeLimit = await checkLast30MinOrder(number);
if (withinTimeLimit?.IsEligible === false) {
// setMessageData(withinTimeLimit?.response);
// setMessageType('warning');
setMaxLimitExceededMessage(withinTimeLimit?.response);
setMaxLimitExceeded(true);
await dispatch(changeSelectedOption(null));
await dispatch(changeSelectedCustId(null));
// Reset after 3 seconds
setTimeout(() => {
setMaxLimitExceeded(false);
setMaxLimitExceededMessage(null);
}, 2500);
return;
}
}
} else {
setMessageData('Please enter valid mobile No.');
setMessageType('warning');
return;
}
try {
setOtpIndex(0);
setOtpSent(true);
let response = await dispatch(
sendupiotp({
MobileNo: number,
CreatedBy: 0,
})
)?.unwrap();
if (response?.data?.statusCode == 1) {
setMessageData('OTP sent to your mobile number');
setMessageType('success');
setOTPNumber(response?.data?.OTP);
startResendTimer();
}
} catch (error) {
console.log(error);
}
};
const verifyOtp = () => {
const enteredOtp = otpInput.join('');
if (enteredOtp === otpNumber?.toString()) {
setMessageType('success');
setMessageData('OTP Verified Successfully');
setOtpSent(false);
setOtpInput(['', '', '', '']);
HandleCloseModal();
// setShowPaymentMethods(true);
setOtpVerified(true);
} else {
setMessageType('error');
setMessageData('Invalid OTP');
setOtpInput(['', '', '', '']);
setOtpIndex(0);
}
};
const onComplete = useCallback(() => {
setMessageData(null);
setMessageType(null);
}, []);
return (
<>
<Messages
messageType={messageType}
messageData={messageData}
onComplete={onComplete}
/>
<DefaultModal
open={open}
// handleCancel={HandleCloseModal}
footer={false}
width={900}
// {width > 768 ? 900 : 700}
children={
<div className="BSOTPpaymentModal-Master">
<h4 className="BSOTPTitlepayment">
{isOtpEnabled ? 'Enter Mobile Number To Order' : 'PAYMENT'}
</h4>
<div className="BSOTPpaymentModal_main">
{!otpSent && !otpVerifed && (
<>
<div className="BSOTPprompt">
{/* <p style={{ fontFamily: 'Poppins', fontWeight: '600' }}>
Get your order bill on your mobile <br />
via SMS / Whatsapp
</p> */}
</div>
<div
className={`BSOTPinputModal ${number ? 'green-border' : ''}`}
>
<input type="text" value={number} readOnly />
{number?.length === 10 && !isIndianMobile(number) && (
<div className="input-err">
Please Enter Valid Mobile Number
</div>
)}
</div>
{/* input boxxes */}
<div
className="BSOTPdailpad-main"
// style={{
// pointerEvents: selectedPaymentOption && 'none',
// opacity: selectedPaymentOption && '40%',
// }}
>
<div
className="BSOTPKiosk-dailpadModal"
// style={{ backgroundColor: getKioskLightColourdata }}
>
<div className="BSOTPKioskPayment-dailpad-1">
<p onClick={() => setNumberFun(1)}>1</p>
<p onClick={() => setNumberFun(2)}>2</p>
<p onClick={() => setNumberFun(3)}>3</p>
</div>
<div className="BSOTPKioskPayment-dailpad-2">
<p onClick={() => setNumberFun(4)}>4</p>
<p onClick={() => setNumberFun(5)}>5</p>
<p onClick={() => setNumberFun(6)}>6</p>
</div>
<div className="BSOTPKioskPayment-dailpad-3">
<p onClick={() => setNumberFun(7)}>7</p>
<p onClick={() => setNumberFun(8)}>8</p>
<p onClick={() => setNumberFun(9)}>9</p>
</div>
<div className="BSOTPKioskPayment-dailpad-4">
<p onClick={handleBackspace}>
<HiOutlineBackspace
size={30}
style={{ marginBottom: '-2px' }}
/>
</p>
<p onClick={() => setNumberFun(0)}>0</p>
<p style={{ background: 'none' }}></p>
</div>
</div>
</div>
{isOtpEnabled && (
<>
<button
className="BSOTPKioskOPTBTn"
// disabled={number?.length === 10}
onClick={() => sendOTP()}
>
Get OTP
</button>
</>
)}
</>
)}
{isOtpEnabled && otpSent && (
<div className="BSOTPotp-section">
<div style={{ fontFamily: 'Poppins', fontSize: '16px' }}>
Enter OTP
</div>
{/* Mobile Number + Edit */}
<div className="BSOTPotp-mobile-row">
<span className="BSOTPotp-mobile-number">{number}</span>
<button
className="BSOTPotp-edit-btn"
onClick={() => {
setOtpSent(false);
setOtpInput(['', '', '', '']);
}}
>
Edit
</button>
``{' '}
</div>
{/* 4 Digit OTP Input */}
<div className='optEnterResendOTP'>
<div className="BSOTPotp-input-container">
{otpInput.map((digit, index) => (
<input
key={index}
type="text"
value={digit}
className={`BSOTPotp-box ${index === otpIndex ? 'active' : ''}`}
onClick={() => setOtpIndex(index)}
readOnly
/>
))}
</div>
<div className="BSOTPotp-buttons">
{/* <button
className="verify-btn"
disabled={otpInput.join('').length !== 4}
onClick={verifyOtp}
>
Verify
</button> */}
<button
className="BSOTPresend-btn"
disabled={!canResend}
onClick={sendOTP}
>
{canResend ? 'Resend OTP' : `Resend in ${resendTimer}s`}
</button>
</div>
</div>
<div className="BSOTPKioskPayment-dailpad-main">
<div
className="BSOTPKiosk-dailpadModal"
// style={{ backgroundColor: getKioskLightColourdata }}
>
<div className="BSOTPKioskPayment-dailpad-1">
<p onClick={() => handleOtpNumber(1)}>1</p>
<p onClick={() => handleOtpNumber(2)}>2</p>
<p onClick={() => handleOtpNumber(3)}>3</p>
</div>
<div className="BSOTPKioskPayment-dailpad-2">
<p onClick={() => handleOtpNumber(4)}>4</p>
<p onClick={() => handleOtpNumber(5)}>5</p>
<p onClick={() => handleOtpNumber(6)}>6</p>
</div>
<div className="BSOTPKioskPayment-dailpad-3">
<p onClick={() => handleOtpNumber(7)}>7</p>
<p onClick={() => handleOtpNumber(8)}>8</p>
<p onClick={() => handleOtpNumber(9)}>9</p>
</div>
<div className="BSOTPKioskPayment-dailpad-4">
<p onClick={handleOtpBackspace}>
<HiOutlineBackspace size={30} />
</p>
<p onClick={() => handleOtpNumber(0)}>0</p>
<p style={{ background: 'none' }}></p>
</div>
</div>
</div>
{/* Buttons */}
</div>
)}
{/* {(!isOtpEnabled || (otpVerifed)) && <>
<p className="choiseTitle">Select Payment Method</p>
{console.log('selectedOption', selectedPaymentOption)}
<div
className="paymentChoise"
style={{
pointerEvents:
(!isIndianMobile(number) || selectedPaymentOption) &&
'none',
opacity:
(!isIndianMobile(number) || selectedPaymentOption) && '40%',
}}
>
{counterAvailability && (
<div
className="upi"
onClick={() => handlePaymentOption('Counter')}
>
<MdOutlinePayments size={50} opacity={0.5} />
<p style={{ fontSize: '12px', textAlign: 'center' }}>
PAY AT THE COUNTER
</p>
</div>
)}
{paymentOptionDetailsBusinessUpi && (
<div
className="upi"
onClick={() => handlePaymentOption('BU')}
>
<img src={UPI} alt="" width={60} />
<p> UPI</p>
</div>
)}
{!paymentOptionDetailsBusinessUpi && !counterAvailability && (
<div className="payment-error-msg">
Please Set Payment Options Contact Admin
</div>
)}
</div>
</>} */}
</div>
<div
className={`BSOTPItem3Warning ${maxLimitExceeded ? 'showing' : ''}`}
>
<p>
<IoIosWarning size={30} color="#b99400" />
{maxLimitExceededMessage}
</p>
</div>
</div>
}
/>
</>
);
};
export default CustomerMobileNumberModal;