2026-03-09 10:43:17 +05:30
|
|
|
import { useEffect, lazy, Suspense, useRef, useState } from 'react';
|
2026-02-24 17:39:01 +05:30
|
|
|
import { useLocation, useNavigate } from 'react-router-dom';
|
|
|
|
|
import { App as CapacitorApp } from '@capacitor/app';
|
2026-01-27 18:27:29 +05:30
|
|
|
import { Routes, Route } from 'react-router-dom';
|
2026-02-10 16:35:19 +05:30
|
|
|
import { useSelector } from 'react-redux';
|
2026-01-27 18:27:29 +05:30
|
|
|
import ProtectedRoutes from './ProtectedRoutes';
|
2026-02-24 17:39:01 +05:30
|
|
|
import SelfBooking from './Pages/SelfBooking/SelfBooking.jsx';
|
2026-02-10 16:35:19 +05:30
|
|
|
import { isMobile, isIOS } from 'react-device-detect';
|
2026-01-27 18:27:29 +05:30
|
|
|
import { routesConfig } from './routesConfig';
|
2026-02-10 16:35:19 +05:30
|
|
|
import { GlobalItemCard } from './Features/BookingScreen/BookingData/BookingData.js';
|
|
|
|
|
import { clearSession, getSession } from './Services/Others.js';
|
2026-02-23 12:18:31 +05:30
|
|
|
|
2026-02-25 16:24:29 +05:30
|
|
|
const KisokSelBooking = lazy(
|
|
|
|
|
() => import('./Pages/SelfBooking/KisokSelBooking')
|
|
|
|
|
);
|
|
|
|
|
const IndividualBooking = lazy(
|
|
|
|
|
() => import('./Pages/SelfBooking/IndividualBooking')
|
|
|
|
|
);
|
2026-02-23 12:18:31 +05:30
|
|
|
|
2026-01-27 18:27:29 +05:30
|
|
|
const commonSubDir = import.meta.env.ENV_COMMON_BASE_URL;
|
|
|
|
|
const subDirectory = import.meta.env.ENV_BASE_URL;
|
2026-02-10 16:35:19 +05:30
|
|
|
import '../ownLib/my-ui-lib.css';
|
2026-02-24 17:39:01 +05:30
|
|
|
import CustomerMenuPage from './Pages/Reports/MenuQRCode/CustomerMenuPage.jsx';
|
|
|
|
|
import WeightScaleApp from './Pages/BookingScreen/WeightscaleApp.jsx';
|
|
|
|
|
import useSubscriptionManager from './useSubscriptionManager.js';
|
|
|
|
|
import useSessionManager from './useSessionManager.js';
|
|
|
|
|
import ExtendSubscriptionModal from './Pages/ExtentedModal/ExtendSubscriptionModal.jsx';
|
2026-02-27 10:50:36 +05:30
|
|
|
import devtools from 'devtools-detect';
|
2026-02-24 17:39:01 +05:30
|
|
|
|
2026-02-25 16:24:29 +05:30
|
|
|
const isCapacitor = () => !!window.Capacitor?.isNativePlatform?.();
|
2026-02-24 17:39:01 +05:30
|
|
|
|
|
|
|
|
// ✅ Define your home/exit pages here
|
|
|
|
|
const HOME_PAGES = [
|
2026-03-09 15:10:14 +05:30
|
|
|
'/app-page/home', // android minimize
|
2026-03-09 18:12:07 +05:30
|
|
|
'/apps/retail/app-page/home',
|
2026-03-13 16:31:12 +05:30
|
|
|
'/', // android minimize
|
2026-02-24 17:39:01 +05:30
|
|
|
];
|
|
|
|
|
|
|
|
|
|
const LOGIN_PAGES = ['signin', 'login', 'auth'];
|
2026-02-11 12:45:21 +05:30
|
|
|
|
2026-01-27 18:27:29 +05:30
|
|
|
const AppRoutes = () => {
|
|
|
|
|
const ItemCard = useSelector(GlobalItemCard);
|
2026-02-11 15:27:50 +05:30
|
|
|
const { sessionData, logout } = useSessionManager(ItemCard);
|
2026-02-25 16:24:29 +05:30
|
|
|
const {
|
|
|
|
|
remainingDays,
|
|
|
|
|
handleCancel,
|
|
|
|
|
freeExtend,
|
|
|
|
|
extendModel,
|
|
|
|
|
handlePay,
|
|
|
|
|
setExtendModel,
|
|
|
|
|
} = useSubscriptionManager(sessionData, logout);
|
2026-02-24 17:39:01 +05:30
|
|
|
const location = useLocation();
|
|
|
|
|
const navigate = useNavigate();
|
2026-03-09 10:43:17 +05:30
|
|
|
const [devToolsOpen, setDevToolsOpen] = useState(false);
|
2026-02-24 17:39:01 +05:30
|
|
|
// ✅ Flag to prevent stack push when back button navigates
|
|
|
|
|
const isBackNav = useRef(false);
|
2026-02-10 16:35:19 +05:30
|
|
|
|
2026-02-24 17:39:01 +05:30
|
|
|
// ✅ Build navigation stack
|
2026-01-27 18:27:29 +05:30
|
|
|
useEffect(() => {
|
2026-02-24 17:39:01 +05:30
|
|
|
// Skip pushing to stack when back button caused this navigation
|
|
|
|
|
if (isBackNav.current) {
|
|
|
|
|
isBackNav.current = false;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
const path = location.pathname + (location.search || '');
|
|
|
|
|
|
|
|
|
|
// Don't track login pages
|
2026-02-25 16:24:29 +05:30
|
|
|
if (LOGIN_PAGES.some((p) => path.includes(p))) return;
|
2026-02-24 17:39:01 +05:30
|
|
|
|
|
|
|
|
const raw = sessionStorage.getItem('navStack');
|
|
|
|
|
let stack = raw ? JSON.parse(raw) : [];
|
|
|
|
|
|
|
|
|
|
if (stack.length === 0 || stack[stack.length - 1] !== path) {
|
|
|
|
|
stack.push(path);
|
|
|
|
|
if (stack.length > 50) stack = stack.slice(-50);
|
|
|
|
|
sessionStorage.setItem('navStack', JSON.stringify(stack));
|
|
|
|
|
console.log('📍 Stack:', stack);
|
|
|
|
|
}
|
|
|
|
|
} catch (e) {}
|
|
|
|
|
}, [location.pathname, location.search]);
|
|
|
|
|
|
|
|
|
|
// ✅ Web — block browser back button
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
if (isCapacitor()) return; // Android handled separately
|
|
|
|
|
|
2026-02-10 16:35:19 +05:30
|
|
|
const handlePopState = () => {
|
2026-02-24 17:39:01 +05:30
|
|
|
const currentPath = location.pathname;
|
|
|
|
|
|
2026-03-09 18:12:07 +05:30
|
|
|
const SessionId = getSession('SessionId');
|
|
|
|
|
|
|
|
|
|
// 🟢 If session exists → allow navigation
|
|
|
|
|
if (SessionId) {
|
2026-03-13 16:31:12 +05:30
|
|
|
console.log('Browser back allowed');
|
2026-02-24 17:39:01 +05:30
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-09 18:12:07 +05:30
|
|
|
// 🔴 Only redirect if user is on protected page
|
2026-03-13 16:31:12 +05:30
|
|
|
if (!LOGIN_PAGES.some((p) => currentPath.includes(p))) {
|
|
|
|
|
console.log('Session missing → redirecting login');
|
2026-01-27 18:27:29 +05:30
|
|
|
clearSession();
|
|
|
|
|
window.location.replace(`${commonSubDir}`);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2026-02-24 18:18:58 +05:30
|
|
|
// Add event listener on mount
|
2026-01-27 18:27:29 +05:30
|
|
|
window.addEventListener('popstate', handlePopState);
|
2026-03-09 18:12:07 +05:30
|
|
|
|
2026-02-24 17:39:01 +05:30
|
|
|
return () => window.removeEventListener('popstate', handlePopState);
|
|
|
|
|
}, [location.pathname]);
|
2026-01-27 18:27:29 +05:30
|
|
|
|
2026-02-24 17:39:01 +05:30
|
|
|
// ✅ Android — Capacitor back button
|
|
|
|
|
useEffect(() => {
|
2026-03-09 18:12:07 +05:30
|
|
|
if (!isCapacitor()) return;
|
2026-02-25 16:24:29 +05:30
|
|
|
|
2026-03-09 18:12:07 +05:30
|
|
|
const handler = async () => {
|
2026-03-13 16:31:12 +05:30
|
|
|
try {
|
|
|
|
|
const currentPath = location.pathname + (location.search || '');
|
|
|
|
|
console.log('🔙 Back pressed:', currentPath);
|
2026-02-25 16:24:29 +05:30
|
|
|
|
2026-03-13 16:31:12 +05:30
|
|
|
const raw = sessionStorage.getItem('navStack');
|
|
|
|
|
let stack = raw ? JSON.parse(raw) : [];
|
2026-02-25 16:24:29 +05:30
|
|
|
|
2026-03-09 18:12:07 +05:30
|
|
|
// Remove current path from stack if it's at the end
|
2026-03-13 16:31:12 +05:30
|
|
|
while (stack.length && stack[stack.length - 1] === currentPath) {
|
|
|
|
|
stack.pop();
|
|
|
|
|
}
|
2026-02-25 16:24:29 +05:30
|
|
|
|
2026-03-09 18:12:07 +05:30
|
|
|
// If there are pages in history, go back to previous page
|
|
|
|
|
if (stack.length > 0) {
|
2026-03-13 16:31:12 +05:30
|
|
|
const previous = stack[stack.length - 1];
|
2026-03-09 18:12:07 +05:30
|
|
|
sessionStorage.setItem('navStack', JSON.stringify(stack));
|
2026-03-13 16:31:12 +05:30
|
|
|
isBackNav.current = true;
|
2026-03-09 18:12:07 +05:30
|
|
|
navigate(previous);
|
|
|
|
|
console.log('Navigate to previous:', previous);
|
2026-03-13 16:31:12 +05:30
|
|
|
return;
|
|
|
|
|
}
|
2026-02-25 16:24:29 +05:30
|
|
|
|
2026-03-09 18:12:07 +05:30
|
|
|
// Stack is empty - check where we are
|
|
|
|
|
// 🏠 Home page → minimize
|
|
|
|
|
if (HOME_PAGES?.some((p) => currentPath?.includes(p))) {
|
2026-03-13 16:31:12 +05:30
|
|
|
console.log('Home page & empty stack → minimizing app');
|
2026-03-09 18:12:07 +05:30
|
|
|
await CapacitorApp.minimizeApp();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 🚪 Login page → minimize
|
|
|
|
|
if (LOGIN_PAGES?.some((p) => currentPath?.includes(p))) {
|
2026-03-13 16:31:12 +05:30
|
|
|
console.log('Login page & empty stack → minimizing app');
|
2026-03-09 18:12:07 +05:30
|
|
|
await CapacitorApp.minimizeApp();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Anywhere else with empty stack → go to home
|
|
|
|
|
const home = '/app-page/home';
|
2026-03-13 16:31:12 +05:30
|
|
|
sessionStorage.setItem('navStack', JSON.stringify([home]));
|
|
|
|
|
isBackNav.current = true;
|
|
|
|
|
navigate(home);
|
2026-03-09 18:12:07 +05:30
|
|
|
console.log('Empty stack, navigate to home');
|
|
|
|
|
} catch (e) {
|
|
|
|
|
console.error('Back handler error:', e);
|
|
|
|
|
await CapacitorApp.minimizeApp();
|
2026-02-24 17:39:01 +05:30
|
|
|
}
|
2026-01-27 18:27:29 +05:30
|
|
|
};
|
|
|
|
|
|
2026-03-09 18:12:07 +05:30
|
|
|
const listener = CapacitorApp.addListener('backButton', handler);
|
2026-01-27 18:27:29 +05:30
|
|
|
|
2026-02-24 17:39:01 +05:30
|
|
|
return () => {
|
2026-03-09 18:12:07 +05:30
|
|
|
listener.remove();
|
2026-02-24 17:39:01 +05:30
|
|
|
};
|
|
|
|
|
}, [navigate, location.pathname, location.search]);
|
2026-03-09 10:43:17 +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);
|
2026-02-27 10:50:36 +05:30
|
|
|
}
|
2026-03-09 10:43:17 +05:30
|
|
|
}
|
|
|
|
|
}, 1000);
|
|
|
|
|
|
|
|
|
|
return () => clearInterval(checkDevTools);
|
|
|
|
|
}, [devToolsOpen]);
|
2026-02-11 12:09:36 +05:30
|
|
|
if (extendModel) {
|
|
|
|
|
return (
|
|
|
|
|
<ExtendSubscriptionModal
|
|
|
|
|
onClose={handleCancel}
|
2026-02-23 12:18:31 +05:30
|
|
|
onPayNow={handlePay}
|
|
|
|
|
onContinueWithCredits={freeExtend}
|
2026-03-16 15:05:57 +05:30
|
|
|
setExtendModel={setExtendModel}
|
2026-01-27 18:27:29 +05:30
|
|
|
/>
|
2026-02-11 12:09:36 +05:30
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
return (
|
2026-03-09 10:43:17 +05:30
|
|
|
<Suspense fallback={null}>
|
2026-02-11 12:09:36 +05:30
|
|
|
<Routes>
|
|
|
|
|
<Route
|
|
|
|
|
path={`${subDirectory}selfBooking/:SelfBookingId`}
|
|
|
|
|
element={<SelfBooking />}
|
|
|
|
|
/>
|
|
|
|
|
<Route
|
|
|
|
|
path={`${subDirectory}MenuQRCode`}
|
|
|
|
|
element={<CustomerMenuPage />}
|
|
|
|
|
/>
|
|
|
|
|
<Route
|
|
|
|
|
path={`${subDirectory}weightscaleapp`}
|
|
|
|
|
element={<WeightScaleApp />}
|
|
|
|
|
/>
|
2026-02-10 16:35:19 +05:30
|
|
|
<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-02-10 16:35:19 +05:30
|
|
|
</Suspense>
|
2026-01-27 18:27:29 +05:30
|
|
|
);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export default AppRoutes;
|