1510 lines
50 KiB
JavaScript
1510 lines
50 KiB
JavaScript
import React, { useCallback, useEffect, useState } from 'react';
|
|
import { Popconfirm, Drawer, Badge, Modal } from 'antd';
|
|
import { QuestionCircleOutlined } from '@ant-design/icons';
|
|
import { useDispatch, useSelector } from 'react-redux';
|
|
import { IoIosArrowForward } from 'react-icons/io';
|
|
import { MdCurrencyRupee } from 'react-icons/md';
|
|
import PozoDineInIcon from '../KioskIcons/KioskDineIn';
|
|
import TakeAway from '../KioskIcons/KioskTakeAway';
|
|
import {
|
|
changeisKioskCartOpen,
|
|
changeKioskPageName,
|
|
getKioskDarkColour,
|
|
globalCurrentKioskPageName,
|
|
globalisKioskCartOpen,
|
|
} from '../../../Features/Kiosk/kiosk';
|
|
import {
|
|
GlobalBookingTypeKiosk,
|
|
GlobalKioskOrderDetails,
|
|
GlobalOrderbtnClicked,
|
|
changeAllGlbStatustData,
|
|
GlobalPaymentgatewayRedirect,
|
|
changeBookingType,
|
|
GlobalOrderId,
|
|
GlobalSalesId,
|
|
changeOrderId,
|
|
changeSalesId,
|
|
changeKioskOrderDetails,
|
|
GlobalMergeData,
|
|
changeMergeData,
|
|
getPaymentGatewayDetails,
|
|
getPaymentGatewayAccessData,
|
|
changeMembershipDetail,
|
|
GlobalOrderOfferDetails,
|
|
GlobalMembershipDetail,
|
|
getPaymentVerfication,
|
|
} from '../../../Features/BookingScreen/BookingData/KioskBookingData';
|
|
import Cookies from 'js-cookie';
|
|
import SelfKisokOrderCart1 from '../OrderCart/SelfBookingOrderCart1';
|
|
import OrderCart2 from '../OrderCart/OrderCart2';
|
|
import OrderCart3 from '../OrderCart/OrderCart3';
|
|
import '../../../Styles/Kiosk/Components/SelfBookingKioskFooter.scss';
|
|
import KioskPayment from '../Payment/KioskPaymentWithModal';
|
|
import { ApplicationPreferences } from '../../../Features/BrachLogin/BranchLogin';
|
|
import { FaAngleUp, FaCircleCheck } from 'react-icons/fa6';
|
|
import { FaAngleDown } from 'react-icons/fa';
|
|
import { PostBookingData, PostCancelPayment } from '../../../Features/BookingScreen/BookingData/BookingData';
|
|
import {
|
|
generateRandomKey,
|
|
getSession,
|
|
removeCookieData,
|
|
encryptedValuesFun,
|
|
encryptObject,
|
|
} from '../../../Services/Others';
|
|
import {
|
|
getSelfBooking,
|
|
getTableDtlsForSelfBooking,
|
|
postSelfBooking,
|
|
putSelfBooking,
|
|
} from '../../../Features/TableBooking/TableBooking';
|
|
import { Messages } from '../../../Components/Notifications/Messages';
|
|
import { useNavigate } from 'react-router-dom';
|
|
import Tick from '../../../Images/tick.gif';
|
|
import { DefaultModal } from '../../../Components/Modal/DefaultModal';
|
|
import { Input, message } from 'antd';
|
|
import { getItem } from '../../../Components/Menu/SideMenu';
|
|
import SelfBookingPayment from '../Payment/SelfBookingPaymementwithModal';
|
|
import OrderQR from './QrCodeSelfBooking';
|
|
import { getAddCustomerDetails } from '../../../Features/BookingScreen/Customer/addCustomer';
|
|
import { PublicQrCodepost } from '../../../Features/ConfigMasterPage/ConfigMasterPage';
|
|
import { AiOutlineShoppingCart } from 'react-icons/ai';
|
|
const subDirectory = import.meta.env.ENV_BASE_URL;
|
|
const CustomPaymentUrl = import.meta.env.ENV_CUSTOM_PAYMENT_URL;
|
|
const MainHomeUrl = import.meta.env.ENV_MAIN_BASE_URL;
|
|
const selfKioskFooter = (props) => {
|
|
const dispatch = useDispatch();
|
|
const navigate = useNavigate();
|
|
|
|
const MergeData = useSelector(GlobalMergeData);
|
|
const OrderofferDetails = useSelector(GlobalOrderOfferDetails);
|
|
const KioskOrderDetails = useSelector(GlobalKioskOrderDetails);
|
|
console.log(KioskOrderDetails, 'KioskOrderDetails ');
|
|
const KioskCurrentPage = useSelector(globalCurrentKioskPageName);
|
|
const GeneratedOrderId = useSelector(GlobalOrderId);
|
|
const GeneratedSalesId = useSelector(GlobalSalesId);
|
|
const getKioskDarkColourdata = useSelector(getKioskDarkColour);
|
|
const BookingType = useSelector(GlobalBookingTypeKiosk);
|
|
const [TotalTaxAmount, setTotalTaxAmount] = useState(null);
|
|
const [TotalBillAmount, setBillAmount] = useState(null);
|
|
const [TotalNetAmount, setTotalNetAmount] = useState(null);
|
|
let WaiterINformation = sessionStorage.getItem('WaiterId');
|
|
const clicked = useSelector(GlobalOrderbtnClicked);
|
|
const getmobilepage = useSelector(GlobalPaymentgatewayRedirect);
|
|
const appPreferences = useSelector(ApplicationPreferences);
|
|
const isKioskCartOpen = useSelector(globalisKioskCartOpen);
|
|
const [isPayViaOpen, setPayViaOpen] = useState(false);
|
|
const [messageType, setMessageType] = useState(null);
|
|
const [messageData, setMessageData] = useState(null);
|
|
const [open, setOpen] = useState(false);
|
|
const [placement, setPlacement] = useState('right');
|
|
const [showPaymentSuccess, setShowPaymentSuccess] = useState(false);
|
|
const [OrderMethod, setOrderMethod] = useState('inPerson');
|
|
const [showPaymentSuccessAfterPayment, setshowPaymentSuccessAfterPayment] =
|
|
useState(false);
|
|
const [showQrCode, setshowQrCode] = useState(false);
|
|
const [paymentOrderId, setPaymentOrderId] = useState(null);
|
|
const [isOrderMethodModalOpen, setIsOrderMethodModalOpen] = useState(false);
|
|
const [Paymentvia, setPaymentvia] = useState(null);
|
|
// Phone Number Modal State
|
|
const [isPhoneModalOpen, setIsPhoneModalOpen] = useState(false);
|
|
const [phoneNumber, setPhoneNumber] = useState('');
|
|
const [isPhoneLoading, setIsPhoneLoading] = useState(false);
|
|
const [pendingOrderType, setPendingOrderType] = useState(null);
|
|
const [qrTimer, setQrTimer] = useState(60);
|
|
const [qrTimerActive, setQrTimerActive] = useState(false);
|
|
const bookingTypePreference = appPreferences?.find(
|
|
(preference) => preference?.PreferredCatName === 'Booking Type'
|
|
)?.PreferenceCatDetails;
|
|
const dinePreference = bookingTypePreference?.find(
|
|
(type) =>
|
|
type?.PreferredSubCatName?.toLowerCase() === 'dine in' &&
|
|
type?.PreferredStatus === 'Y'
|
|
);
|
|
const CompId = getSession('CompId');
|
|
const AppId = getSession('AppId');
|
|
const BranchId = getSession('BranchId');
|
|
const kioskTemplateData = props?.data;
|
|
const sessionData = props?.SessionDtl;
|
|
let isSelfBookingOpen = sessionStorage.getItem('SelfBookingId');
|
|
const [chairInformation, setChairInformation] = useState();
|
|
const [TableINformation, setTableINformation] = useState();
|
|
const [paymentUrl, setpaymentUrl] = useState(null);
|
|
const [showCancelConfirm, setShowCancelConfirm] = useState(null);
|
|
const [TransctionId, setTransctionId] = useState(null);
|
|
const [paymentGatewayAccess, setPaymentGatewayAccess] = useState([]);
|
|
// let chairInformation = getSession('table');
|
|
// let TableINformation = sessionStorage.getItem('tableID');
|
|
const storedBookingMethod = getSession('bookingMethod');
|
|
const bookingTypeName = sessionStorage.getItem('bookingTypeName');
|
|
|
|
const [allchairData, setAllchairData] = useState([]);
|
|
console.log('chairInformation', TableINformation);
|
|
|
|
useEffect(() => {
|
|
// If no payment URL → do nothing
|
|
if (!paymentUrl) {
|
|
console.log('paymentUrl is null → No listener / No interval');
|
|
return;
|
|
}
|
|
|
|
console.log('paymentUrl exists → Setting Listener + Polling');
|
|
|
|
// -------------------------
|
|
// 1) MESSAGE LISTENER
|
|
// -------------------------
|
|
function handleMessage(event) {
|
|
const data = event.data;
|
|
|
|
if (!data || data.type !== 'PAYMENT_STATUS') return;
|
|
|
|
console.log('Received message from iframe:', data);
|
|
|
|
if (data.status === 'TIMEOUT') {
|
|
setTimeout(() => {
|
|
console.log('TIMEOUT → Clearing paymentUrl');
|
|
setpaymentUrl(null);
|
|
}, 4000);
|
|
}
|
|
}
|
|
|
|
window.addEventListener('message', handleMessage);
|
|
|
|
// -------------------------
|
|
// 2) POLLING INTERVAL
|
|
// -------------------------
|
|
const interval = setInterval(async () => {
|
|
try {
|
|
const response = await dispatch(
|
|
getPaymentVerfication(TransctionId)
|
|
).unwrap();
|
|
|
|
console.log('Payment verification:', response);
|
|
|
|
const status = response?.data?.response?.[0]?.STATUS;
|
|
|
|
if (response?.data?.statusCode === 1 && status === 'TXN_SUCCESS') {
|
|
console.log('Payment Success → Stopping interval + clearing URL');
|
|
|
|
clearInterval(interval);
|
|
setpaymentUrl(null);
|
|
clearsDatas(TransctionId, 'UPI');
|
|
}
|
|
} catch (error) {
|
|
console.error('Payment check error:', error);
|
|
}
|
|
}, 4000);
|
|
|
|
// -------------------------
|
|
// CLEANUP → remove listener + interval
|
|
// -------------------------
|
|
return () => {
|
|
console.log('Cleanup → Removing listener & clearing interval');
|
|
window.removeEventListener('message', handleMessage);
|
|
clearInterval(interval);
|
|
};
|
|
}, [paymentUrl]);
|
|
|
|
useEffect(() => {
|
|
setChairInformation(getSession('table'));
|
|
setTableINformation(sessionStorage.getItem('tableID'));
|
|
fetchPaymentAccess();
|
|
}, [sessionStorage]);
|
|
useEffect(() => {
|
|
TotalCalculation();
|
|
}, [KioskOrderDetails]);
|
|
const selfBookingId = sessionStorage.getItem('SelfBookingId');
|
|
useEffect(() => {
|
|
if (getmobilepage) {
|
|
MobileNumberPage();
|
|
}
|
|
}, [getmobilepage]);
|
|
|
|
useEffect(() => {
|
|
if (isKioskCartOpen) {
|
|
setOpen(true);
|
|
}
|
|
}, [isKioskCartOpen]);
|
|
useEffect(() => {
|
|
fetchTableData(TableINformation);
|
|
}, [TableINformation]);
|
|
|
|
useEffect(() => {
|
|
if (qrTimerActive && qrTimer > 0) {
|
|
const interval = setInterval(() => {
|
|
setQrTimer((prev) => prev - 1);
|
|
}, 1000);
|
|
return () => clearInterval(interval);
|
|
} else if (qrTimer === 0) {
|
|
setshowQrCode(false);
|
|
setQrTimerActive(false);
|
|
setQrTimer(60);
|
|
}
|
|
}, [qrTimerActive, qrTimer]);
|
|
|
|
async function processBookings(bookings, MembershipDetail, CustId) {
|
|
let MemberShipData = MembershipDetail?.[0];
|
|
let remainingHrs = MemberShipData?.RemainingSessionHrs;
|
|
const processedBookings = bookings?.map((booking) => {
|
|
const from = booking.AvailableFrom
|
|
? booking.AvailableFrom.split(':')
|
|
: [0, 0];
|
|
const to = booking.AvailableTo ? booking.AvailableTo.split(':') : [0, 0];
|
|
|
|
const slotHrs = +to[0] + +to[1] / 60 - (+from[0] + +from[1] / 60);
|
|
const totalSessionHrs = slotHrs * booking.Size;
|
|
|
|
let membershipApplied = false;
|
|
let cost = booking.MRP;
|
|
|
|
if (remainingHrs >= totalSessionHrs) {
|
|
membershipApplied = true;
|
|
cost = 0;
|
|
remainingHrs -= totalSessionHrs;
|
|
} else {
|
|
membershipApplied = false;
|
|
cost = booking.MRP * 0.95;
|
|
}
|
|
|
|
return {
|
|
OfferId: MemberShipData?.MembershipId,
|
|
OfferAmount: booking?.TotalAmt,
|
|
OfferValue: 0,
|
|
TableName: 'MemberShip',
|
|
TableUniqueName: 'MemberShip',
|
|
TableUniqueId: 'string',
|
|
ProdId: booking?.ProdId,
|
|
SinglePc: booking?.SinglePc,
|
|
StockAvailable: booking?.StockAvailable,
|
|
ProdVariantName: booking?.ProdVariantName,
|
|
ActualFreeQty: 0,
|
|
Type: 'string',
|
|
BookingType: booking?.BookingType,
|
|
InwardDtlId: booking?.InwardDtlId,
|
|
OfferType: 'M',
|
|
PlanId: MemberShipData?.PlanId,
|
|
Detail: [],
|
|
ProdCat: booking?.ProdCat,
|
|
OfferCode: 'string',
|
|
CustId: CustId,
|
|
UsedCount: slotHrs,
|
|
AppliesTo: 'string',
|
|
FreeProductsList: {},
|
|
};
|
|
});
|
|
|
|
return processedBookings;
|
|
// setOrderOfferDetails(processedBookings);
|
|
}
|
|
|
|
const fetchPaymentAccess = async () => {
|
|
const paymentGatewayAccessResponse = await dispatch(
|
|
getPaymentGatewayAccessData({
|
|
AppId: sessionData.AppId,
|
|
CompId: sessionData.CompId,
|
|
BranchId: sessionData.BranchId,
|
|
ActiveStatus: 'A',
|
|
})
|
|
).unwrap();
|
|
setPaymentGatewayAccess(paymentGatewayAccessResponse?.data?.data);
|
|
// fetchPaymentOptionsData(
|
|
// paymentGatewayAccessResponse?.data?.data,
|
|
// paymentGatewayAccessResponse?.data?.data
|
|
// );
|
|
};
|
|
const fetchTableData = async (TableId) => {
|
|
const res = await dispatch(
|
|
getTableDtlsForSelfBooking({
|
|
tableId: TableId,
|
|
AppId,
|
|
CompId,
|
|
BranchId,
|
|
})
|
|
).unwrap();
|
|
if (res?.data?.statusCode === 1) {
|
|
setAllchairData(
|
|
res.data.data?.[0]?.ChairLevelSerDetails?.map((item) => item.ChairId) ||
|
|
[]
|
|
);
|
|
}
|
|
};
|
|
|
|
const handleShareWhatsAppFn = async (OrderId) => {
|
|
try {
|
|
// Validate required data
|
|
if (!OrderId) {
|
|
console.error('OrderId is required');
|
|
setMessageType('error');
|
|
setMessageData('Order ID not found. Please try again.');
|
|
return;
|
|
}
|
|
|
|
let orderIdsArray = [OrderId];
|
|
|
|
// Validate encryptObject function exists
|
|
if (typeof encryptObject !== 'function') {
|
|
console.error('encryptObject function not available');
|
|
setMessageType('error');
|
|
setMessageData('Encryption service unavailable. Please try again.');
|
|
return;
|
|
}
|
|
|
|
const encrypted = encryptObject(orderIdsArray);
|
|
|
|
const postData = {
|
|
Url: encrypted,
|
|
CreatedBy: 0,
|
|
};
|
|
|
|
const res = await dispatch(PublicQrCodepost(postData)).unwrap();
|
|
|
|
if (res?.data?.statusCode === 1) {
|
|
const urlData = res?.data?.ReferenceNo;
|
|
if (urlData) {
|
|
const documentUrl = `${MainHomeUrl}viewbill?code=${urlData}`;
|
|
// window.location.href = documentUrl;
|
|
window.open(documentUrl, '_blank');
|
|
} else {
|
|
setMessageType('error');
|
|
setMessageData('Receipt URL not generated. Please try again.');
|
|
}
|
|
} else {
|
|
setMessageType('error');
|
|
setMessageData('Failed to generate receipt. Please try again.');
|
|
}
|
|
} catch (err) {
|
|
console.error('Error while calling PublicQrCodepost:', err);
|
|
setMessageType('error');
|
|
setMessageData(
|
|
'Failed to load receipt. Please check your connection and try again.'
|
|
);
|
|
}
|
|
};
|
|
const TotalCalculation = () => {
|
|
const totalwithouttax = KioskOrderDetails?.reduce((accumulator, card) => {
|
|
return (
|
|
accumulator +
|
|
parseFloat(card.WithoutTaxRate || card.TotalAmt - card.TaxAmt || 0)
|
|
);
|
|
}, 0);
|
|
setBillAmount(parseFloat(totalwithouttax)?.toFixed(2));
|
|
const totalPrice = KioskOrderDetails?.reduce((accumulator, card) => {
|
|
return accumulator + parseFloat(card.TotalAmt || 0);
|
|
}, 0);
|
|
setTotalNetAmount(parseFloat(totalPrice)?.toFixed(2));
|
|
const totalTaxAmt = KioskOrderDetails?.reduce((accumulator, card) => {
|
|
return accumulator + parseFloat(card.TaxAmt || 0);
|
|
}, 0);
|
|
|
|
setTotalTaxAmount(parseFloat(totalTaxAmt)?.toFixed(2));
|
|
};
|
|
|
|
const MobileNumberPage = async (type) => {
|
|
placeOrder(type);
|
|
};
|
|
|
|
const handleClick = (type) => {
|
|
if (KioskCurrentPage === 'OrderView') {
|
|
if (KioskOrderDetails?.length > 0) {
|
|
if (!GeneratedOrderId && !GeneratedSalesId) {
|
|
setPendingOrderType(type);
|
|
setIsPhoneModalOpen(true);
|
|
} else if (type != 'Pay') {
|
|
MobileNumberPage(type);
|
|
} else {
|
|
let defaultBehaviour = sessionStorage.getItem('notselectcus');
|
|
if (defaultBehaviour == 'true') {
|
|
setShowPaymentSuccess(true);
|
|
} else {
|
|
setIsOrderMethodModalOpen(true);
|
|
}
|
|
|
|
// defaultBehaviour ? setShowPaymentSuccess(true) : setIsOrderMethodModalOpen(true);
|
|
}
|
|
}
|
|
} else {
|
|
dispatch(changeKioskPageName('OrderView'));
|
|
}
|
|
};
|
|
// Drawer code
|
|
|
|
const showDrawer = () => {
|
|
setOpen(true);
|
|
// OrderApiCall();
|
|
};
|
|
|
|
// Phone Number Modal Functions
|
|
const handlePhoneModalCancel = () => {
|
|
setIsPhoneModalOpen(false);
|
|
setPhoneNumber('');
|
|
setPendingOrderType(null);
|
|
};
|
|
|
|
const handlePhoneModalSubmit = async () => {
|
|
if (!phoneNumber.trim()) {
|
|
message.error('Please enter your phone number');
|
|
return;
|
|
}
|
|
|
|
// Basic phone number validation
|
|
if (!/^\d{10}$/.test(phoneNumber.trim())) {
|
|
message.error('Please enter a valid 10-digit phone number');
|
|
return;
|
|
}
|
|
|
|
setIsPhoneLoading(true);
|
|
try {
|
|
sessionStorage.setItem('CustomerPhoneNumber', phoneNumber.trim());
|
|
|
|
// let CustomerDetails = await dispatch(getAddCustomerDetails({
|
|
// CompId: CompId,
|
|
// BranchId: BranchId,
|
|
// AppId: AppId,
|
|
// MobileNo: phoneNumber.trim(),
|
|
// })).unwrap();
|
|
setIsPhoneModalOpen(false);
|
|
setPhoneNumber('');
|
|
// setPendingOrderType(null);
|
|
// if (CustomerDetails?.data?.statusCode == 1 && CustomerDetails?.data?.data?.[0]?.MembershipDetail?.length > 0) {
|
|
|
|
// await dispatch(changeMembershipDetail(CustomerDetails?.data?.data?.[0]));
|
|
// let res = await processBookings(KioskOrderDetails, CustomerDetails?.data?.data?.[0]?.MembershipDetail, CustomerDetails?.data?.data?.[0]?.CustId)
|
|
|
|
// await placeOrder(pendingOrderType, null, 'PC', null, res);
|
|
|
|
// }
|
|
// else
|
|
if (pendingOrderType) {
|
|
await placeOrder(pendingOrderType);
|
|
}
|
|
} catch (error) {
|
|
console.error('Phone number save error:', error);
|
|
message.error('Failed to save phone number. Please try again.');
|
|
} finally {
|
|
setIsPhoneLoading(false);
|
|
}
|
|
};
|
|
|
|
// Function to handle card payment processing
|
|
const processCardPayment = async (cardDetails) => {
|
|
try {
|
|
// Get payment gateway details
|
|
const paymentGatewayDetails = await dispatch(
|
|
getPaymentGatewayDetails({
|
|
AppId: AppId,
|
|
CompId: CompId,
|
|
BranchId: BranchId,
|
|
DetailType: 'P',
|
|
})
|
|
).unwrap();
|
|
|
|
// Get mode ID for the selected card
|
|
const modeId = await getModeId(
|
|
cardDetails.paymentOptionsData,
|
|
cardDetails.bankDetails.CardType === 'CRDC'
|
|
? 'CreditCard'
|
|
: 'DebitCard',
|
|
'Payment Gateway'
|
|
);
|
|
|
|
return {
|
|
paymentGatewayDetails,
|
|
modeId,
|
|
bankDetails: cardDetails.bankDetails,
|
|
};
|
|
} catch (error) {
|
|
console.error('Error processing card payment:', error);
|
|
throw error;
|
|
}
|
|
};
|
|
|
|
// Function to handle UPI payment processing
|
|
const processUpiPayment = async (upiData) => {
|
|
try {
|
|
// Get payment gateway details
|
|
const paymentGatewayDetails = await dispatch(
|
|
getPaymentGatewayDetails({
|
|
AppId: AppId,
|
|
CompId: CompId,
|
|
BranchId: BranchId,
|
|
DetailType: 'P',
|
|
})
|
|
).unwrap();
|
|
|
|
// For UPI, the upiData is already the mode details array
|
|
// We need to find the UPI mode ID from the data
|
|
let modeId = null;
|
|
if (upiData && upiData.length > 0) {
|
|
// Find the UPI mode ID from the first UPI mode detail
|
|
const upiMode = upiData.find((mode) => mode.ModeName === 'UPI');
|
|
if (upiMode) {
|
|
modeId = upiMode.ModeId;
|
|
}
|
|
}
|
|
|
|
return {
|
|
paymentGatewayDetails,
|
|
modeId,
|
|
upiData: upiData,
|
|
};
|
|
} catch (error) {
|
|
console.error('Error processing UPI payment:', error);
|
|
throw error;
|
|
}
|
|
};
|
|
|
|
// Function to get mode ID (copied from payment component)
|
|
const getModeId = async (paymentDetails, option, optionName) => {
|
|
const paymentDeviceOption = paymentDetails.OptionDetails.find(
|
|
(option) => option.OptionName === optionName
|
|
);
|
|
if (!paymentDeviceOption) {
|
|
return null;
|
|
}
|
|
const selectedMode = paymentDeviceOption.ModeDetails.find(
|
|
(mode) => mode.ModeName === option
|
|
);
|
|
if (!selectedMode) {
|
|
return null;
|
|
}
|
|
return selectedMode.ModeId;
|
|
};
|
|
|
|
// Function to handle UPI payment gateway form submission
|
|
const handleUpiPaymentGateway = async (response, processedUpiData) => {
|
|
try {
|
|
let PaymentOrderDetails = response?.data?.PaymentOrderDtl?.filter(
|
|
(item) => item.PaymentOptionType == 'PG' && item.PaymentStatus == 'P'
|
|
);
|
|
let PaymentOrderIndividualDetails =
|
|
PaymentOrderDetails?.length == 1 ? PaymentOrderDetails?.[0] : [];
|
|
|
|
const form = document.createElement('form');
|
|
form.method = 'POST';
|
|
form.action = `${CustomPaymentUrl}/ccavRetailRequestHandler`;
|
|
form.style.display = 'none'; // Hide the form
|
|
|
|
const customerPhoneNumber = sessionStorage.getItem('CustomerPhoneNumber');
|
|
|
|
const data1 = {
|
|
merchant_id: paymentGatewayAccess?.[0]?.['MerchantId'],
|
|
order_id: PaymentOrderIndividualDetails?.PaymentOrderId,
|
|
currency: 'INR',
|
|
amount: TotalNetAmount,
|
|
redirect_url:
|
|
'https://pozo.app/CustomPaymentGateway/CustomPaymentGateway/ccavRetailResponseHandler',
|
|
cancel_url:
|
|
'https://pozo.app/CustomPaymentGateway/CustomPaymentGateway/ccavRetailResponseHandler',
|
|
payment_option: processedUpiData.upiData?.[0]?.PayOpt,
|
|
card_type: processedUpiData.upiData?.[0]?.CardType,
|
|
card_name: 'UPI',
|
|
data_accept:
|
|
processedUpiData.upiData?.[0]?.MethodDetails?.[0]?.DataAcceptedAt ==
|
|
'CCAvenue'
|
|
? 'Y'
|
|
: 'N',
|
|
language: 'EN',
|
|
billing_name: 'User',
|
|
billing_address: 'xyz',
|
|
billing_city: 'xyz',
|
|
billing_state: 'xyz',
|
|
billing_zip: '000000',
|
|
billing_country: 'India',
|
|
billing_tel: customerPhoneNumber,
|
|
billing_email: 'xyz@gmail.com',
|
|
delivery_name: '',
|
|
delivery_address: AppId,
|
|
delivery_city: 'K',
|
|
delivery_zip: BranchId,
|
|
delivery_country: processedUpiData.modeId,
|
|
delivery_tel: customerPhoneNumber,
|
|
merchant_param1: '',
|
|
merchant_param2: PaymentOrderIndividualDetails?.OrderId,
|
|
merchant_param3: 0,
|
|
merchant_param4: CompId,
|
|
merchant_param5: 'paymentRetailHandler.html',
|
|
promo_code: '',
|
|
customer_identifier: '',
|
|
workingKey: paymentGatewayAccess?.[0]?.['WorkingKey'], // Include the working key
|
|
accessCode: paymentGatewayAccess?.[0]?.['AccessCode'],
|
|
};
|
|
|
|
Object.keys(data1).forEach((key) => {
|
|
const input = document.createElement('input');
|
|
input.type = 'hidden';
|
|
input.name = key;
|
|
input.value = encryptedValuesFun(data1[key]);
|
|
form.appendChild(input);
|
|
});
|
|
|
|
document.body.appendChild(form);
|
|
form.submit();
|
|
|
|
// Close payment modal
|
|
setShowPaymentSuccess(false);
|
|
} catch (error) {
|
|
console.error('Error handling UPI payment gateway:', error);
|
|
setMessageType('error');
|
|
setMessageData('Error processing UPI payment. Please try again.');
|
|
}
|
|
};
|
|
|
|
const placeOrder = async (
|
|
type,
|
|
paymentMethod = null,
|
|
paymentOptionType = 'PC',
|
|
upiData = null,
|
|
OrderOfferDetail = []
|
|
) => {
|
|
let BusinessUpi =
|
|
OrderOfferDetail &&
|
|
typeof OrderOfferDetail === 'object' &&
|
|
!Array.isArray(OrderOfferDetail)
|
|
? OrderOfferDetail?.ModeDetails?.[0] || {}
|
|
: {};
|
|
console.log(OrderOfferDetail, 'OrderOfferDetail');
|
|
// Process card payment details if it's a card payment
|
|
let processedCardData = null;
|
|
if (paymentMethod === 'Card' && upiData && upiData.bankDetails) {
|
|
try {
|
|
processedCardData = await processCardPayment(upiData);
|
|
} catch (error) {
|
|
console.error('Error processing card payment:', error);
|
|
setMessageType('error');
|
|
setMessageData('Error processing card payment. Please try again.');
|
|
return;
|
|
}
|
|
}
|
|
|
|
// Process UPI payment details if it's a UPI payment
|
|
let processedUpiData = null;
|
|
if (paymentMethod === 'UPI' && upiData) {
|
|
try {
|
|
console.log('UPI Data received:', upiData);
|
|
processedUpiData = await processUpiPayment(upiData);
|
|
console.log('Processed UPI Data:', processedUpiData);
|
|
} catch (error) {
|
|
console.error('Error processing UPI payment:', error);
|
|
setMessageType('error');
|
|
setMessageData('Error processing UPI payment. Please try again.');
|
|
return;
|
|
}
|
|
}
|
|
|
|
const map = new Map();
|
|
|
|
KioskOrderDetails.forEach((item) => {
|
|
const key = `${item.InwardDtlId}-${item.ProdId}`;
|
|
if (map.has(key)) {
|
|
const existing = map.get(key);
|
|
existing.OrderQty += item.OrderQty;
|
|
existing.TotalAmt += item.TotalAmt;
|
|
} else {
|
|
map.set(key, { ...item });
|
|
}
|
|
});
|
|
|
|
// Get phone number from session storage
|
|
const customerPhoneNumber = sessionStorage.getItem('CustomerPhoneNumber');
|
|
const now = new Date();
|
|
const formattedDate = `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}-${String(now.getDate()).padStart(2, '0')}`;
|
|
|
|
let data = {
|
|
ActiveStatus: 'A',
|
|
AddlInfo: 'test',
|
|
AppId: AppId,
|
|
BalGiven: 0,
|
|
BillAmount: TotalBillAmount,
|
|
BookingMedia: 'DW',
|
|
BookingType: 129,
|
|
BranchId: BranchId,
|
|
CompId: CompId,
|
|
CustSuppId: null,
|
|
ExtraChargeDetails: null,
|
|
GivenAmt: 0,
|
|
NetAmount: TotalNetAmount,
|
|
OrderDate: formattedDate,
|
|
MobileNo: customerPhoneNumber || '',
|
|
OrderDtlDetails: Array.from(map.values())?.map((item) => ({
|
|
BookingType: item?.BookingType,
|
|
CounterName: item?.CounterName,
|
|
InwardDtlId: item?.InwardDtlId,
|
|
OfferAmt: item?.OfferAmt,
|
|
OfferType: item?.OfferType,
|
|
OfferValue: item?.OfferValue,
|
|
OrderQty: item?.OrderQty,
|
|
OrderRate: item?.OrderRate,
|
|
OrderStatus: item?.OrderStatus,
|
|
OrderType: 'S',
|
|
ProdId: item?.ProdId,
|
|
ProdNameQty: item?.ProdNameQty,
|
|
ProductIdentifierDtls: item?.ProductIdentifierDtls,
|
|
RefundQty: item?.RefundQty,
|
|
SinglePc: item?.SinglePc,
|
|
TaxAmt: item?.TaxAmt,
|
|
TaxId: item?.TaxId,
|
|
TotalAmt: item?.TotalAmt,
|
|
Type: item?.Type,
|
|
})),
|
|
OrderOfferDetail: OrderOfferDetail,
|
|
OrderType: 'S',
|
|
OtherServiceTicketAmount: null,
|
|
OtherServiceTicketId: null,
|
|
OverallDiscEst: 0,
|
|
OverallDiscSales: 0,
|
|
PaymentDetail:
|
|
type != 'Pay'
|
|
? []
|
|
: [
|
|
{
|
|
AccountDtl:
|
|
paymentMethod === 'UPI' && processedUpiData
|
|
? processedUpiData?.paymentGatewayDetails?.data?.data || []
|
|
: [],
|
|
Amount: TotalNetAmount,
|
|
Credit: 0,
|
|
Debit: 0,
|
|
PaymentOptionType: paymentOptionType,
|
|
PaymentStatus: 'P',
|
|
|
|
PaymentType:
|
|
paymentMethod === 'UPI' && processedUpiData
|
|
? processedUpiData?.modeId
|
|
: BusinessUpi?.ModeId
|
|
? BusinessUpi?.ModeId
|
|
: 0,
|
|
ModeOfPayment: null,
|
|
MerchantId: BusinessUpi?.MerchantId,
|
|
},
|
|
],
|
|
PaymentStatus: 'P',
|
|
PaymentType: processedUpiData?.modeId || BusinessUpi?.ModeId || 0,
|
|
Reference: 'test',
|
|
RefundAmount: 0,
|
|
SalesPaymentType: 'normal',
|
|
|
|
SalesTableLinkDetails:
|
|
storedBookingMethod === 'individualChair'
|
|
? chairInformation?.map((chairId) => ({
|
|
ChairId: chairId,
|
|
TableId: TableINformation,
|
|
WaiterId:
|
|
WaiterINformation != undefined ? WaiterINformation : null,
|
|
}))
|
|
: allchairData?.map((chairId) => ({
|
|
ChairId: chairId,
|
|
TableId: TableINformation,
|
|
WaiterId:
|
|
WaiterINformation != undefined ? WaiterINformation : null,
|
|
})),
|
|
|
|
ServiceCategory: null,
|
|
ServiceProvider: 0,
|
|
TaxAmount: TotalTaxAmount,
|
|
VatAmount: 0,
|
|
};
|
|
|
|
let response;
|
|
if (GeneratedOrderId && GeneratedSalesId && type == 'Pay') {
|
|
if (Cookies.get('DeviceStatusId')) {
|
|
data['DeviceStatusId'] = Cookies.get('DeviceStatusId');
|
|
} else {
|
|
let DeviceStatusId = generateRandomKey();
|
|
Cookies.set('DeviceStatusId', DeviceStatusId || 'unknown', {
|
|
expires: 365,
|
|
});
|
|
data['DeviceStatusId'] = DeviceStatusId;
|
|
}
|
|
Cookies.set('LastorderId', GeneratedOrderId || 'unknown', {
|
|
expires: 365,
|
|
});
|
|
|
|
data['OrderId'] = GeneratedOrderId;
|
|
data['SalesId'] = GeneratedSalesId;
|
|
|
|
data['UpdatedBy'] = 0;
|
|
|
|
response = await dispatch(putSelfBooking(data)).unwrap();
|
|
if (response?.data?.statusCode == 1) {
|
|
// Handle UPI payment gateway form submission
|
|
if (paymentMethod === 'UPI' && processedUpiData) {
|
|
await handleUpiPaymentGateway(response, processedUpiData);
|
|
} else if (paymentOptionType == 'BU') {
|
|
let OrderId = response?.data?.OrderId;
|
|
setTransctionId(OrderId);
|
|
let Amt = response?.data?.PaymentOrderDtl?.[0]?.Amount;
|
|
setShowPaymentSuccess(false);
|
|
setpaymentUrl(response?.data?.PaymentPageLink);
|
|
} else {
|
|
setTransctionId(response?.data?.OrderId);
|
|
clearsDatas(response?.data?.OrderId);
|
|
}
|
|
}
|
|
} else if (GeneratedOrderId && GeneratedSalesId) {
|
|
data['OrderId'] = GeneratedOrderId;
|
|
data['SalesId'] = GeneratedSalesId;
|
|
data['UpdatedBy'] = 0;
|
|
response = await dispatch(putSelfBooking(data)).unwrap();
|
|
if (response?.data?.statusCode === 1) {
|
|
setMessageType('success');
|
|
setMessageData('Order Placed Successfully');
|
|
}
|
|
let random = Cookies.get('UniqueId');
|
|
await dispatch(
|
|
getSelfBooking({
|
|
uniqueId: random,
|
|
CompId: CompId,
|
|
BranchId: BranchId,
|
|
AppId: AppId,
|
|
})
|
|
);
|
|
} else {
|
|
let Randomkey = generateRandomKey();
|
|
data['CreatedBy'] = 0;
|
|
data['DeviceUniqueId'] = Randomkey;
|
|
response = await dispatch(postSelfBooking(data)).unwrap();
|
|
if (response?.data?.statusCode === 1) {
|
|
Cookies.set('UniqueId', Randomkey || 'unknown', { expires: 1 });
|
|
setMessageType('success');
|
|
setMessageData('Order Placed Successfully');
|
|
|
|
let response1 = await dispatch(
|
|
getSelfBooking({
|
|
uniqueId: Randomkey,
|
|
CompId: CompId,
|
|
BranchId: BranchId,
|
|
AppId: AppId,
|
|
})
|
|
).unwrap();
|
|
|
|
if (
|
|
response1?.data?.statusCode === 1 &&
|
|
response1?.data?.data?.length > 0
|
|
) {
|
|
dispatch(changeOrderId(response1?.data?.data?.[0]?.OrderId));
|
|
dispatch(changeSalesId(response1?.data?.data?.[0]?.SalesId));
|
|
}
|
|
}
|
|
}
|
|
};
|
|
const clearsDatas = (OrderId, Method = null) => {
|
|
let Randomkey = generateRandomKey();
|
|
Cookies.set('LastorderId', OrderId || 'unknown', { expires: 365 });
|
|
Cookies.set('UniqueId', Randomkey || 'unknown', { expires: 1 });
|
|
setMessageType('success');
|
|
setMessageData('Order Placed Successfully');
|
|
setShowPaymentSuccess(false);
|
|
setshowQrCode(true);
|
|
if (Method) {
|
|
setPaymentvia(Method);
|
|
} else {
|
|
setQrTimer(60);
|
|
setQrTimerActive(true);
|
|
}
|
|
const orderId = OrderId;
|
|
setPaymentOrderId(orderId);
|
|
setTimeout(() => {
|
|
setPaymentvia(null);
|
|
localStorage.clear();
|
|
// setshowPaymentSuccessAfterPayment(false)
|
|
setshowQrCode(false);
|
|
setTransctionId(null);
|
|
setPaymentOrderId(null);
|
|
Cookies.remove('UniqueId');
|
|
sessionStorage.clear();
|
|
dispatch(changeKioskOrderDetails([]));
|
|
dispatch(changeKioskPageName());
|
|
dispatch(changeOrderId());
|
|
dispatch(changeSalesId());
|
|
dispatch(changeisKioskCartOpen(false));
|
|
dispatch(changeMergeData([]));
|
|
dispatch(changeMembershipDetail([]));
|
|
// dispatch(changeOrderOfferDetail([]));
|
|
// dispatch(changeSelfBookingCustomerDtls([]));
|
|
// changeSelfBookingCustomerDtls([])
|
|
|
|
navigate(`${subDirectory}selfBooking/${isSelfBookingOpen}`);
|
|
}, 60000);
|
|
};
|
|
|
|
const onClose = () => {
|
|
dispatch(changeisKioskCartOpen(false));
|
|
setOpen(false);
|
|
};
|
|
|
|
const ChangeType = async (Type) => {
|
|
await dispatch(changeBookingType(Type));
|
|
};
|
|
|
|
const onComplete = useCallback(() => {
|
|
setMessageData(null);
|
|
setMessageType(null);
|
|
}, []);
|
|
|
|
// PostCancelPayment
|
|
const CancelPayment = async () => {
|
|
const response = await dispatch(PostCancelPayment({OrderId: TransctionId})).unwrap()
|
|
if (response?.data?.statusCode) {
|
|
// setBusinessUPI(false);
|
|
setpaymentUrl(null)
|
|
}
|
|
}
|
|
|
|
return (
|
|
<div>
|
|
<Messages
|
|
messageType={messageType}
|
|
messageData={messageData}
|
|
onComplete={onComplete}
|
|
/>
|
|
|
|
<div className="kioskpaymentmain">
|
|
<div className="selfkioskFootertopMain">
|
|
<div className="selfkioskFootertop1">
|
|
{KioskCurrentPage !== 'OrderView' && bookingTypeName == 'Both' && (
|
|
<div
|
|
style={{
|
|
display: 'flex',
|
|
flexDirection: 'column',
|
|
alignItems: 'center',
|
|
cursor: 'pointer',
|
|
gap: ' 5px',
|
|
}}
|
|
onClick={() =>
|
|
BookingType === 'TakeAway' && ChangeType('Dine In')
|
|
}
|
|
>
|
|
<PozoDineInIcon
|
|
className={
|
|
BookingType == 'Dine In'
|
|
? 'BSBillingNav-icon-table pulse-element'
|
|
: 'BSBillingNav-icon'
|
|
}
|
|
/>
|
|
<p style={{ fontSize: '12px', fontWeight: '500' }}>DineIn</p>
|
|
</div>
|
|
)}
|
|
{KioskCurrentPage !== 'OrderView' && bookingTypeName == 'Both' && (
|
|
<div
|
|
style={{
|
|
display: 'flex',
|
|
flexDirection: 'column',
|
|
alignItems: 'center',
|
|
cursor: 'pointer',
|
|
gap: ' 5px',
|
|
}}
|
|
onClick={() =>
|
|
BookingType !== 'TakeAway' && ChangeType('TakeAway')
|
|
}
|
|
>
|
|
<TakeAway
|
|
className={
|
|
BookingType != 'Dine In'
|
|
? 'BSBillingNav-icon-table pulse-element'
|
|
: 'BSBillingNav-icon'
|
|
}
|
|
/>
|
|
<p style={{ fontSize: '12px', fontWeight: '500' }}>TakeAway</p>
|
|
</div>
|
|
)}
|
|
|
|
{/* {KioskOrderDetails?.length > 0 &&
|
|
KioskCurrentPage !== 'OrderView' && ( */}
|
|
<div
|
|
className="kioskpaymentviewsummary"
|
|
onClick={() => showDrawer()}
|
|
>
|
|
<Badge
|
|
count={KioskOrderDetails?.length}
|
|
style={{ marginTop: '7px' }}
|
|
>
|
|
|
|
<AiOutlineShoppingCart className="CarticonFooterKiosk" />
|
|
</Badge>
|
|
</div>
|
|
{/* )} */}
|
|
</div>
|
|
|
|
<table className="kiosksummarytable">
|
|
<tr>
|
|
<td className="kiosk-table-cell">
|
|
<div>
|
|
<span>Qty</span>
|
|
<span>: </span>
|
|
<span>
|
|
{' '}
|
|
{KioskOrderDetails?.reduce(
|
|
(total, item) => total + item?.OrderQty,
|
|
0
|
|
)}
|
|
</span>
|
|
</div>
|
|
</td>
|
|
<td className="kiosk-table-cell">
|
|
<div>
|
|
<span>Bill Amt</span>
|
|
<span>:</span>
|
|
<span>₹{Math.round(TotalBillAmount)}</span>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td className="kiosk-table-cell">
|
|
<div>
|
|
<span>Items</span>
|
|
<span>:</span>
|
|
<span>{KioskOrderDetails?.length}</span>
|
|
</div>
|
|
</td>
|
|
<td
|
|
className="kiosk-table-cell"
|
|
style={{
|
|
display: 'flex',
|
|
alignItems: 'center',
|
|
justifyContent: 'space-between',
|
|
border: 'none',
|
|
}}
|
|
>
|
|
<div>
|
|
<span>Tax</span>
|
|
<span> : </span>
|
|
<span> ₹{TotalTaxAmount}</span>
|
|
</div>
|
|
{/* <MdCurrencyRupee size={16} style={{ marginBottom: '1px' }} /> */}
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
|
|
<div className="selfkioskFooterBottomMain">
|
|
<div className="actionbuttonscontainer">
|
|
<p
|
|
className={
|
|
KioskOrderDetails?.length > 0 &&
|
|
KioskOrderDetails?.some((e) => !e?.disabled)
|
|
? 'orderbtnenabled'
|
|
: 'orderbtndisabled'
|
|
}
|
|
onClick={() => {
|
|
handleClick('Order');
|
|
}}
|
|
style={{
|
|
cursor:
|
|
KioskOrderDetails?.length > 0 && !clicked
|
|
? 'pointer'
|
|
: 'default',
|
|
// backgroundColor:
|
|
// KioskOrderDetails?.length > 0 &&
|
|
// !clicked &&
|
|
// getKioskDarkColourdata,
|
|
}}
|
|
>
|
|
Order
|
|
</p>
|
|
<>
|
|
{GeneratedOrderId && KioskOrderDetails?.length > 0 && (
|
|
<p
|
|
className={
|
|
KioskOrderDetails?.length > 0 && !clicked
|
|
? 'paybtnenabled'
|
|
: 'paybtndisabled'
|
|
}
|
|
onClick={() => {
|
|
handleClick('Pay');
|
|
}}
|
|
style={{
|
|
cursor:
|
|
KioskOrderDetails?.length > 0 && !clicked
|
|
? 'pointer'
|
|
: 'default',
|
|
// backgroundColor:
|
|
// KioskOrderDetails?.length > 0 &&
|
|
// !clicked &&
|
|
// getKioskDarkColourdata,
|
|
}}
|
|
>
|
|
Pay
|
|
</p>
|
|
)}
|
|
</>
|
|
|
|
<Drawer
|
|
title="Order View"
|
|
placement={placement}
|
|
width={480}
|
|
onClose={onClose}
|
|
open={open}
|
|
className="my-cls"
|
|
>
|
|
<SelfKisokOrderCart1 KioskOrderDetails={KioskOrderDetails} />
|
|
</Drawer>
|
|
|
|
{/* <div className="payVia" onClick={handlePayVia}>
|
|
PAY VIA {isPayViaOpen ? <FaAngleUp /> : <FaAngleDown />}
|
|
</div>
|
|
|
|
{isPayViaOpen && (
|
|
<div className="kiosk-action-buttons" style={{ padding: '10px' }}>
|
|
<button
|
|
className="kiosk-pay-btn"
|
|
onClick={() => {
|
|
// Handle pay functionality
|
|
console.log('Pay button clicked');
|
|
}}
|
|
>
|
|
Pay
|
|
</button>
|
|
<button
|
|
className="kiosk-merge-btn"
|
|
onClick={() => {
|
|
// Handle merge bill functionality
|
|
console.log('Merge Bill button clicked');
|
|
}}
|
|
>
|
|
Merge Bill
|
|
</button>
|
|
<button
|
|
className="kiosk-pay-request-btn"
|
|
onClick={() => {
|
|
// Handle pay request functionality
|
|
console.log('Pay Request button clicked');
|
|
}}
|
|
>
|
|
Pay Request
|
|
</button>
|
|
<button
|
|
className="kiosk-change-table-btn"
|
|
onClick={() => {
|
|
// Handle change table functionality
|
|
console.log('Change Table button clicked');
|
|
}}
|
|
>
|
|
Change Table
|
|
</button>
|
|
</div>
|
|
)} */}
|
|
</div>
|
|
<div className="actionbuttons2">
|
|
<p>Total Amount</p>
|
|
<div className="total-amount-display">
|
|
:{' '}
|
|
<MdCurrencyRupee
|
|
size={20}
|
|
style={{ marginBottom: '1px', marginRight: '-5px' }}
|
|
/>
|
|
{TotalNetAmount}{' '}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{/* <div className="payment-summary">
|
|
<div
|
|
style={{
|
|
display: 'flex',
|
|
width: '100%',
|
|
fontFamily: 'Poppins',
|
|
alignItems: 'center',
|
|
gap: '16px',
|
|
justifyContent: 'center',
|
|
}}
|
|
>
|
|
<p>
|
|
Qty :{' '}
|
|
{KioskOrderDetails?.reduce(
|
|
(total, item) => total + item?.OrderQty,
|
|
0
|
|
)}
|
|
</p>
|
|
<p>Items : {KioskOrderDetails?.length}</p>
|
|
</div>
|
|
<div
|
|
style={{
|
|
display: 'flex',
|
|
width: '100%',
|
|
alignItems: 'center',
|
|
gap: '10px',
|
|
justifyContent: 'center',
|
|
}}
|
|
>
|
|
<p style={{ color: '#37943c' }}>
|
|
Bill Amount : ₹ {TotalBillAmount}
|
|
</p>
|
|
{TotalTaxAmount > 0 && (
|
|
<p style={{ color: '#37943c' }}>
|
|
Tax :{' '}
|
|
<MdCurrencyRupee
|
|
style={{ marginTop: '2px', marginRight: '-5px' }}
|
|
/>{' '}
|
|
{TotalTaxAmount}
|
|
</p>
|
|
)}
|
|
</div>
|
|
<div style={{ display: 'flex', alignItems: 'center', gap: '6px' }}>
|
|
<p style={{ color: '#37943C' }}>Total Amount</p>
|
|
<div style={{ display: 'flex' }}>
|
|
<div className="total-bill-SelfBooking">
|
|
{' '}
|
|
<MdCurrencyRupee
|
|
size={20}
|
|
style={{ marginBottom: '1px', marginRight: '-5px' }}
|
|
/>
|
|
{TotalNetAmount}{' '}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div> */}
|
|
</div>
|
|
{showPaymentSuccess && (
|
|
<div
|
|
className="payment-success-popup"
|
|
style={{ display: 'flex', flexDirection: 'column', zIndex: '100' }}
|
|
>
|
|
{/* <div className="payment-success-content">
|
|
<span role="img" aria-label="success" style={{fontSize: 40, color: '#4BB543'}}>✔️</span>
|
|
<h2>Payment Successful!</h2>
|
|
<p>Your payment was processed successfully.</p>
|
|
</div> */}
|
|
|
|
{showPaymentSuccess && (
|
|
<SelfBookingPayment
|
|
modalOpen={showPaymentSuccess}
|
|
handleCancel={() => {
|
|
setShowPaymentSuccess(false);
|
|
}}
|
|
sessionData={sessionData}
|
|
HandlePayatCounter={placeOrder}
|
|
OrderMethod={OrderMethod}
|
|
/>
|
|
)}
|
|
</div>
|
|
)}
|
|
|
|
{showQrCode && paymentOrderId && Paymentvia && (
|
|
<>
|
|
<div className="qr-popup-overlay" />
|
|
<div className="qr-code-popup">
|
|
<p className="success-header">
|
|
Your payment has successfully completed! <br />
|
|
<FaCircleCheck size={50} color="#4BB543" className="success-icon" />
|
|
</p>
|
|
<div
|
|
onClick={async (e) => {
|
|
try {
|
|
e.preventDefault();
|
|
if (!TransctionId) {
|
|
setMessageType('error');
|
|
setMessageData('Transaction ID not found. Please contact support.');
|
|
return;
|
|
}
|
|
await handleShareWhatsAppFn(TransctionId);
|
|
} catch (error) {
|
|
console.error('Error in View Receipt click handler:', error);
|
|
setMessageType('error');
|
|
setMessageData('Failed to process receipt request. Please try again.');
|
|
}
|
|
}}
|
|
className="receipt-link"
|
|
>
|
|
View Receipt
|
|
</div>
|
|
<div className="order-id-display">
|
|
<p className="order-id-text">
|
|
Order ID: <span className="order-id-number">{paymentOrderId?.split('-').pop()}</span>
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</>
|
|
)}
|
|
{showQrCode && paymentOrderId && !Paymentvia && (
|
|
<>
|
|
<div className="qr-popup-overlay" />
|
|
<div className="qr-code-popup">
|
|
<div className="counter-header">
|
|
<h2 className="counter-title">Go to counter for payment </h2>
|
|
</div>
|
|
<p className="qr-instruction">
|
|
Scan this QR code to view your order details
|
|
</p>
|
|
<div className="qr-container">
|
|
<OrderQR orderId={paymentOrderId} />
|
|
</div>
|
|
<div className="order-id-display">
|
|
<p className="order-id-text">
|
|
Order ID: <span className="order-id-number">{paymentOrderId?.split('-').pop()}</span>
|
|
</p>
|
|
</div>
|
|
<div className="qr-timer-display">
|
|
<div className="timer-circle">
|
|
<svg className="timer-svg" viewBox="0 0 100 100">
|
|
<circle
|
|
className="timer-circle-bg"
|
|
cx="50"
|
|
cy="50"
|
|
r="45"
|
|
/>
|
|
<circle
|
|
className="timer-circle-progress"
|
|
cx="50"
|
|
cy="50"
|
|
r="45"
|
|
style={{
|
|
strokeDashoffset: `${283 - (283 * qrTimer) / 60}`
|
|
}}
|
|
/>
|
|
</svg>
|
|
<div className="timer-text">{qrTimer}s</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</>
|
|
)}
|
|
|
|
<DefaultModal
|
|
open={isPhoneModalOpen}
|
|
title="Enter Your Phone Number"
|
|
handleCancel={handlePhoneModalCancel}
|
|
handleSubmit={handlePhoneModalSubmit}
|
|
buttonText={isPhoneLoading ? 'Processing...' : 'Continue'}
|
|
width={520}
|
|
footer={true}
|
|
className="phone-number-modal enhanced-phone-modal"
|
|
>
|
|
<div className="phone-modal-content">
|
|
<div className="phone-input-section">
|
|
<div className="input-icon">
|
|
<svg width="24" height="24" viewBox="0 0 24 24" fill="none">
|
|
<path d="M6.62 10.79C8.06 13.62 10.38 15.94 13.21 17.38L15.41 15.18C15.69 14.9 16.08 14.82 16.43 14.93C17.55 15.3 18.75 15.5 20 15.5C20.55 15.5 21 15.95 21 16.5V20C21 20.55 20.55 21 20 21C10.61 21 3 13.39 3 4C3 3.45 3.45 3 4 3H7.5C8.05 3 8.5 3.45 8.5 4C8.5 5.25 8.7 6.45 9.07 7.57C9.18 7.92 9.1 8.31 8.82 8.59L6.62 10.79Z" fill="#4BB543"/>
|
|
</svg>
|
|
</div>
|
|
<label className="phone-label">Phone Number</label>
|
|
<Input
|
|
placeholder="Enter your 10-digit phone number"
|
|
value={phoneNumber}
|
|
onChange={(e) => setPhoneNumber(e.target.value)}
|
|
size="large"
|
|
className="phone-input"
|
|
maxLength={10}
|
|
type="tel"
|
|
prefix={<span className="country-code">+91</span>}
|
|
/>
|
|
</div>
|
|
<div className="phone-info-card">
|
|
<div className="info-icon">
|
|
<svg width="16" height="16" viewBox="0 0 24 24" fill="none">
|
|
<path d="M12 2C6.48 2 2 6.48 2 12C2 17.52 6.48 22 12 22C17.52 22 22 17.52 22 12C22 6.48 17.52 2 12 2ZM13 17H11V11H13V17ZM13 9H11V7H13V9Z" fill="#1890ff"/>
|
|
</svg>
|
|
</div>
|
|
<p className="info-text">
|
|
We need your phone number for order tracking and delivery updates.
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</DefaultModal>
|
|
{/* Order method modal: ask whether customer will come in person or needs home delivery */}
|
|
<DefaultModal
|
|
open={isOrderMethodModalOpen}
|
|
title="How would you like to receive your order?"
|
|
handleCancel={() => setIsOrderMethodModalOpen(false)}
|
|
handleSubmit={() => setShowPaymentSuccess(true)}
|
|
buttonText={null}
|
|
width={480}
|
|
footer={false}
|
|
className="order-method-modal"
|
|
>
|
|
<div
|
|
style={{
|
|
padding: '10px 0',
|
|
display: 'flex',
|
|
flexDirection: 'column',
|
|
gap: '12px',
|
|
}}
|
|
>
|
|
<p style={{ margin: 0, fontSize: '15px', color: '#333' }}>
|
|
Will you come in person, or do you need home delivery?
|
|
</p>
|
|
|
|
<div style={{ display: 'flex', gap: '12px', marginTop: '8px' }}>
|
|
<button
|
|
onClick={() => {
|
|
(setIsOrderMethodModalOpen(false),
|
|
setShowPaymentSuccess(true),
|
|
setOrderMethod('inPerson'));
|
|
}}
|
|
style={{
|
|
flex: 1,
|
|
padding: '12px 10px',
|
|
background: '#4BB543',
|
|
color: 'white',
|
|
border: 'none',
|
|
borderRadius: '8px',
|
|
cursor: 'pointer',
|
|
fontWeight: 600,
|
|
}}
|
|
>
|
|
I'll come in person
|
|
</button>
|
|
|
|
<button
|
|
onClick={() => {
|
|
(setIsOrderMethodModalOpen(false),
|
|
setShowPaymentSuccess(true),
|
|
setOrderMethod(null));
|
|
}}
|
|
style={{
|
|
flex: 1,
|
|
padding: '12px 10px',
|
|
background: '#1a73e8',
|
|
color: 'white',
|
|
border: 'none',
|
|
borderRadius: '8px',
|
|
cursor: 'pointer',
|
|
fontWeight: 600,
|
|
}}
|
|
>
|
|
Home delivery
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</DefaultModal>
|
|
{paymentUrl != null && (
|
|
<div className="payment-modal">
|
|
<div className="modal-header">
|
|
<h2>Complete Payment</h2>
|
|
<button
|
|
className="paymentclose-btn"
|
|
onClick={() => {
|
|
// setpaymentUrl(null);
|
|
setShowCancelConfirm(true);
|
|
}}
|
|
>
|
|
✖
|
|
</button>
|
|
</div>
|
|
|
|
<iframe
|
|
src={paymentUrl}
|
|
title="Payment"
|
|
className="payment-frame"
|
|
></iframe>
|
|
</div>
|
|
)}
|
|
{showCancelConfirm && (
|
|
<Modal
|
|
open={showCancelConfirm}
|
|
title="Cancel Payment"
|
|
onOk={() => {
|
|
setShowCancelConfirm(false);
|
|
CancelPayment()
|
|
}}
|
|
onCancel={() => setShowCancelConfirm(false)}
|
|
okText="Yes"
|
|
cancelText="No"
|
|
>
|
|
Do you want to cancel the payment?
|
|
</Modal>
|
|
)}
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default selfKioskFooter;
|