diff --git a/src/Features/UpiDetails/UpiDetails.js b/src/Features/UpiDetails/UpiDetails.js index 285142c..9897332 100644 --- a/src/Features/UpiDetails/UpiDetails.js +++ b/src/Features/UpiDetails/UpiDetails.js @@ -45,6 +45,13 @@ export const putupi = createAsyncThunk('putupi', async (putData) => { return await axiosRetailInstanceData.put(`/upi`, putData); }); +export const checkLastOrderTimeLimit = createAsyncThunk('kiosk/lastOrderTimeLimit', async (data) => { + const { MobileNo, CompId, AppId, BranchId } = data; + if (MobileNo) { + return await axiosRetailInstanceData.get(`/Selfbookingeligibility?mobileNo=${MobileNo}&CompId=${CompId}&AppId=${AppId}&BranchId=${BranchId}`); + } +}); + export const delupi = createAsyncThunk('delupi', async (deleteData) => { if ( data?.CompId != null && diff --git a/src/Pages/BookingScreen/Template/SalesCountComponent.jsx b/src/Pages/BookingScreen/Template/SalesCountComponent.jsx index 2230ff8..24494ec 100644 --- a/src/Pages/BookingScreen/Template/SalesCountComponent.jsx +++ b/src/Pages/BookingScreen/Template/SalesCountComponent.jsx @@ -205,7 +205,7 @@ const SalesCountComponent = React.memo( let AutoReceiveStock = preferencedata?.[0]?.SettingDtlDetails?.some( (s) => s?.SettingIdName?.toLowerCase() === 'autoreceivestock' && - s?.SettingValue === 'Y' + s?.SettingValue === 'N' ); setAutoReceiveStock(!AutoReceiveStock); if (AutoReceiveStock) { diff --git a/src/Pages/Kiosk/Components/KioskFooter.jsx b/src/Pages/Kiosk/Components/KioskFooter.jsx index 2ff6a12..2db1fbf 100644 --- a/src/Pages/Kiosk/Components/KioskFooter.jsx +++ b/src/Pages/Kiosk/Components/KioskFooter.jsx @@ -7,6 +7,7 @@ import { MdCurrencyRupee } from 'react-icons/md'; import PozoDineInIcon from '../KioskIcons/KioskDineIn'; import TakeAway from '../KioskIcons/KioskTakeAway'; import { + changeKioskCustomerMobileNo, changeKioskPageName, getKioskDarkColour, globalCurrentKioskPageName, @@ -54,6 +55,7 @@ const KioskFooter = (props) => { const Oncancel = () => { dispatch(changeKioskPageName('initialPage')); dispatch(changeAllGlbStatustData()); + dispatch(changeKioskCustomerMobileNo(null)); // clear all global val }; @@ -110,6 +112,7 @@ const KioskFooter = (props) => { }; const handlePaymentCancel = () => { setPaymentModalOpen(false); + dispatch(changeKioskCustomerMobileNo(null)); }; return (
diff --git a/src/Pages/Kiosk/Components/KioskFooter2.jsx b/src/Pages/Kiosk/Components/KioskFooter2.jsx index 12a864d..a435001 100644 --- a/src/Pages/Kiosk/Components/KioskFooter2.jsx +++ b/src/Pages/Kiosk/Components/KioskFooter2.jsx @@ -3,6 +3,7 @@ import { useDispatch, useSelector } from 'react-redux'; import { Popconfirm, Drawer } from 'antd'; import { QuestionCircleOutlined } from '@ant-design/icons'; import { + changeKioskCustomerMobileNo, changeKioskPageName, getKioskDarkColour, globalCurrentKioskPageName, @@ -75,6 +76,7 @@ const KioskFooter2 = (props) => { const Oncancel = () => { dispatch(changeKioskPageName('initialPage')); dispatch(changeAllGlbStatustData()); + dispatch(changeKioskCustomerMobileNo(null)); // clear all global val }; const MobileNumberPage = async () => { @@ -105,6 +107,7 @@ const KioskFooter2 = (props) => { }; const handlePaymentCancel = () => { setPaymentModalOpen(false); + dispatch(changeKioskCustomerMobileNo(null)); }; return ( diff --git a/src/Pages/Kiosk/Components/KioskFooter3.jsx b/src/Pages/Kiosk/Components/KioskFooter3.jsx index 9077cd2..14c3684 100644 --- a/src/Pages/Kiosk/Components/KioskFooter3.jsx +++ b/src/Pages/Kiosk/Components/KioskFooter3.jsx @@ -7,6 +7,7 @@ import TakeAway from '../KioskIcons/KioskTakeAway'; import { IoIosArrowForward } from 'react-icons/io'; import { MdCurrencyRupee } from 'react-icons/md'; import { + changeKioskCustomerMobileNo, changeKioskPageName, getKioskDarkColour, globalCurrentKioskPageName, @@ -81,6 +82,7 @@ const KioskFooter3 = (props) => { const Oncancel = () => { dispatch(changeKioskPageName('initialPage')); dispatch(changeAllGlbStatustData()); + dispatch(changeKioskCustomerMobileNo(null)); // clear all global val }; @@ -101,6 +103,7 @@ const KioskFooter3 = (props) => { }; const handlePaymentCancel = () => { setPaymentModalOpen(false); + dispatch(changeKioskCustomerMobileNo(null)); }; return (
diff --git a/src/Pages/Kiosk/Components/KioskHeader.jsx b/src/Pages/Kiosk/Components/KioskHeader.jsx index 3b9f338..7de9087 100644 --- a/src/Pages/Kiosk/Components/KioskHeader.jsx +++ b/src/Pages/Kiosk/Components/KioskHeader.jsx @@ -2,6 +2,7 @@ import { Badge, Drawer, Popconfirm } from 'antd'; import '../../../Styles/Kiosk/Components/KioskHeader.scss'; import { IoIosArrowBack } from 'react-icons/io'; import { + changeKioskCustomerMobileNo, changeKioskPageName, getKioskCompLogo, getKioskLightColour, @@ -16,10 +17,12 @@ import { changeAllGlbStatustData, getProductCategories, } from '../../../Features/BookingScreen/BookingData/KioskBookingData'; -import { useState } from 'react'; +import { useEffect, useState } from 'react'; import KisokOrderCart2 from '../OrderCart/OrderCart2'; import KisokOrderCart1 from '../OrderCart/OrderCart1'; import KisokOrderCart3 from '../OrderCart/OrderCart3'; +import { MdFullscreen, MdFullscreenExit } from "react-icons/md"; + const KioskHeader = (props) => { const dispatch = useDispatch(); @@ -37,7 +40,36 @@ const KioskHeader = (props) => { }, 0); const cartTheme = props?.KioskThemeData?.KioskOrderCart?.[0]; const [open, setOpen] = useState(false); + const [isFullscreen, setIsFullscreen] = useState(false); console.log(cartTheme, "propsprops") + + const toggleFullscreen = () => { + if (!document.fullscreenElement) { + document.documentElement.requestFullscreen(); + setIsFullscreen(true); + } else { + document.exitFullscreen(); + setIsFullscreen(false); + } + }; + + useEffect(() => { + // Function to check fullscreen state + const checkFullscreen = () => { + setIsFullscreen(!!document.fullscreenElement); + }; + + // Check on initial render + checkFullscreen(); + + // Listen for changes (enter / exit fullscreen) + document.addEventListener('fullscreenchange', checkFullscreen); + + return () => { + document.removeEventListener('fullscreenchange', checkFullscreen); + }; + }, []); + const BackToCategory = async () => { await dispatch( getProductCategories({ @@ -51,6 +83,7 @@ const KioskHeader = (props) => { const BackToCardBasedonPreCatWithClear = async () => { await dispatch(changeAllGlbStatustData()); await dispatch(changeKioskPageName('initialPage')); + dispatch(changeKioskCustomerMobileNo(null)); }; const BackToCardBasedonPreCat = async () => { if ( @@ -84,30 +117,37 @@ const KioskHeader = (props) => { >

ORDER TOTAL

- {KioskOrderDetails?.length > 0 && ( -
- - setOpen(true)} /> - -
- {' '} - {TotalNetAmount?.toFixed(2)} +
+ {isFullscreen ? ( + + ) : ( + + )} + {KioskOrderDetails?.length > 0 && ( +
+ + setOpen(true)} /> + +
+ {' '} + {TotalNetAmount?.toFixed(2)} +
-
- )} + )} +
{CurrentPageName === 'categoryPage' && - KioskOrderDetails?.length > 0 ? ( + KioskOrderDetails?.length > 0 ? ( { + const actionContainerRef = useRef(null); const dispatch = useDispatch(); const getKioskBranchNamedata = useSelector(getKioskBranchName); const getKioskCompLogodata = useSelector(getKioskCompLogo); @@ -23,6 +26,38 @@ const InitialPage1 = (props) => { await dispatch(changeBookingType(eventName)); }; + useEffect(() => { + const toggleFullScreen = () => { + if (!document.fullscreenElement) { + document.documentElement.requestFullscreen?.().catch((err) => { + console.log('Fullscreen blocked:', err); + }); + } else { + document.exitFullscreen?.(); + } + }; + + const handleDoubleClick = (e) => { + // Ignore if double click is inside Dine/TakeAway section + if ( + actionContainerRef.current && + actionContainerRef.current.contains(e.target) + ) { + return; + } + + toggleFullScreen(); + }; + + window.addEventListener('dblclick', handleDoubleClick); + + return () => { + window.removeEventListener('dblclick', handleDoubleClick); + }; + }, []); + + console.log(isMobile, "isMobile"); + return ( <>
@@ -60,7 +95,7 @@ const InitialPage1 = (props) => { /> */}

-
+
{(SalesType === 'D' || SalesType === 'B') && (
{ diff --git a/src/Pages/Kiosk/Payment/KioskPaymentWithModal.jsx b/src/Pages/Kiosk/Payment/KioskPaymentWithModal.jsx index c516ec5..d049f3a 100644 --- a/src/Pages/Kiosk/Payment/KioskPaymentWithModal.jsx +++ b/src/Pages/Kiosk/Payment/KioskPaymentWithModal.jsx @@ -81,10 +81,13 @@ import { ApplicationPreferences } from '../../../Features/BrachLogin/BranchLogin import { VerifiedPaymentDtl } from '../../../Features/BookingScreen/Customer/addCustomer.js'; import PaymentGatewayEmbedded from '../../BookingScreen/Components/UtillComponents/PaymentGatewayEmbedded.jsx'; import MobileMultiPdfPrintTrigger from '../../BookingScreen/Components/UtillComponents/MobileMultiPdfPrintTrigger.jsx'; +import { checkLastOrderTimeLimit, sendupiotp } from '../../../Features/UpiDetails/UpiDetails.js'; +import { isIndianMobile } from '../../../utils/calculations.js'; const CustomPaymentUrl = import.meta.env.ENV_CUSTOM_PAYMENT_URL; const KioskPayment = (props) => { + const paymentGatewayRef = React.useRef(null); const dispatch = useDispatch(); const SessionData = props?.sessionData; const DeviceMacAddress = getSession('DeviceAddress'); @@ -92,6 +95,7 @@ const KioskPayment = (props) => { const [open, setOpen] = useState(props.modalOpen); const [width, setWidth] = useState(window.innerWidth); + const [showCancelConfirm, setShowCancelConfirm] = useState(false); const appPreferences = useSelector(ApplicationPreferences); const CustomerMobileNumber = useSelector(globalKioskCustomerMobileNo); const OrderId = useSelector(GlobalOrderId); @@ -147,9 +151,28 @@ const KioskPayment = (props) => { setting?.SettingIdName?.toLowerCase() === 'mobilea4' && setting?.SettingValue === 'Y' ); + 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' + ); + const bookingTypePreference = appPreferences?.find( (preference) => preference?.PreferredCatName === 'Booking Type' )?.PreferenceCatDetails; + const [showPaymentMethods, setShowPaymentMethods] = useState(null); + const [resendTimer, setResendTimer] = useState(0) + 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 [paymentUrl, setpaymentUrl] = useState(null); const [businessUPI, setBusinessUPI] = useState(false); console.log(PrintOrderDetails, 'PrintOrderDetails'); @@ -161,16 +184,20 @@ const KioskPayment = (props) => { useEffect(() => { TotalCalculation(); }, [KioskOrderDetails]); - // useEffect(() => { - // let data = { - // CompId: SessionData.CompId, - // BranchId: SessionData.BranchId, - // AppId: SessionData.AppId, - // DeviceMacAddress: DeviceMacAddress, - // }; - // dispatch(getKioskPrinterDetails(data)).unwrap(); - // dispatch(getPreferenceData({ CompId: SessionData.CompId, BranchId: SessionData.BranchId, AppId: SessionData.AppId })).unwrap(); - // }, []); + useEffect(() => { + if (SessionData.CompId && SessionData.BranchId && SessionData.AppId) { + if (DeviceMacAddress) { + let data = { + CompId: SessionData.CompId, + BranchId: SessionData.BranchId, + AppId: SessionData.AppId, + DeviceMacAddress: DeviceMacAddress, + }; + dispatch(getKioskPrinterDetails(data)).unwrap(); + } + dispatch(getPreferenceData({ CompId: SessionData.CompId, BranchId: SessionData.BranchId, AppId: SessionData.AppId })).unwrap(); + } + }, [SessionData.CompId, SessionData.BranchId, SessionData.AppId]); useEffect(() => { const getPrintData = async () => { @@ -325,7 +352,7 @@ const KioskPayment = (props) => { }, [width]); useEffect(() => { - number?.length === 10 && dispatch(changeKioskCustomerMobileNo(number)); + isIndianMobile(number) && dispatch(changeKioskCustomerMobileNo(number)); }, [number]); const onChange = (e) => { @@ -348,14 +375,13 @@ const KioskPayment = (props) => { const items = [ { key: '1', - label: `${ - paymentGatewayMethods?.[selectedOption]?.CardType == 'CRDC' || + label: `${paymentGatewayMethods?.[selectedOption]?.CardType == 'CRDC' || paymentGatewayMethods?.[selectedOption]?.CardType == 'DBCRD' - ? 'Choose Your Card' - : paymentGatewayMethods?.[selectedOption]?.CardType == 'WLT' - ? 'Choose Your Wallet' - : 'Choose Your Bank' - } `, + ? 'Choose Your Card' + : paymentGatewayMethods?.[selectedOption]?.CardType == 'WLT' + ? 'Choose Your Wallet' + : 'Choose Your Bank' + } `, children: ( { }); }; + 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)); }; @@ -709,7 +762,27 @@ const KioskPayment = (props) => { return null; } + const checkLast30MinOrder = async (MobileNo) => { + const response = await dispatch(checkLastOrderTimeLimit({ + MobileNo, + AppId: SessionData.AppId, + CompId: SessionData.CompId, + BranchId: SessionData.BranchId, + }))?.unwrap(); + return response?.data; + }; + const handlePaymentOption = async (option) => { + + if (isTimeLimitEnabled) { + const withinTimeLimit = await checkLast30MinOrder(number); + if (withinTimeLimit?.IsEligible === false) { + setMessageData(withinTimeLimit?.response); + setMessageType('warning'); + return; + } + } + setSelectedPaymentOption(option); dispatch(changeSelectedKioskPaymentOption(option)); @@ -865,9 +938,9 @@ const KioskPayment = (props) => { changeOrderId( response?.data?.OrderDetails?.[0]?.SalesId ? extractLastNumberOrderId( - response?.data?.OrderDetails?.[0]?.SalesId, - response?.data?.OrderDetails?.[0]?.FYStatus - ) + response?.data?.OrderDetails?.[0]?.SalesId, + response?.data?.OrderDetails?.[0]?.FYStatus + ) : null ) ); @@ -975,9 +1048,9 @@ const KioskPayment = (props) => { changeOrderId( response?.data?.OrderDetails?.[0]?.SalesId ? extractLastNumberOrderId( - response?.data?.OrderDetails?.[0]?.SalesId, - response?.data?.OrderDetails?.[0]?.FYStatus - ) + response?.data?.OrderDetails?.[0]?.SalesId, + response?.data?.OrderDetails?.[0]?.FYStatus + ) : null ) ); @@ -1157,11 +1230,11 @@ const KioskPayment = (props) => { changeOrderId( putPaymentDeviceResponse?.data?.OrderDetails?.[0]?.SalesId ? extractLastNumberOrderId( - putPaymentDeviceResponse?.data?.OrderDetails?.[0] - ?.SalesId, - putPaymentDeviceResponse?.data?.OrderDetails?.[0] - ?.FYStatus - ) + putPaymentDeviceResponse?.data?.OrderDetails?.[0] + ?.SalesId, + putPaymentDeviceResponse?.data?.OrderDetails?.[0] + ?.FYStatus + ) : null ) ); @@ -1555,7 +1628,7 @@ const KioskPayment = (props) => { const selectedStyle = stylesMap[ - printerTemplateStyle == undefined ? 'Style 13' : printerTemplateStyle + printerTemplateStyle == undefined ? 'Style 13' : printerTemplateStyle ]; if (selectedStyle) { await Promise.all( @@ -1761,6 +1834,80 @@ const KioskPayment = (props) => { clearAllStates(); }; + 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'); + 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 startResendTimer = () => { + setCanResend(false); + setResendTimer(30); + const timer = setInterval(() => { + setResendTimer((prev) => { + if (prev <= 1) { + clearInterval(timer); + setCanResend(true); + return 0; + } + return prev - 1; + }); + }, 1000); + } + + const handleOtpChange = (e, index) => { + const value = e.target.value.replace(/\D/g, ''); + + const newOtp = [...otpInput]; + newOtp[index] = value; + setOtpInput(newOtp); + }; + + const verifyOtp = () => { + const enteredOtp = otpInput.join(''); + + if (enteredOtp === otpNumber?.toString()) { + setMessageType('success'); + setMessageData('OTP Verified Successfully'); + setOtpSent(false); + setOtpInput(['', '', '', '']); + setShowPaymentMethods(true); + setOtpVerified(true); + } else { + setMessageType('error'); + setMessageData('Invalid OTP'); + } + }; + return (
{ placeholder={ paymentGatewayMethods?.[selectedOption]?.CardType == 'CRDC' || - paymentGatewayMethods?.[selectedOption]?.CardType == + paymentGatewayMethods?.[selectedOption]?.CardType == 'DBCRD' ? 'Search Your Card' : paymentGatewayMethods?.[selectedOption]?.CardType == - 'WLT' + 'WLT' ? 'Search Your Wallet' : 'Search Your Bank' } @@ -1889,73 +2036,170 @@ const KioskPayment = (props) => {
) : (
-

PAYMENT

+

{isOtpEnabled && !showPaymentMethods + ? "Verify Mobile Number" + : "PAYMENT"}

-
-

- Get your order bill on your mobile
- via SMS / Whatsapp -

-
+ {!otpSent && !otpVerifed && (<> +
+

+ Get your order bill on your mobile
+ via SMS / Whatsapp +

+
-
- -
- - {/* input boxxes */} -
-
-

setNumberFun(1)}>1

-

setNumberFun(2)}>2

-

setNumberFun(3)}>3

-
-
-

setNumberFun(4)}>4

-

setNumberFun(5)}>5

-

setNumberFun(6)}>6

-
-
-

setNumberFun(7)}>7

-

setNumberFun(8)}>8

-

setNumberFun(9)}>9

-
-
-

- -

-

setNumberFun(0)}>0

-

+ + {number?.length === 10 && !isIndianMobile(number) &&
Please Enter Valid Mobile Number
} +
+ + + {/* input boxxes */} +
+
+
+

setNumberFun(1)}>1

+

setNumberFun(2)}>2

+

setNumberFun(3)}>3

+
+
+

setNumberFun(4)}>4

+

setNumberFun(5)}>5

+

setNumberFun(6)}>6

+
+
+

setNumberFun(7)}>7

+

setNumberFun(8)}>8

+

setNumberFun(9)}>9

+
+
+

+ +

+

setNumberFun(0)}>0

+

+
-
-

Select Payment Method

- {console.log('selectedOption', selectedPaymentOption)} -
- {/* {upiAvailability && ( + {isOtpEnabled && ( + <> + + + )} + )} + {(isOtpEnabled && otpSent) && ( +
+ + {/* Mobile Number + Edit */} +
+ {number} + +
+ + {/* 4 Digit OTP Input */} +
+ {otpInput.map((digit, index) => ( + setOtpIndex(index)} + readOnly + /> + ))} +
+
+
+
+

handleOtpNumber(1)}>1

+

handleOtpNumber(2)}>2

+

handleOtpNumber(3)}>3

+
+
+

handleOtpNumber(4)}>4

+

handleOtpNumber(5)}>5

