2026-01-27 18:27:29 +05:30
|
|
|
|
// AppRoutes.jsx
|
2026-02-11 12:09:36 +05:30
|
|
|
|
import React, { useEffect, useState, useRef, lazy, } from 'react';
|
2026-01-27 18:27:29 +05:30
|
|
|
|
import { Routes, Route } from 'react-router-dom';
|
|
|
|
|
|
import { useNavigate } from 'react-router-dom';
|
|
|
|
|
|
import { useDispatch, useSelector } from 'react-redux';
|
|
|
|
|
|
import ProtectedRoutes from './ProtectedRoutes';
|
2026-02-11 12:09:36 +05:30
|
|
|
|
|
|
|
|
|
|
import SelfBooking from './Pages/SelfBooking/SelfBooking.jsx'
|
2026-01-27 18:27:29 +05:30
|
|
|
|
import { isMobile, isIOS } from "react-device-detect";
|
2026-02-11 12:09:36 +05:30
|
|
|
|
// const { routesConfig } = lazy(() => import('./routesConfig'));
|
2026-01-27 18:27:29 +05:30
|
|
|
|
import { routesConfig } from './routesConfig';
|
|
|
|
|
|
import {
|
|
|
|
|
|
ChangeAppExpDateData,
|
|
|
|
|
|
changeHeightforExpDate,
|
|
|
|
|
|
getAppSubscriptionDate,
|
|
|
|
|
|
GlobalItemCard,
|
|
|
|
|
|
} from './Features/BookingScreen/BookingData/BookingData.js';
|
|
|
|
|
|
import {
|
|
|
|
|
|
checkSession,
|
|
|
|
|
|
GenerateLogout,
|
|
|
|
|
|
} from './Features/BrachLogin/BranchLogin.js';
|
|
|
|
|
|
import {
|
|
|
|
|
|
clearSession,
|
|
|
|
|
|
getSession,
|
|
|
|
|
|
TokendecryptedValuesFun,
|
|
|
|
|
|
} from './Services/Others.js';
|
|
|
|
|
|
import devtools from 'devtools-detect';
|
|
|
|
|
|
import KisokSelBooking from './Pages/SelfBooking/KisokSelBooking.jsx';
|
|
|
|
|
|
import IndividualBooking from './Pages/SelfBooking/IndividualBooking.jsx';
|
|
|
|
|
|
const commonSubDir = import.meta.env.ENV_COMMON_BASE_URL;
|
|
|
|
|
|
const subDirectory = import.meta.env.ENV_BASE_URL;
|
|
|
|
|
|
import "../ownLib/my-ui-lib.css"
|
|
|
|
|
|
import CustomerMenuPage from './Pages/Reports/MenuQRCode/CustomerMenuPage.jsx';
|
|
|
|
|
|
import WeightScaleApp from './Pages/BookingScreen/WeightscaleApp.jsx';
|
2026-02-11 12:09:36 +05:30
|
|
|
|
|
|
|
|
|
|
import { getPurchasedAppDetails, postInvoice } from './Features/BookingScreen/Pricing/Pricing.js';
|
|
|
|
|
|
import { sendSms } from './Features/Payment/PaymentDetails/PaymentDetails.js';
|
|
|
|
|
|
import ExtendSubscriptionModal from './Pages/ExtentedModal/ExtendSubscriptionModal.jsx';
|
2026-01-27 18:27:29 +05:30
|
|
|
|
const AppRoutes = () => {
|
|
|
|
|
|
const navigate = useNavigate();
|
|
|
|
|
|
const dispatch = useDispatch();
|
|
|
|
|
|
const ItemCard = useSelector(GlobalItemCard);
|
|
|
|
|
|
const [remainingDays, setRemainingDays] = useState(null);
|
|
|
|
|
|
const prevRemainingDays = useRef(null);
|
|
|
|
|
|
const [sessionData, setSessionData] = useState(null);
|
|
|
|
|
|
const [devToolsOpen, setDevToolsOpen] = useState(false);
|
2026-02-11 12:09:36 +05:30
|
|
|
|
const [extendModel, setExtendModel] = useState(false);
|
2026-01-27 18:27:29 +05:30
|
|
|
|
useEffect(() => {
|
|
|
|
|
|
const handlePopState = (e) => {
|
|
|
|
|
|
const SessionId = getSession('SessionId');
|
|
|
|
|
|
if (!SessionId) {
|
|
|
|
|
|
alert(
|
|
|
|
|
|
'Session invalid and Unauthorized action detected. Redirecting to login...'
|
|
|
|
|
|
);
|
|
|
|
|
|
clearSession();
|
|
|
|
|
|
window.location.replace(`${commonSubDir}`);
|
|
|
|
|
|
} else {
|
|
|
|
|
|
window.history.go(1);
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// Add event listener on mount
|
|
|
|
|
|
window.addEventListener('popstate', handlePopState);
|
|
|
|
|
|
|
|
|
|
|
|
// Clean up the event listener on unmount
|
|
|
|
|
|
return () => {
|
|
|
|
|
|
window.removeEventListener('popstate', handlePopState);
|
|
|
|
|
|
};
|
|
|
|
|
|
}, []);
|
|
|
|
|
|
|
2026-02-11 12:09:36 +05:30
|
|
|
|
//cmd it start
|
|
|
|
|
|
// useEffect(() => {
|
|
|
|
|
|
// sessionCheckFun()
|
|
|
|
|
|
// }, [navigate, ItemCard]);
|
2026-01-27 18:27:29 +05:30
|
|
|
|
|
2026-02-11 12:09:36 +05:30
|
|
|
|
//cmd it End
|
2026-01-27 18:27:29 +05:30
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
|
const loadSessionData = () => {
|
|
|
|
|
|
const CompId = getSession('CompId');
|
|
|
|
|
|
const AppId = getSession('AppId');
|
|
|
|
|
|
const BranchId = getSession('BranchId');
|
|
|
|
|
|
const UserType = getSession('UserType');
|
|
|
|
|
|
console.log('loadSessionData:', CompId, AppId, BranchId, UserType);
|
|
|
|
|
|
|
|
|
|
|
|
if (CompId && AppId && BranchId) {
|
|
|
|
|
|
setSessionData({ CompId, AppId, BranchId, UserType });
|
|
|
|
|
|
return true; // Indicate that session data is available
|
|
|
|
|
|
}
|
|
|
|
|
|
return false; // Indicate that session data is not yet available
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
if (!loadSessionData()) {
|
|
|
|
|
|
const interval = setInterval(() => {
|
|
|
|
|
|
if (loadSessionData()) {
|
|
|
|
|
|
clearInterval(interval); // Stop checking once data is available
|
|
|
|
|
|
}
|
|
|
|
|
|
}, 1000);
|
|
|
|
|
|
|
|
|
|
|
|
return () => clearInterval(interval); // Cleanup interval on unmount
|
|
|
|
|
|
}
|
|
|
|
|
|
}, []);
|
|
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
|
const fetchExpDate = async () => {
|
|
|
|
|
|
if (!sessionData) {
|
|
|
|
|
|
console.log('Session data not available, skipping API call...');
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
const { CompId, AppId, BranchId, UserType } = sessionData;
|
|
|
|
|
|
const data = { CompId, BranchId, AppId };
|
|
|
|
|
|
|
|
|
|
|
|
let res = await dispatch(getAppSubscriptionDate(data)).unwrap();
|
|
|
|
|
|
|
|
|
|
|
|
if (res?.data?.statusCode === 1 && res?.data?.data?.length > 0) {
|
|
|
|
|
|
const expData = res?.data?.data?.[0];
|
|
|
|
|
|
|
|
|
|
|
|
if (prevRemainingDays.current !== expData.RemainingDays) {
|
|
|
|
|
|
prevRemainingDays.current = expData.RemainingDays;
|
|
|
|
|
|
setRemainingDays(expData.RemainingDays);
|
|
|
|
|
|
dispatch(ChangeAppExpDateData(expData));
|
|
|
|
|
|
dispatch(changeHeightforExpDate(expData.RemainingDays));
|
|
|
|
|
|
|
2026-02-11 12:09:36 +05:30
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2026-01-27 18:27:29 +05:30
|
|
|
|
if (
|
|
|
|
|
|
expData.RemainingDays < 1 &&
|
|
|
|
|
|
expData.RemainingHours < 1 &&
|
|
|
|
|
|
expData.RemainingMinutes < 1 &&
|
|
|
|
|
|
expData.RemainingSeconds < 1
|
|
|
|
|
|
) {
|
2026-02-11 12:09:36 +05:30
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2026-01-27 18:27:29 +05:30
|
|
|
|
if (
|
2026-02-11 12:09:36 +05:30
|
|
|
|
(UserType !== 'Super Admin' ||
|
|
|
|
|
|
UserType !== 'Super Admin User') && (expData?.PlanType?.toLowerCase() == "extend expired")
|
2026-01-27 18:27:29 +05:30
|
|
|
|
) {
|
|
|
|
|
|
console.log('Subscription expired, logging out...');
|
|
|
|
|
|
alert(
|
|
|
|
|
|
'Subscription expired, logging out. Redirecting to login...'
|
|
|
|
|
|
);
|
|
|
|
|
|
Logout();
|
|
|
|
|
|
}
|
2026-02-11 12:09:36 +05:30
|
|
|
|
else if (
|
|
|
|
|
|
(UserType !== 'Super Admin' ||
|
|
|
|
|
|
UserType !== 'Super Admin User') && (expData?.PlanType?.toLowerCase() == "plan expired")
|
|
|
|
|
|
) {
|
|
|
|
|
|
setExtendModel(true)
|
|
|
|
|
|
// "Extend Expired"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// alert(
|
|
|
|
|
|
// 'Subscription expired, logging out. Redirecting to login...'
|
|
|
|
|
|
// );
|
|
|
|
|
|
// Logout();
|
|
|
|
|
|
}
|
2026-01-27 18:27:29 +05:30
|
|
|
|
}
|
|
|
|
|
|
}
|
2026-02-11 12:09:36 +05:30
|
|
|
|
|
2026-01-27 18:27:29 +05:30
|
|
|
|
} else {
|
|
|
|
|
|
console.log('No subscription data found, logging out...');
|
|
|
|
|
|
alert(
|
|
|
|
|
|
'No subscription data found, logging out. Redirecting to login...'
|
|
|
|
|
|
);
|
|
|
|
|
|
Logout();
|
|
|
|
|
|
}
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error('Error fetching subscription data:', error);
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
if (remainingDays === null) {
|
|
|
|
|
|
fetchExpDate();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const interval = setInterval(fetchExpDate, 60 * 60 * 1000);
|
|
|
|
|
|
|
|
|
|
|
|
return () => clearInterval(interval);
|
|
|
|
|
|
}, [sessionData, remainingDays]);
|
|
|
|
|
|
|
|
|
|
|
|
const Logout = async () => {
|
|
|
|
|
|
const UserId = getSession('UserId');
|
|
|
|
|
|
const status = 'N';
|
|
|
|
|
|
try {
|
|
|
|
|
|
const res = await dispatch(GenerateLogout({ UserId, status })).unwrap();
|
|
|
|
|
|
if (res?.data?.statusCode === 1) {
|
|
|
|
|
|
sessionStorage.clear();
|
|
|
|
|
|
window.location.replace(`${commonSubDir}`);
|
|
|
|
|
|
}
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error('Logout failed:', error);
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
2026-02-11 12:09:36 +05:30
|
|
|
|
// mohan
|
|
|
|
|
|
// useEffect(() => {
|
|
|
|
|
|
// if (isMobile || isIOS) {
|
|
|
|
|
|
// console.log("📱 Mobile/iOS device → skipping DevTools detection");
|
|
|
|
|
|
// return;
|
|
|
|
|
|
// }
|
|
|
|
|
|
// const checkDevTools = setInterval(() => {
|
|
|
|
|
|
// if (devtools.isOpen && !devToolsOpen) {
|
|
|
|
|
|
// setDevToolsOpen(true);
|
|
|
|
|
|
// document.body.innerHTML =
|
|
|
|
|
|
// "<h1 style='color: red; text-align: center;'>Close Inspect to continue using the application.</h1>";
|
|
|
|
|
|
// }
|
|
|
|
|
|
// else if (!devtools.isOpen && devToolsOpen) {
|
|
|
|
|
|
// setDevToolsOpen(false);
|
|
|
|
|
|
|
|
|
|
|
|
// setTimeout(() => {
|
|
|
|
|
|
// window.location.reload();
|
|
|
|
|
|
// }, 100);
|
|
|
|
|
|
|
|
|
|
|
|
// clearInterval(checkDevTools);
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
|
|
// if (!devtools.isOpen) {
|
|
|
|
|
|
// let before = performance.now();
|
|
|
|
|
|
|
|
|
|
|
|
// let after = performance.now();
|
|
|
|
|
|
|
|
|
|
|
|
// let executionDelay = after - before;
|
|
|
|
|
|
|
|
|
|
|
|
// if (executionDelay > 100) {
|
|
|
|
|
|
// setDevToolsOpen(true);
|
|
|
|
|
|
// document.body.innerHTML =
|
|
|
|
|
|
// "<h1 style='color: red; text-align: center;'>Close Inspect to continue using the application.</h1>";
|
|
|
|
|
|
// } else {
|
|
|
|
|
|
// setDevToolsOpen(false);
|
|
|
|
|
|
// }
|
|
|
|
|
|
// }
|
|
|
|
|
|
// }, 1000);
|
|
|
|
|
|
|
|
|
|
|
|
// return () => clearInterval(checkDevTools);
|
|
|
|
|
|
// }, [devToolsOpen]);
|
|
|
|
|
|
|
|
|
|
|
|
const sessionCheckFun = async () => {
|
|
|
|
|
|
const UserId = getSession('UserId');
|
|
|
|
|
|
const sessionId = getSession('SessionId');
|
|
|
|
|
|
const IsLogout = getSession('Mode');
|
|
|
|
|
|
let encryptedLoginType = TokendecryptedValuesFun(
|
|
|
|
|
|
sessionStorage.getItem('LoginType')
|
|
|
|
|
|
);
|
|
|
|
|
|
if (encryptedLoginType != 'Kiosk') {
|
|
|
|
|
|
const res = await dispatch(checkSession({ UserId, sessionId })).unwrap();
|
|
|
|
|
|
if (res?.data?.statusCode === 1) {
|
|
|
|
|
|
if (res?.data?.response === 'False') {
|
|
|
|
|
|
if (IsLogout !== 'Logout') {
|
|
|
|
|
|
alert('Session invalid. Redirecting to login...');
|
2026-01-27 18:27:29 +05:30
|
|
|
|
}
|
2026-02-11 12:09:36 +05:30
|
|
|
|
clearSession();
|
|
|
|
|
|
window.location.replace(commonSubDir);
|
2026-01-27 18:27:29 +05:30
|
|
|
|
}
|
|
|
|
|
|
}
|
2026-02-11 12:09:36 +05:30
|
|
|
|
}
|
|
|
|
|
|
};
|
2026-01-27 18:27:29 +05:30
|
|
|
|
|
2026-02-11 12:09:36 +05:30
|
|
|
|
// ---------------- DATE UTILS ----------------
|
|
|
|
|
|
function formatDate(date) {
|
|
|
|
|
|
const year = date.getFullYear();
|
|
|
|
|
|
const month = String(date.getMonth() + 1).padStart(2, '0');
|
|
|
|
|
|
const day = String(date.getDate()).padStart(2, '0');
|
|
|
|
|
|
const hours = String(date.getHours()).padStart(2, '0');
|
|
|
|
|
|
const minutes = String(date.getMinutes()).padStart(2, '0');
|
|
|
|
|
|
const seconds = String(date.getSeconds()).padStart(2, '0');
|
|
|
|
|
|
const milliseconds = String(date.getMilliseconds()).padStart(3, '0');
|
|
|
|
|
|
|
|
|
|
|
|
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}.${milliseconds}`;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function addDays(dateString, days) {
|
|
|
|
|
|
// Make it ISO-safe for iOS / WebView
|
|
|
|
|
|
const isoDate = dateString.replace(' ', 'T');
|
|
|
|
|
|
const currentDate = new Date(isoDate);
|
|
|
|
|
|
|
|
|
|
|
|
currentDate.setDate(currentDate.getDate() + Number(days));
|
|
|
|
|
|
|
|
|
|
|
|
return formatDate(currentDate);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// ---------------- MAIN FUNCTION ----------------
|
|
|
|
|
|
const freeExtend = async () => {
|
|
|
|
|
|
try {
|
|
|
|
|
|
const { CompId, AppId, BranchId, UserType } = sessionData;
|
|
|
|
|
|
const UserId = getSession('UserId');
|
|
|
|
|
|
|
|
|
|
|
|
// Current date
|
|
|
|
|
|
const now = new Date();
|
|
|
|
|
|
const currentDate = formatDate(now);
|
|
|
|
|
|
|
|
|
|
|
|
// 1️⃣ Get purchased app details
|
|
|
|
|
|
const response1 = await dispatch(
|
|
|
|
|
|
getPurchasedAppDetails({ AppId, UserId })
|
|
|
|
|
|
).unwrap();
|
|
|
|
|
|
|
|
|
|
|
|
const PurchasedDetails = response1?.data?.data;
|
|
|
|
|
|
|
|
|
|
|
|
if (!PurchasedDetails || !PurchasedDetails.length) {
|
|
|
|
|
|
console.error('No purchased details found');
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 2️⃣ Prepare post data
|
|
|
|
|
|
const postData = {
|
|
|
|
|
|
UserId: UserId,
|
|
|
|
|
|
AppId: AppId,
|
|
|
|
|
|
PricingId: PurchasedDetails[0]?.PricingId,
|
|
|
|
|
|
PurDate: currentDate,
|
|
|
|
|
|
NoofDays: 30,
|
|
|
|
|
|
PaymentMode: 27,
|
|
|
|
|
|
PaymentStatus: 'S',
|
|
|
|
|
|
LicenseStatus: PurchasedDetails[0]?.LicenseStatus,
|
|
|
|
|
|
Price: PurchasedDetails[0]?.Price ?? 0,
|
|
|
|
|
|
TaxId: PurchasedDetails[0]?.TaxId ?? 0,
|
|
|
|
|
|
NetPrice: PurchasedDetails[0]?.ExistingPlanNetPrice ?? 0,
|
|
|
|
|
|
ValidityStart: currentDate,
|
|
|
|
|
|
ValidityEnd: addDays(
|
|
|
|
|
|
currentDate,
|
|
|
|
|
|
PurchasedDetails[0]?.NoOfDays
|
|
|
|
|
|
),
|
|
|
|
|
|
CreatedBy: UserId,
|
|
|
|
|
|
TaxAmount: PurchasedDetails[0]?.TaxAmount ?? 0,
|
|
|
|
|
|
MobileNo: getSession('MobileNo'),
|
|
|
|
|
|
MailId: 'ts@gmmail.com',
|
|
|
|
|
|
Type: "FreeExtend"
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// 3️⃣ Post invoice
|
|
|
|
|
|
const response = await dispatch(postInvoice(postData)).unwrap();
|
|
|
|
|
|
|
|
|
|
|
|
// 4️⃣ Send SMS if required
|
|
|
|
|
|
if (response?.data?.statusCode === 1 && response?.data?.SMSbody) {
|
|
|
|
|
|
await dispatch(
|
|
|
|
|
|
sendSms({ body: response.data.SMSbody })
|
|
|
|
|
|
);
|
|
|
|
|
|
setExtendModel(false)
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error('freeExtend error:', error);
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
const handleCancel = () => {
|
|
|
|
|
|
Logout();
|
|
|
|
|
|
setExtendModel(false)
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
const handlePay = () => {
|
|
|
|
|
|
setExtendModel(false)
|
|
|
|
|
|
let AppName = getSession("AppName")
|
|
|
|
|
|
navigate(`${subDirectory}PricingPage`, { state: { AppName: AppName } });
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (extendModel) {
|
|
|
|
|
|
return (
|
|
|
|
|
|
<ExtendSubscriptionModal
|
|
|
|
|
|
onClose={handleCancel}
|
|
|
|
|
|
onPayNow={handlePay}
|
|
|
|
|
|
onContinueWithCredits={freeExtend}
|
2026-01-27 18:27:29 +05:30
|
|
|
|
/>
|
2026-02-11 12:09:36 +05:30
|
|
|
|
);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
|
<>
|
|
|
|
|
|
<Routes>
|
|
|
|
|
|
<Route
|
|
|
|
|
|
path={`${subDirectory}selfBooking/:SelfBookingId`}
|
|
|
|
|
|
element={<SelfBooking />}
|
|
|
|
|
|
/>
|
|
|
|
|
|
<Route
|
|
|
|
|
|
path={`${subDirectory}MenuQRCode`}
|
|
|
|
|
|
element={<CustomerMenuPage />}
|
|
|
|
|
|
/>
|
|
|
|
|
|
<Route
|
|
|
|
|
|
path={`${subDirectory}weightscaleapp`}
|
|
|
|
|
|
element={<WeightScaleApp />}
|
|
|
|
|
|
/>
|
|
|
|
|
|
<Route path={`${subDirectory}kioskSelfBooking`} element={<KisokSelBooking />} />
|
2026-01-27 18:27:29 +05:30
|
|
|
|
|
2026-02-11 12:09:36 +05:30
|
|
|
|
<Route
|
|
|
|
|
|
path={`${subDirectory}kiosk-individual-self-booking`}
|
|
|
|
|
|
element={<IndividualBooking />}
|
|
|
|
|
|
/>
|
|
|
|
|
|
<Route
|
|
|
|
|
|
path="/*"
|
|
|
|
|
|
element={<ProtectedRoutes routesConfig={routesConfig} />}
|
|
|
|
|
|
/>
|
|
|
|
|
|
</Routes>
|
|
|
|
|
|
</>
|
2026-01-27 18:27:29 +05:30
|
|
|
|
);
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
export default AppRoutes;
|