483 lines
18 KiB
JavaScript
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;
|