+

handleOtpNumber(6)}>6

+
+
+

handleOtpNumber(7)}>7

+

handleOtpNumber(8)}>8

+

handleOtpNumber(9)}>9

+
+
+

+ +

+

handleOtpNumber(0)}>0

+

+
+
+
+ + {/* Buttons */} +
+ + + +
+ +
+ )} + {(!isOtpEnabled || (showPaymentMethods && otpVerifed)) && <> +

Select Payment Method

+ {console.log('selectedOption', selectedPaymentOption)} +
+ {/* {upiAvailability && (
handlePaymentOption('UPI')} @@ -1964,7 +2208,7 @@ const KioskPayment = (props) => {

UPI

)} */} - {/* {cardAvailability && ( + {/* {cardAvailability && (
handlePaymentOption('Card')} @@ -1973,32 +2217,33 @@ const KioskPayment = (props) => {

CARD

)} */} - {counterAvailability && ( -
handlePaymentOption('Counter')} - > - -

- PAY AT THE COUNTER -

-
- )} - {paymentOptionDetailsBusinessUpi && ( -
handlePaymentOption('BU')} - > - -

UPI

-
- )} - {!paymentOptionDetailsBusinessUpi && !counterAvailability && ( -
- Please Set Payment Options Contact Admin -
- )} -
+ {counterAvailability && ( +
handlePaymentOption('Counter')} + > + +

+ PAY AT THE COUNTER +

+
+ )} + {paymentOptionDetailsBusinessUpi && ( +
handlePaymentOption('BU')} + > + +

UPI

+
+ )} + {!paymentOptionDetailsBusinessUpi && !counterAvailability && ( +
+ Please Set Payment Options Contact Admin +
+ )} +
+ }
) @@ -2076,10 +2321,28 @@ const KioskPayment = (props) => { paymentSucess={paymentSucess} ClearAllGlobalStateDatas={ClearAllGlobalStateDatas} // CustomerDisplay={CustomerDisplay} + ref={paymentGatewayRef} /> } /> + {showCancelConfirm && ( + { + paymentGatewayRef.current?.clearPolling(); + setBusinessUPI(false); + setShowCancelConfirm(false); + ClearAllGlobalStateDatas(); + }} + onCancel={() => setShowCancelConfirm(false)} + okText="Yes" + cancelText="No" + > + Do you want to cancel the payment? + + )}
); }; diff --git a/src/Pages/Kiosk/Payment/KioskPaymentWithModal.scss b/src/Pages/Kiosk/Payment/KioskPaymentWithModal.scss index 767d7b3..0e9d260 100644 --- a/src/Pages/Kiosk/Payment/KioskPaymentWithModal.scss +++ b/src/Pages/Kiosk/Payment/KioskPaymentWithModal.scss @@ -27,6 +27,14 @@ display: flex; justify-content: center; padding: 1rem 1rem; + flex-direction: column; + + .input-err{ + color: red; + font-size: 13px; + margin-top: 4px; + font-family: 'Poppins', sans-serif; + } input { width: 50vw; @@ -309,7 +317,7 @@ } .paymentCardMain .ant-radio-group, -.ant-radio-wrapper span.ant-radio + * { +.ant-radio-wrapper span.ant-radio+* { padding: 10px 10px; } @@ -317,10 +325,7 @@ padding: 54px 35px !important; } -.paymentCardMain - .ant-collapse - .ant-collapse-item:last-child - > .ant-collapse-content { +.paymentCardMain .ant-collapse .ant-collapse-item:last-child>.ant-collapse-content { overflow: scroll; height: 26vh; } @@ -337,6 +342,7 @@ } @media (max-width: 768px) { + .paymentModal_main .KioskPayment-inputModal input, .paymentModal_main .Kiosk-dailpadModal { width: 65vw; @@ -436,3 +442,122 @@ height: 80vh; } } + +.KioskOPTBTn { + width: 70%; + padding: 12px 16px; + font-size: 20px; + font-family: "Poppins"; + font-weight: 400; + border: none; + outline: none; + background-color: #000000; + color: #fff; + border-radius: 10px; + cursor: pointer; + +} + +.otp-section { + margin-top: 20px; + text-align: center; + + .otp-mobile-row { + display: flex; + justify-content: center; + align-items: center; + gap: 15px; + margin-bottom: 20px; + + .otp-mobile-number { + font-size: 20px; + font-weight: 600; + letter-spacing: 1px; + } + + .otp-edit-btn { + background: none; + border: none; + color: #007bff; + font-size: 16px; + cursor: pointer; + + &:hover { + text-decoration: underline; + } + } + } + + .otp-input-container { + display: flex; + justify-content: center; + gap: 20px; + margin-bottom: 25px; + + .otp-box { + width: 65px; + height: 65px; + font-size: 28px; + text-align: center; + border: 2px solid #ccc; + border-radius: 8px; + outline: none; + transition: 0.2s ease; + + &:focus { + border-color: #28a745; + box-shadow: 0 0 6px rgba(40, 167, 69, 0.4); + } + } + + .otp-box.active { + border: 2px solid #28a745; + } + } + + .otp-buttons { + display: flex; + justify-content: center; + gap: 20px; + + + button { + min-width: 140px; + padding: 12px 18px; + font-size: 16px; + font-weight: 500; + border-radius: 8px; + cursor: pointer; + transition: 0.2s ease; + font-family: 'Poppins', sans-serif !important; + display: flex; + align-items: center; + justify-content: center; + + &:disabled { + opacity: 0.5; + cursor: not-allowed; + } + } + + .verify-btn { + background-color: #28a745; + border: none; + color: #fff; + + &:hover:not(:disabled) { + background-color: #218838; + } + } + + .resend-btn { + background-color: #ffc107; + border: none; + color: #000; + + &:hover:not(:disabled) { + background-color: #e0a800; + } + } + } +} \ No newline at end of file diff --git a/src/Pages/Preference/PreferenceList.jsx b/src/Pages/Preference/PreferenceList.jsx index 4cbbe51..00b2137 100644 --- a/src/Pages/Preference/PreferenceList.jsx +++ b/src/Pages/Preference/PreferenceList.jsx @@ -22,7 +22,7 @@ import { ApplicationPreferences } from '../../Features/BrachLogin/BranchLogin.js import './PreferenceList.scss'; const PreferenceList = () => { - const { SadminuserAccess } = useAuth(); + const { SadminuserAccess, featureaddDetails } = useAuth(); const dispatch = useDispatch(); const formRef = useRef(); @@ -57,16 +57,17 @@ const PreferenceList = () => { const settingsList = tableValue[0]?.SettingDtlDetails ?? preferenceConfigs; const allSettingsMap = {}; - settingsList?.forEach(({ SettingIdName, SettingValue, SettingCount }) => { - allSettingsMap[SettingIdName?.toLowerCase()] = { value: SettingValue, count: SettingCount }; + settingsList?.forEach(({ SettingIdName, SettingValue, SettingCount, SettingTime }) => { + allSettingsMap[SettingIdName?.toLowerCase()] = { value: SettingValue, count: SettingCount, time: SettingTime?.split(' ')?.[0] }; }); - console.log(settingsList, 'settingsList'); + console.log(featureaddDetails, 'featureaddDetails'); const buildInitialValues = () => ({ dashboard: allSettingsMap['dashboard']?.value === 'Y', shortcutkeys: allSettingsMap['shortcutkeys']?.value === 'Y', autoreceivestock: allSettingsMap['autoreceivestock']?.value === 'Y', + kioskotp: allSettingsMap['kioskotp']?.value === 'Y', decimal: allSettingsMap['decimal']?.value === 'Y', enabledModules: [ ...(allSettingsMap['dinein']?.value === 'Y' ? ['dinein'] : []), @@ -86,7 +87,17 @@ const PreferenceList = () => { preorderpricechange: allSettingsMap['preorderpricechange']?.value === 'Y', quantityrestriction: allSettingsMap['overalllimit']?.value === 'Y' || allSettingsMap['itemwiselimit']?.value === 'Y', quantityrestrictiontype: allSettingsMap['overalllimit']?.value === 'Y' ? 'overall' : allSettingsMap['itemwiselimit']?.value === 'Y' ? 'itemwise' : 'overall', + kiosktimelimit: allSettingsMap['hours']?.value === 'Y' || allSettingsMap['minutes']?.value === 'Y', + kiosktimelimittype: allSettingsMap['hours']?.value === 'Y' ? 'hours' : allSettingsMap['minutes']?.value === 'Y' ? 'minutes' : 'minutes', maxquantity: allSettingsMap['overalllimit']?.value === 'Y' ? allSettingsMap['overalllimit']?.count || 1 : allSettingsMap['itemwiselimit']?.value === 'Y' ? allSettingsMap['itemwiselimit']?.count || 1 : 1, + maxtime: + allSettingsMap['hours']?.value === 'Y' + ? (allSettingsMap['hours']?.time + ? parseFloat(allSettingsMap['hours']?.time / 60) + : 0.5) + : allSettingsMap['minutes']?.value === 'Y' + ? parseFloat(allSettingsMap['minutes']?.time || 30) + : 30, billOption: ['whatsapp', 'sms', 'email'].some( (k) => allSettingsMap[k]?.value === 'Y' ) @@ -158,6 +169,7 @@ const PreferenceList = () => { if (settingsList) { const built = buildInitialValues(); setInitialValues(built); + console.log(built, 'built'); formRef.current?.setFieldsValue(built); } }, [settingsList]); @@ -295,6 +307,7 @@ const PreferenceList = () => { dashboard: values.dashboard, shortcutkeys: values.shortcutkeys, autoreceivestock: values.autoreceivestock, + kioskotp: values.kioskotp, decimal: values.decimal, searchfocus: values.searchfocus, addproductcard: values.addproductcard, @@ -317,6 +330,8 @@ const PreferenceList = () => { editbill: values.editbill, overalllimit: values.quantityrestriction && values.quantityrestrictiontype === 'overall', itemwiselimit: values.quantityrestriction && values.quantityrestrictiontype === 'itemwise', + hours: values.kiosktimelimit && values.kiosktimelimittype === 'hours', + minutes: values.kiosktimelimit && values.kiosktimelimittype === 'minutes', }; const arrayValues = { @@ -349,7 +364,13 @@ const PreferenceList = () => { SettingId: setting.SettingId, Comments: setting.Comments || 'Enter Comment', SettingValue: isChecked ? 'Y' : 'N', - SettingCount: ((key === 'overalllimit' || key === 'itemwiselimit') && isChecked) ? parseFloat(values.maxquantity) || null : null + SettingCount: ((key === 'overalllimit' || key === 'itemwiselimit') && isChecked) ? parseFloat(values.maxquantity) || null : null, + SettingTime: + ((key === "hours" && isChecked) + ? ((parseFloat(values.maxtime) * 60)?.toFixed(2) + ' ' + 'Minutes' || null) + : (key === "minutes" && isChecked) + ? (parseFloat(values.maxtime)?.toFixed(2) + ' ' + 'Minutes' || null) + : null), }; }); @@ -459,6 +480,7 @@ const PreferenceList = () => {
{ )} + {featureaddDetails?.find( + (item) => item?.FeatureAddonName?.toLowerCase() === 'kiosk sales' + ) && renderCheckbox('kioskotp', 'Enable OTP verification for Kiosk Orders?')} + {featureaddDetails?.find( + (item) => item?.FeatureAddonName?.toLowerCase() === 'kiosk sales' + ) && (allSettingsMap['hours'] !== undefined || allSettingsMap['minutes'] !== undefined) && <> + + Yes + + prev.kiosktimelimit !== curr.kiosktimelimit}> + {({ getFieldValue }) => getFieldValue('kiosktimelimit') && ( + <> + + formRef.current?.setFieldsValue({ maxtime: undefined })}> + Minutes + Hours + + + + + prev.kiosktimelimittype !== curr.kiosktimelimittype + } + > + {({ getFieldValue }) => { + const type = getFieldValue('kiosktimelimittype'); + + const isHours = type === 'hours'; + + return ( + + + + ); + }} + + + )} + + }
diff --git a/src/Pages/StockTransfer/CreateTransfer.jsx b/src/Pages/StockTransfer/CreateTransfer.jsx index d7f9a56..8de5898 100644 --- a/src/Pages/StockTransfer/CreateTransfer.jsx +++ b/src/Pages/StockTransfer/CreateTransfer.jsx @@ -191,7 +191,7 @@ const CreateTransfer = () => { formProductRef?.current?.resetFields(); if (!scanner) { - setProductSearchText(''); + setProductSearchText(''); } return success; @@ -377,7 +377,7 @@ const CreateTransfer = () => { setVariantDetails([]); setSelectedProductForVariant(null); setSelectedVariants([]); - + if (scanner) { setTimeout(() => { productInputRef.current?.focus(); @@ -437,6 +437,7 @@ const CreateTransfer = () => { InwardDtlId: item.InwardDtlId, ProdVariantName:item.ProdVariantName, RequestedQty: Number(item.ReceivedQty), + ProdVariantName: item.ProdVariantName, })), CreatedBy: UserId, }; @@ -528,12 +529,12 @@ const CreateTransfer = () => { />
) : ( - - - + + + )}
@@ -644,7 +645,7 @@ const CreateTransfer = () => { setVariantDetails([]); setSelectedProductForVariant(null); setSelectedVariants([]); - + if (scanner) { setTimeout(() => { productInputRef.current?.focus(); diff --git a/src/Styles/Kiosk/Components/KioskHeader.scss b/src/Styles/Kiosk/Components/KioskHeader.scss index 4e251d2..e150d78 100644 --- a/src/Styles/Kiosk/Components/KioskHeader.scss +++ b/src/Styles/Kiosk/Components/KioskHeader.scss @@ -67,3 +67,17 @@ font-weight: 600; flex-direction: row-reverse; } +.headerFullMin{ + display: flex; + align-items: center; + gap: 10px; +} +.FullMinIcon{ + background-color: #fff; + height: 40px; + width: 40px; + padding: 5px; + border-radius: 4px; + transition: all 0.3s ease-in-out; + cursor: pointer; +} \ No newline at end of file diff --git a/src/utils/calculations.js b/src/utils/calculations.js index e3c5108..6e40a41 100644 --- a/src/utils/calculations.js +++ b/src/utils/calculations.js @@ -7,4 +7,6 @@ export const calculateOverAllQtyLimit = (orders) => { export const capitalizeFirstLetter = (text) => { if (!text) return ''; return text.charAt(0).toUpperCase() + text.slice(1); -}; \ No newline at end of file +}; + +export const isIndianMobile = (mobile) => /^\d{10}$/.test(mobile) && /^[6-9]/.test(mobile); \ No newline at end of file