diff --git a/src/App.jsx b/src/App.jsx index 9bc0579..6ea87ea 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -1,47 +1,88 @@ -import { useEffect, lazy, Suspense } from 'react'; +import { useEffect, lazy, Suspense, useRef } from 'react'; +import { useLocation, useNavigate } from 'react-router-dom'; +import { App as CapacitorApp } from '@capacitor/app'; import { Routes, Route } from 'react-router-dom'; import { useSelector } from 'react-redux'; import ProtectedRoutes from './ProtectedRoutes'; +import SelfBooking from './Pages/SelfBooking/SelfBooking.jsx'; import { isMobile, isIOS } from 'react-device-detect'; import { routesConfig } from './routesConfig'; import { GlobalItemCard } from './Features/BookingScreen/BookingData/BookingData.js'; import { clearSession, getSession } from './Services/Others.js'; -import devtools from 'devtools-detect'; -const KisokSelBooking = lazy( - () => import('./Pages/SelfBooking/KisokSelBooking') -); -const IndividualBooking = lazy( - () => import('./Pages/SelfBooking/IndividualBooking') -); - -const CustomerMenuPage = lazy( - () => import('./Pages/Reports/MenuQRCode/CustomerMenuPage.jsx') -); -const WeightScaleApp = lazy( - () => import('./Pages/BookingScreen/WeightscaleApp.jsx') -); -const SelfBooking = lazy(() => import('./Pages/SelfBooking/SelfBooking.jsx')); - -import useSessionManager from './useSessionManager.js'; -import useSubscriptionManager from './useSubscriptionManager.js'; -const ExtendSubscriptionModal = lazy( - () => import('./Pages/ExtentedModal/ExtendSubscriptionModal.jsx') -); +const KisokSelBooking = lazy(() => import('./Pages/SelfBooking/KisokSelBooking')); +const IndividualBooking = lazy(() => import('./Pages/SelfBooking/IndividualBooking')); const commonSubDir = import.meta.env.ENV_COMMON_BASE_URL; const subDirectory = import.meta.env.ENV_BASE_URL; + import '../ownLib/my-ui-lib.css'; -import CardSkeleton from './Components/Skeleton/CardSkeleton.jsx'; +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'; + +const isCapacitor = () => !!(window.Capacitor?.isNativePlatform?.()); + +// ✅ Define your home/exit pages here +const HOME_PAGES = [ + '/landing-page/home', + '/home/landing-page/home', + 'app-page/home', // android minimize +]; + +const LOGIN_PAGES = ['signin', 'login', 'auth']; const AppRoutes = () => { const ItemCard = useSelector(GlobalItemCard); const { sessionData, logout } = useSessionManager(ItemCard); - const { remainingDays, handleCancel, handlePay, freeExtend, extendModel } = - useSubscriptionManager(sessionData, logout); + const { remainingDays, handleCancel, freeExtend, extendModel, setExtendModel } = useSubscriptionManager(sessionData, logout); + const location = useLocation(); + const navigate = useNavigate(); + // ✅ Flag to prevent stack push when back button navigates + const isBackNav = useRef(false); + + // ✅ Build navigation stack 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 + if (LOGIN_PAGES.some(p => path.includes(p))) return; + + 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 + const handlePopState = () => { + const currentPath = location.pathname; + + // On home page — just stay, don't redirect + if (HOME_PAGES.some(p => currentPath.includes(p))) { + window.history.go(1); // stay here + return; + } + const SessionId = getSession('SessionId'); if (!SessionId) { alert( @@ -50,30 +91,91 @@ const AppRoutes = () => { clearSession(); window.location.replace(`${commonSubDir}`); } else { - window.history.go(1); + window.history.go(1); // block back on web } }; - // Add event listener on mount window.addEventListener('popstate', handlePopState); + return () => window.removeEventListener('popstate', handlePopState); + }, [location.pathname]); - // Clean up the event listener on unmount - return () => { - window.removeEventListener('popstate', handlePopState); + // ✅ Android — Capacitor back button + useEffect(() => { + if (!isMobile && !isIOS && !isCapacitor()) return; + + const handler = async () => { + try { + const currentPath = location.pathname + (location.search || ''); + console.log('🔙 Back pressed:', currentPath); + + // ✅ On home page + if (HOME_PAGES.some(p => currentPath.includes(p))) { + if (isCapacitor()) { + console.log('📱 Minimizing app'); + await CapacitorApp.minimizeApp(); // minimize — not exit + } + return; + } + + // ✅ On login page → exit app + if (LOGIN_PAGES.some(p => currentPath.includes(p))) { + console.log('🚪 Exiting app'); + if (isCapacitor()) await CapacitorApp.exitApp(); + return; + } + + // ✅ Get stack and go back one by one + const raw = sessionStorage.getItem('navStack'); + let stack = raw ? JSON.parse(raw) : []; + + // Remove current path from top + while (stack.length > 0 && stack[stack.length - 1] === currentPath) { + stack.pop(); + } + + if (stack.length > 0) { + const previous = stack[stack.length - 1]; + + // If previous is login → go to home instead + if (LOGIN_PAGES.some(p => previous.includes(p))) { + console.log('⬅️ Previous was login → going home'); + const home = '/landing-page/home'; + sessionStorage.setItem('navStack', JSON.stringify([home])); + isBackNav.current = true; + navigate(home); + return; + } + + console.log('⬅️ Back to:', previous); + sessionStorage.setItem('navStack', JSON.stringify(stack)); + isBackNav.current = true; // ✅ Prevent loop + navigate(previous); + + } else { + // Stack empty → go home + const home = '/landing-page/home'; + console.log('📭 Stack empty → home'); + sessionStorage.setItem('navStack', JSON.stringify([home])); + isBackNav.current = true; + navigate(home); + } + } catch (e) { + console.error('Back error:', e); + navigate('/landing-page/home'); + } }; - }, []); - // useEffect(() => { - // if (isMobile || isIOS) return; - // const timer = setInterval(() => { - // if (devtools.isOpen) { - // document.body.innerHTML = - // "

Close Inspect to continue

"; - // } - // }, 1000); + let listener; + try { + listener = CapacitorApp.addListener('backButton', handler); + } catch (e) {} - // return () => clearInterval(timer); - // }, []); + return () => { + try { + if (listener?.remove) listener.remove(); + } catch (e) {} + }; + }, [navigate, location.pathname, location.search]); if (extendModel) { return ( @@ -84,6 +186,7 @@ const AppRoutes = () => { /> ); } + return ( }>