import React, { useState, useEffect, useCallback, useRef } from 'react'; import { Messages } from '../../Components/Notifications/Messages'; import FormHeader from '../PageComponents/FormHeader'; import { Tables } from '../../Components/Tables/Table'; import { DropDowns } from '../../Components/Forms/DropDown'; import { useDispatch } from 'react-redux'; import { getConfiguration, PublicQrCodepost, } from '../../Features/ConfigMasterPage/ConfigMasterPage'; import Buttons from '../../Components/Forms/Buttons'; import { PlusOutlined, DownloadOutlined, EyeOutlined } from '@ant-design/icons'; import { MdClear } from 'react-icons/md'; import { getDineinTableData } from '../../Features/Dinein/Dinein'; import { encryptObject, getSession } from '../../Services/Others'; import QRCode from 'react-qr-code'; import jsPDF from 'jspdf'; import html2canvas from 'html2canvas'; import { Modal } from 'antd'; import { ApplicationPreferences, getBranchDetail, } from '../../Features/BrachLogin/BranchLogin'; import { changeBreadCrumb, getEmpAccess } from '../../Features/AppPage/CenterPage'; import { useSelector } from 'react-redux'; import PublicQrCodeShare from './PublicQrCodeShare/PublicQrCodeShare'; import { FeatureAddon } from '../../Features/BookingScreen/BookingData/BookingData'; import { getPaymentOptionsData } from '../../Features/Payment/Paymentoptions/Paymentoptions'; import { useAuth } from '../../AuthContext'; const subDirectory = import.meta.env.ENV_MAIN_BASE_URL; const items = [ { name: 'Home', link: `${subDirectory}app-page/home`, }, ]; const PublicQrCode = () => { const dispatch = useDispatch(); console.log('PublicQrCode component rendered', `${subDirectory}`); const appPreferences = useSelector(ApplicationPreferences); const commonModulePreference = appPreferences?.find( (preference) => preference?.PreferredCatName === 'Common Module' )?.PreferenceCatDetails; const sportsAppPreference = commonModulePreference?.find( (preference) => preference?.PreferredSubCatName === 'SportsApp' && preference?.PreferredStatus == 'Y' ); const [messageType, setMessageType] = useState(null); const [messageData, setMessageData] = useState(null); const [configdatas, setConfigdatas] = useState([]); const [configId, setConfigId] = useState(null); const [TableId, setTableId] = useState(null); const [WaiterId, setWaiterId] = useState(null); const [Tabledata, setTabledata] = useState([]); const [CheckTabledata, setCheckTabledata] = useState([]); const [qrCodeUrl, setQrCodeUrl] = useState(''); const [empData, setEmpData] = useState(); const [addnewAccess, setaddnewAccess] = useState(true); const [selectedConfig, setSelectedConfig] = useState({ id: '', name: 'Both', }); const [SelectedSelfBooking, setSelectedSelfBooking] = useState({ id: '', name: '', }); const initializedRef = useRef(false); const configIdInitializedRef = useRef(false); const handleSubmitCalledRef = useRef(false); const [branchData, setBranchData] = useState([]); const [page, setPage] = useState(1); const [isPreviewModalOpen, setIsPreviewModalOpen] = useState(false); const [pdfPreviewUrl, setPdfPreviewUrl] = useState(''); const qrCodeRef = useRef(null); const CompId = getSession('CompId'); const BranchId = getSession('BranchId'); const AppId = getSession('AppId'); const UserId = getSession('UserId'); const UserType = getSession('UserType'); const { SadminuserAccess } = useAuth(); const SAAccessCommonMaster = SadminuserAccess?.find( (e) => e?.MenuName === 'SelfBooking QR Code' ); const allowed = ['TakeAway', CheckTabledata?.length > 0 ? 'Dine In' : '']; const bookingTypePreference = appPreferences?.find( (preference) => preference?.PreferredCatName === 'Booking Type' )?.PreferenceCatDetails; const dinePreference = bookingTypePreference?.find( (type) => type?.PreferredSubCatName?.toLowerCase() === 'dine in' && type?.PreferredStatus === 'Y' ); const takeAwayPreference = bookingTypePreference?.find( (type) => type?.PreferredSubCatName?.toLowerCase() === 'take away' && type?.PreferredStatus === 'Y' ); const filtered = configdatas.filter( (item) => allowed.includes(item.ConfigName) && item?.TypeName == 'Booking Type' ); const SelfBooking = configdatas.filter( (item) => item?.TypeName === 'SelfBookingOption' ); const SelfBookingtype = configdatas.filter( (item) => item?.TypeName === 'SelfBookingType' ); // Check if filtered contains both "Dine In" and "TakeAway" const hasDineIn = filtered.some( (item) => item.ConfigName?.toLowerCase() === 'dine in' ); const hasTakeAway = filtered.some( (item) => item.ConfigName?.toLowerCase() === 'takeaway' ); const hasBoth = hasDineIn && hasTakeAway; let finalFiltered = []; filtered.forEach((item) => { const name = item.ConfigName?.toLowerCase(); if (sportsAppPreference) { if (name === 'takeaway') { finalFiltered.push({ ...item, ConfigName: 'Online Booking' }); } } else { if (name === 'dine in') { if (dinePreference) { finalFiltered.push(item); // keep dine in } } else if (name === 'takeaway') { if (takeAwayPreference) { finalFiltered.push(item); // keep take away } else { // rename to Sales if takeaway not allowed finalFiltered.push({ ...item, ConfigName: 'Sales' }); } } else { finalFiltered.push(item); // keep any other booking type } } }); // Remove duplicates by ConfigName finalFiltered = finalFiltered.filter( (item, index, self) => index === self.findIndex((t) => t.ConfigName === item.ConfigName) ); // Add "Both" option only if filtered contains both "Dine In" and "TakeAway" and sportsAppPreference is false if (hasBoth && !sportsAppPreference) { finalFiltered.unshift({ ConfigId: 'All', // you can give a special id ConfigName: 'Both', }); } console.log(finalFiltered, filtered, 'Final Filtered'); useEffect(() => { fetchApi(); fetchBranchData(); dispatch(changeBreadCrumb({ items: items })); }, []); // Reset initialization refs when CheckTabledata or sportsAppPreference changes useEffect(() => { configIdInitializedRef.current = false; }, [CheckTabledata]); useEffect(() => { handleSubmitCalledRef.current = false; }, [sportsAppPreference]); // Set default configId based on available options useEffect(() => { if (configIdInitializedRef.current || !finalFiltered?.length) return; if (sportsAppPreference) { // Set default to "Online Booking" when sportsAppPreference is true const onlineBookingOption = finalFiltered.find( (option) => option.ConfigName === 'Online Booking' ); if (onlineBookingOption) { setConfigId(onlineBookingOption.ConfigId); configIdInitializedRef.current = true; } } else if (hasBoth) { // Set default to "Both" if both options are available setConfigId('All'); configIdInitializedRef.current = true; } else if (finalFiltered?.length > 0) { // Set default to first available option if only one is available setConfigId(finalFiltered[0]?.ConfigId || null); configIdInitializedRef.current = true; } }, [sportsAppPreference, finalFiltered, hasBoth]); const fetchBranchData = async () => { const response = await dispatch( getBranchDetail({ BrId: BranchId }) ).unwrap(); if (response?.data?.statusCode === 1) { setBranchData(response?.data?.data); } else { setBranchData(); } let response2 = await dispatch( getDineinTableData({ CompId: CompId, BranchId: BranchId, AppId: AppId }) ).unwrap(); if (response2?.data?.statusCode == 1) { setCheckTabledata(response2?.data?.data); } }; useEffect(() => { let hasAccess = false; if (UserType === 'Admin' || UserType === 'Super Admin') { hasAccess = true; } else if (UserType === 'Employee') { hasAccess = empData?.AddAccess === 'Y'; } else if (UserType === 'Super Admin User') { hasAccess = SAAccessCommonMaster?.AddAccess === 'Y'; } setaddnewAccess(!hasAccess); }, [empData, SAAccessCommonMaster, UserType]); useEffect(() => { if (UserType === "Employee") { fetchApiEmpAccess() } }, [UserType]) const fetchApiEmpAccess = async () => { let data = { CompId: CompId, BranchId: BranchId, AppId: AppId, EmpId: UserId, }; let response = await dispatch(getEmpAccess(data)).unwrap(); let datas = response?.data?.data?.[0]?.EmpAccessDetails?.filter( (item) => item.ConfigName === 'SelfBooking QR Code' ); setEmpData(datas?.[0]); }; const fetchApi = async () => { let response = await dispatch(getConfiguration({ Type: 'SA' })).unwrap(); if (response?.data?.statusCode === 1) { setConfigdatas(response?.data?.data); } }; const ConfigSelect = (e) => { let isDinein = filtered?.find((item) => item.ConfigId === e)?.ConfigName === 'Dine In'; if (isDinein && !sportsAppPreference) { TableData(); } else { setTabledata([]); } setConfigId(e); setQrCodeUrl(''); // Clear QR code when booking type changes setTableId(null); setWaiterId(null); // Reset table selection }; const TableSelect = (e) => { let getWaiterId = Tabledata?.find((a) => a?.TableId == e); setTableId(e); setWaiterId(getWaiterId?.WaiterId); setQrCodeUrl(''); // Clear QR code when table changes }; const TableData = async () => { let response = await dispatch( getDineinTableData({ CompId: CompId, BranchId: BranchId, AppId: AppId }) ).unwrap(); if (response?.data?.statusCode == 1) { setTabledata(response?.data?.data); } }; const HandleSubmit = async () => { if (!sportsAppPreference) { try { const bookingTypeName = filtered?.find((item) => item.ConfigId === configId)?.ConfigName || 'Both'; const tableName = Tabledata?.find((item) => item.TableId === TableId)?.TableName || ''; console.log(bookingTypeName, 'bookingTypeName'); if (!configId) { setMessageType('error'); setMessageData('Please select a booking type.'); return; } let data = {}; if (Tabledata?.length > 0) { if (!TableId) { setMessageType('error'); setMessageData('Please select a table.'); return; } data = { BranchId, BookingType: configId, TableId, bookingTypeName, tableName, WaiterId, selfBookingOption: selectedConfig.name, selfBookingtype: SelectedSelfBooking.name, }; } else { data = { BranchId, BookingType: configId, bookingTypeName, selfBookingOption: selectedConfig.name, selfBookingtype: SelectedSelfBooking.name, }; } const encrypted = encryptObject(data); const postData = { Url: encrypted, CreatedBy: UserId }; const res = await dispatch(PublicQrCodepost(postData)).unwrap(); if (res?.data?.statusCode == 1) { const QrUrl = `${subDirectory}selfBooking/${res?.data?.ReferenceNo}`; setQrCodeUrl(QrUrl); generatePDF(true, QrUrl); } } catch (error) { console.error('HandleSubmit Error:', error); setMessageType('error'); setMessageData('An unexpected error occurred.'); } } else { let Data1 = filtered?.find((e) => e?.ConfigName === 'TakeAway'); let data = { BranchId, BookingType: Data1?.ConfigId, bookingTypeName: Data1?.ConfigName, selfBookingOption: selectedConfig.name, selfBookingtype: SelectedSelfBooking.name, }; const encrypted = encryptObject(data); const postData = { Url: encrypted, CreatedBy: UserId }; const res = await dispatch(PublicQrCodepost(postData)).unwrap(); if (res?.data?.statusCode == 1) { const QrUrl = `${subDirectory}selfBooking/${res?.data?.ReferenceNo}`; setQrCodeUrl(QrUrl); generatePDF(true, QrUrl); } } }; // Auto-submit when sportsAppPreference is true (only once) useEffect(() => { if ( sportsAppPreference && !handleSubmitCalledRef.current && finalFiltered?.length > 0 && configId ) { const onlineBookingOption = finalFiltered.find( (option) => option.ConfigName === 'Online Booking' ); if (onlineBookingOption && configId === onlineBookingOption.ConfigId) { handleSubmitCalledRef.current = true; // Use setTimeout to avoid calling during render setTimeout(() => { HandleSubmit(); }, 0); } } // eslint-disable-next-line react-hooks/exhaustive-deps }, [sportsAppPreference, finalFiltered, configId]); // Function to generate PDF const generatePDF = async (isPreview = false, encrypted) => { console.log('generatePDF called with:', { isPreview, encrypted }); if (!encrypted) { setMessageType('error'); setMessageData('Please generate QR code first'); return; } try { // Get booking type name and table name for display const bookingTypeName = filtered?.find((item) => item.ConfigId === configId)?.ConfigName || 'Both'; const tableName = Tabledata?.find((item) => item.TableId === TableId)?.TableName || ''; // Get branch details const branch = branchData?.[0] || {}; const branchName = branch.BrName || branch.CompName || ''; const branchMobile = branch.BrMobile || ''; const companyLogo = branch.CompLogo || ''; const branchAddress = [ branch.Address1, branch.Address2, branch.City, branch.State, branch.Zip, ] .filter(Boolean) .join(', ') || ''; // Create a temporary div for PDF content const tempDiv = document.createElement('div'); tempDiv.style.padding = '40px'; tempDiv.style.backgroundColor = 'white'; tempDiv.style.fontFamily = 'Arial, sans-serif'; tempDiv.style.textAlign = 'center'; tempDiv.style.width = '600px'; tempDiv.style.margin = '0 auto'; // Add content to the temporary div tempDiv.innerHTML = `
${branchAddress || ''}
${branchMobile || ''}
🔗 ${encrypted}
URL: {qrCodeUrl}