import { Suspense, lazy } from 'react';
import AppToaster from '@/components/third-party/AppToaster';
import { QueryClientProvider } from '@tanstack/react-query';
import { queryClientInstance } from '@/lib/query-client';
import { Navigate, BrowserRouter as Router, Route, Routes } from 'react-router-dom';
import PageNotFound from './lib/PageNotFound';
import { AuthProvider, useAuth } from '@/lib/AuthContext';
import { ZoneProvider } from '@/lib/ZoneContext';
import ScrollToTop from './components/ScrollToTop';
import ProtectedRoute from '@/components/ProtectedRoute';
import AdminLayout from '@/layouts/AdminLayout';
import Login from '@/pages/Login';
/* Every console page is code-split. The Dispatch board alone pulls the map,
the solver payload builders and the comparison panels; loading that on the
way to the Hubs table would make every first paint pay for it. */
/* Doormile-only pages. A client login is sent home rather than shown a page
whose every request the server refuses. */
function StaffOnly({ children }) {
const { isClient } = useAuth();
return isClient ? : children;
}
const Dispatch = lazy(() => import('@/pages/doormile/dispatch/Dispatch.jsx'));
const DispatchPreview = lazy(() => import('@/pages/doormile/dispatch/Preview.jsx'));
const Home = lazy(() => import('@/pages/doormile/home/Home.jsx'));
const Orders = lazy(() => import('@/pages/doormile/orders/Orders'));
const Bookings = lazy(() => import('@/pages/doormile/bookings/Bookings'));
const OrdersPreview = lazy(() => import('@/pages/doormile/orders/OrdersPreview'));
const CreateOrder = lazy(() => import('@/pages/doormile/orders/CreateOrder'));
const MultipleOrders = lazy(() => import('@/pages/doormile/orders/MultipleOrders'));
const Deliveries = lazy(() => import('@/pages/doormile/deliveries/Deliveries'));
const Returns = lazy(() => import('@/pages/doormile/returns/Returns'));
const Tenants = lazy(() => import('@/pages/doormile/clients/Tenants'));
const CreateClient = lazy(() => import('@/pages/doormile/clients/CreateClient'));
const ClientOnboarding = lazy(() => import('@/pages/doormile/clients/ClientOnboarding'));
const CreateCustomer = lazy(() => import('@/pages/doormile/clients/CreateCustomer'));
const Pricing = lazy(() => import('@/pages/doormile/pricing/Pricing'));
const Riders = lazy(() => import('@/pages/doormile/riders/Riders'));
const CreateRider = lazy(() => import('@/pages/doormile/riders/CreateRider'));
const EditRider = lazy(() => import('@/pages/doormile/riders/EditRider'));
const Customers = lazy(() => import('@/pages/doormile/customers/Customers'));
const Hubs = lazy(() => import('@/pages/doormile/hubs/Hubs'));
const Vehicles = lazy(() => import('@/pages/doormile/vehicles/Vehicles'));
const AppUsers = lazy(() => import('@/pages/doormile/appUsers/AppUsers'));
const Tripsheets = lazy(() => import('@/pages/doormile/tripsheets/Tripsheets'));
const Exceptions = lazy(() => import('@/pages/doormile/exceptions/Exceptions'));
const CompetitiveIntel = lazy(() => import('@/pages/doormile/competitiveIntel/CompetitiveIntel'));
const OrdersSummary = lazy(() => import('@/pages/doormile/reports/OrdersSummary'));
const OrdersDetails = lazy(() => import('@/pages/doormile/reports/OrdersDetails'));
const RidersSummary = lazy(() => import('@/pages/doormile/reports/RidersSummary'));
const Profitability = lazy(() => import('@/pages/doormile/reports/Profitability'));
const ViewProfile = lazy(() => import('@/pages/doormile/ViewProfile'));
const Settings = lazy(() => import('@/pages/doormile/settings/Settings'));
const Agents = lazy(() => import('@/pages/doormile/agents/Agents'));
const PageFallback = () => (
);
const AuthenticatedApp = () => {
const { isLoadingAuth, isLoadingPublicSettings } = useAuth();
if (isLoadingPublicSettings || isLoadingAuth) {
return (
);
}
return (
}>
{/* Sign-in — outside the protected boundary. */}
} />
}>
{/* Dispatch is the console's home: it is the board operators sit on
all day, and the one page that answers "what is happening right
now" without a filter being set first. */}
} />
} />
} />
} />
}>
} />
} />
{/* Control X — the board formerly routed at /doormile/dispatch.
The directory, the component and the .dispatch-container CSS
namespace keep their old names on purpose: they are internal,
and renaming a 5,800-line stylesheet's root class is a large
diff with no user-visible benefit and real risk of missing a
selector. Only what an operator sees and types changes. */}
} />
} />
{/* The old paths keep working.
This board is the page operators sit on all day, so it is the
one most likely to be bookmarked, pinned in a browser tab
group, or pasted into a message. Renaming the route without
this would turn every one of those into a 404 — a support
problem with no upside, avoided by two lines. `replace` so the
dead path does not linger in history behind a Back press. */}
} />
} />
{/* Static before dynamic, so `orders/create` cannot be read as an
order whose id is "create". */}
} />
} />
} />
} />
} />
} />
} />
{/* Reverse logistics: parcels going back to the sender (RTO). */}
} />
} />
} />
{/* Owner-only (admin@doormile.com); the page and the server both check. */}
} />
} />
} />
} />
} />
} />
{/* Backwards-compatible aliases */}
} />
} />
} />
} />
} />
} />
} />
} />
} />
} />
} />
} />
} />
} />
} />
} />
{/* The AI_engine swarm. Read-only: it reports what the agents are
and what they last did, and has no control surface, because
every autonomy gate lives in that repository's own env. */}
} />
} />
);
};
function App() {
return (
{/* Every toast in the app (OpenToast, the design system's `toast`,
direct react-hot-toast calls) renders here: top-right, one card
design. Without a mounted renderer every toast fires into
nothing — including the data layer's failure notices. */}
);
}
export default App;