Android_Retail/src/App.jsx

269 lines
8.3 KiB
React
Raw Normal View History

2026-03-09 10:43:17 +05:30
import { useEffect, lazy, Suspense, useRef, useState } from 'react';
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';
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';
2026-03-27 09:52:12 +05:30
import { clearSession, getSession, sessionStore } 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';
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';
import devtools from 'devtools-detect';
2026-03-27 09:52:12 +05:30
import { useDevToolsDetection } from './utils/useDevToolsDetection.js';
import { Capacitor } from '@capacitor/core';
2026-03-27 09:52:12 +05:30
// const isCapacitor = () => !!window.Capacitor?.isNativePlatform?.();
const isCapacitor = () => Capacitor.isNativePlatform();
// ✅ 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
];
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);
const location = useLocation();
const navigate = useNavigate();
2026-03-09 10:43:17 +05:30
const [devToolsOpen, setDevToolsOpen] = useState(false);
// ✅ Flag to prevent stack push when back button navigates
const isBackNav = useRef(false);
2026-03-27 09:52:12 +05:30
console.log(isCapacitor(), 'Is Capacitor');
// ✅ Build navigation stack
2026-01-27 18:27:29 +05:30
useEffect(() => {
// 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-03-27 09:52:12 +05:30
const raw = getSession('navStack');
console.log('🎯 Current path:', path);
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);
2026-03-27 09:52:12 +05:30
sessionStore('navStack', JSON.stringify(stack));
console.log('📍 Stack:', stack);
}
2026-03-20 14:40:49 +05:30
} 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 = () => {
const currentPath = location.pathname;
2026-03-09 18:12:07 +05:30
const SessionId = getSession('SessionId');
2026-03-27 09:52:12 +05:30
console.log('SessionId:', SessionId, 'CurrentPath:', currentPath)
2026-03-09 18:12:07 +05:30
// 🟢 If session exists → allow navigation
if (SessionId) {
2026-03-13 16:31:12 +05:30
console.log('Browser back allowed');
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}`);
}
};
// 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
return () => window.removeEventListener('popstate', handlePopState);
}, [location.pathname]);
2026-01-27 18:27:29 +05:30
// ✅ Android — Capacitor back button
2026-03-27 09:52:12 +05:30
useEffect(() => {
if (!isCapacitor()) return;
2026-01-27 18:27:29 +05:30
2026-03-27 09:52:12 +05:30
const handler = async () => {
try {
const currentPath = window.location.pathname + window.location.search; // Bug 2 fix
2026-01-27 18:27:29 +05:30
2026-03-27 09:52:12 +05:30
const raw = getSession('navStack');
let stack = raw ? JSON.parse(raw) : [];
2026-03-27 09:52:12 +05:30
while (stack.length && stack[stack.length - 1] === currentPath) {
stack.pop();
}
2026-03-27 09:52:12 +05:30
if (stack.length > 0) {
const previous = stack[stack.length - 1];
sessionStore('navStack', JSON.stringify(stack));
isBackNav.current = true; // Bug 3 fix — BEFORE navigate
navigate(previous);
return;
}
2026-03-27 09:52:12 +05:30
if (HOME_PAGES?.some((p) => currentPath?.includes(p))) {
await CapacitorApp.minimizeApp();
return;
}
2026-03-27 09:52:12 +05:30
if (LOGIN_PAGES?.some((p) => currentPath?.includes(p))) {
await CapacitorApp.minimizeApp();
return;
}
2026-03-27 09:52:12 +05:30
const home = '/app-page/home';
isBackNav.current = true; // Bug 3 fix here too
sessionStore('navStack', JSON.stringify([home]));
navigate(home);
} catch (e) {
console.error('Back handler error:', e);
await CapacitorApp.minimizeApp();
}
};
2026-03-27 09:52:12 +05:30
const listenerPromise = CapacitorApp.addListener('backButton', handler); // Bug 1 fix
return () => {
listenerPromise.then(({ remove }) => remove());
};
}, [navigate,location.pathname, location.search]);
// 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 isBlocked = useDevToolsDetection(() => {
// // optional: log, notify, etc.
// console.warn('DevTools detected');
// });
// if (isBlocked) {
// return (
// <div style={{
// display: 'flex',
// justifyContent: 'center',
// alignItems: 'center',
// height: '100vh',
// flexDirection: 'column',
// gap: '1rem'
// }}>
// <h1 style={{ color: 'red' }}>
// DevTools detected. Please close it to continue.
// </h1>
// </div>
// );
// }
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}
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;