updates on the ui changes and changed into doormile
This commit is contained in:
236
src/App.jsx
236
src/App.jsx
@@ -1,67 +1,59 @@
|
||||
import { Toaster } from "@/components/ui/toaster"
|
||||
import { Suspense, lazy } from 'react';
|
||||
import { Toaster } from '@/components/ui/toaster';
|
||||
import { Toaster as HotToaster } from 'react-hot-toast';
|
||||
import { QueryClientProvider } from '@tanstack/react-query'
|
||||
import { queryClientInstance } from '@/lib/query-client'
|
||||
import { Navigate, BrowserRouter as Router, Route, Routes, useParams } from 'react-router-dom';
|
||||
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 ScrollToTop from './components/ScrollToTop';
|
||||
import ProtectedRoute from '@/components/ProtectedRoute';
|
||||
import Layout from '@/layouts/Layout';
|
||||
import Overview from '@/pages/Overview';
|
||||
import Positions from '@/pages/Positions';
|
||||
import PositionDetail from '@/pages/PositionDetail';
|
||||
import Candidates from '@/pages/Candidates';
|
||||
import HiredHistory from '@/pages/HiredHistory';
|
||||
import TalentPool from '@/pages/TalentPool';
|
||||
import Apply from '@/pages/Apply';
|
||||
import UserTracking from '@/pages/UserTracking';
|
||||
import Analytics from '@/pages/Analytics';
|
||||
import CreatePosition from '@/pages/CreatePosition';
|
||||
import Profile from '@/pages/Profile';
|
||||
import University from '@/pages/University';
|
||||
import CourseDetail from '@/pages/CourseDetail';
|
||||
import WorkerProfile from '@/pages/WorkerProfile';
|
||||
import KrowIdentity from '@/pages/KrowIdentity';
|
||||
import Owliver from '@/pages/Owliver';
|
||||
import EmployeeDashboard from '@/pages/EmployeeDashboard';
|
||||
import DesignSystem from '@/pages/DesignSystem';
|
||||
|
||||
/* Admin product — its own layout and route tree, so the Admin redesign can
|
||||
diverge without touching the Employer or Talent experiences. */
|
||||
import AdminLayout from '@/layouts/AdminLayout';
|
||||
import ControlCenter from '@/pages/admin/ControlCenter';
|
||||
import AdminPositions from '@/pages/admin/Positions';
|
||||
import AdminCandidates from '@/pages/admin/Candidates';
|
||||
import AdminCandidateProfile from '@/pages/admin/CandidateProfile';
|
||||
import AdminCandidatesAnalysis from '@/pages/admin/CandidatesAnalysis';
|
||||
import AdminHiredHistory from '@/pages/admin/HiredHistory';
|
||||
import AdminTalentPool from '@/pages/admin/TalentPool';
|
||||
import AdminAnalytics from '@/pages/admin/Analytics';
|
||||
import AdminActivity from '@/pages/admin/Activity';
|
||||
import AdminProfile from '@/pages/admin/Profile';
|
||||
import AdminSettings from '@/pages/admin/Settings';
|
||||
import AdminWorkspace from '@/pages/admin/Workspace';
|
||||
import AdminWorkspaceSkills from '@/pages/admin/WorkspaceSkills';
|
||||
import AdminWorkspaceAgents from '@/pages/admin/WorkspaceAgents';
|
||||
import AdminAgentDetail from '@/pages/admin/AgentDetail';
|
||||
import AdminSkillEditor from '@/pages/admin/SkillEditor';
|
||||
import AdminOwliverSkillEditor from '@/pages/admin/OwliverSkillEditor';
|
||||
import AdminSkillDevelopment from '@/pages/admin/SkillDevelopment';
|
||||
import AdminLogin from '@/pages/admin/Login';
|
||||
import AdminRoute from '@/pages/admin/AdminRoute';
|
||||
import Login from '@/pages/Login';
|
||||
|
||||
/** `/university/:id` → the same challenge inside the Admin shell, id preserved. */
|
||||
const LegacyCourseRedirect = () => {
|
||||
const { id } = useParams();
|
||||
return <Navigate to={`/admin/university/${id}`} replace />;
|
||||
};
|
||||
/* 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. */
|
||||
const Dispatch = lazy(() => import('@/pages/doormile/dispatch/Dispatch.jsx'));
|
||||
const DispatchPreview = lazy(() => import('@/pages/doormile/dispatch/Preview.jsx'));
|
||||
|
||||
/** `/positions/:id` → the same position inside the Admin shell, id preserved. */
|
||||
const LegacyPositionRedirect = () => {
|
||||
const { id } = useParams();
|
||||
return <Navigate to={`/admin/positions/${id}`} replace />;
|
||||
};
|
||||
const Orders = lazy(() => import('@/pages/doormile/orders/Orders'));
|
||||
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 Tenants = lazy(() => import('@/pages/doormile/clients/Tenants'));
|
||||
const CreateClient = lazy(() => import('@/pages/doormile/clients/CreateClient'));
|
||||
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 PageFallback = () => (
|
||||
<div className="flex min-h-[60vh] items-center justify-center">
|
||||
<div className="h-8 w-8 animate-spin rounded-full border-4 border-slate-200 border-t-slate-800" />
|
||||
</div>
|
||||
);
|
||||
|
||||
const AuthenticatedApp = () => {
|
||||
const { isLoadingAuth, isLoadingPublicSettings } = useAuth();
|
||||
@@ -75,83 +67,62 @@ const AuthenticatedApp = () => {
|
||||
}
|
||||
|
||||
return (
|
||||
<Routes>
|
||||
{/* Admin sign-in — outside the protected boundary. */}
|
||||
<Route path="/admin/login" element={<AdminLogin />} />
|
||||
<Suspense fallback={<PageFallback />}>
|
||||
<Routes>
|
||||
{/* Sign-in — outside the protected boundary. */}
|
||||
<Route path="/login" element={<Login />} />
|
||||
|
||||
<Route element={<ProtectedRoute />}>
|
||||
{/* The application opens on the Admin console, which is entered through
|
||||
its own sign-in. Employer keeps every one of its routes, including
|
||||
Overview at an explicit path — nothing of that product is removed,
|
||||
only the address the app happens to start at. */}
|
||||
<Route path="/" element={<Navigate to="/admin/login" replace />} />
|
||||
<Route element={<ProtectedRoute />}>
|
||||
{/* 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. */}
|
||||
<Route path="/" element={<Navigate to="/doormile/dispatch" replace />} />
|
||||
|
||||
<Route element={<AdminRoute />}>
|
||||
<Route path="/admin" element={<AdminLayout />}>
|
||||
<Route index element={<ControlCenter />} />
|
||||
<Route path="positions" element={<AdminPositions />} />
|
||||
<Route path="positions/new" element={<CreatePosition />} />
|
||||
<Route path="positions/:id" element={<PositionDetail />} />
|
||||
<Route path="candidates" element={<AdminCandidates />} />
|
||||
{/* The full Candidate Intelligence profile. A page rather than a
|
||||
drawer: the record carries around forty fields and fifteen
|
||||
screening dimensions, which a 480px column cannot show without
|
||||
hiding most of it. */}
|
||||
<Route path="candidates/:id" element={<AdminCandidateProfile />} />
|
||||
<Route path="hired" element={<AdminHiredHistory />} />
|
||||
<Route path="talent-pool" element={<AdminTalentPool />} />
|
||||
<Route path="university" element={<University />} />
|
||||
<Route path="university/:id" element={<CourseDetail />} />
|
||||
<Route path="analytics" element={<AdminAnalytics />} />
|
||||
<Route path="activity" element={<AdminActivity />} />
|
||||
<Route path="profile" element={<AdminProfile />} />
|
||||
{/* Two centres, deliberately separate. Settings configures the
|
||||
account and the system; Workspace & Skills configures the
|
||||
workforce — Owliver's capabilities, training and progression —
|
||||
each with its own pages underneath rather than one page holding
|
||||
both subjects. */}
|
||||
<Route path="settings" element={<AdminSettings />} />
|
||||
<Route path="workspace" element={<AdminWorkspace />} />
|
||||
<Route path="workspace/agents" element={<AdminWorkspaceAgents />} />
|
||||
{/* Static before dynamic, so `agents/new` cannot be read as an
|
||||
agent whose id is "new". */}
|
||||
<Route path="workspace/agents/new" element={<AdminAgentDetail />} />
|
||||
<Route path="workspace/agents/:id" element={<AdminAgentDetail />} />
|
||||
<Route path="workspace/skills" element={<AdminWorkspaceSkills />} />
|
||||
{/* Two editors, because a UI skill and an Owliver skill configure
|
||||
different things. Static segments rank above the dynamic `:id`,
|
||||
so `skills/owliver/...` cannot be read as a skill called
|
||||
"owliver" — and the two original addresses are untouched. */}
|
||||
<Route path="workspace/skills/new" element={<AdminSkillEditor />} />
|
||||
<Route path="workspace/skills/owliver/new" element={<AdminOwliverSkillEditor />} />
|
||||
<Route path="workspace/skills/owliver/:id" element={<AdminOwliverSkillEditor />} />
|
||||
<Route path="workspace/skills/:id" element={<AdminSkillEditor />} />
|
||||
<Route path="workspace/skill-development" element={<AdminSkillDevelopment />} />
|
||||
<Route path="/doormile" element={<AdminLayout />}>
|
||||
<Route index element={<Navigate to="/doormile/dispatch" replace />} />
|
||||
|
||||
<Route path="dispatch" element={<Dispatch />} />
|
||||
<Route path="dispatch/preview" element={<DispatchPreview />} />
|
||||
|
||||
{/* Static before dynamic, so `orders/create` cannot be read as an
|
||||
order whose id is "create". */}
|
||||
<Route path="orders" element={<Orders />} />
|
||||
<Route path="orders/create" element={<CreateOrder />} />
|
||||
<Route path="orders/createorders" element={<MultipleOrders />} />
|
||||
<Route path="orders/preview" element={<OrdersPreview />} />
|
||||
|
||||
<Route path="deliveries" element={<Deliveries />} />
|
||||
|
||||
<Route path="tenants" element={<Tenants />} />
|
||||
<Route path="clients/create" element={<CreateClient />} />
|
||||
<Route path="customer/create" element={<CreateCustomer />} />
|
||||
|
||||
<Route path="pricing" element={<Pricing />} />
|
||||
|
||||
<Route path="riders" element={<Riders />} />
|
||||
<Route path="riders/create" element={<CreateRider />} />
|
||||
<Route path="riders/edit" element={<EditRider />} />
|
||||
|
||||
<Route path="customers" element={<Customers />} />
|
||||
<Route path="hubs" element={<Hubs />} />
|
||||
<Route path="vehicles" element={<Vehicles />} />
|
||||
<Route path="app-users" element={<AppUsers />} />
|
||||
<Route path="tripsheets" element={<Tripsheets />} />
|
||||
<Route path="exceptions" element={<Exceptions />} />
|
||||
<Route path="competitive-intel" element={<CompetitiveIntel />} />
|
||||
|
||||
<Route path="reports/orderssummary" element={<OrdersSummary />} />
|
||||
<Route path="reports/ordersdetails" element={<OrdersDetails />} />
|
||||
<Route path="reports/riderssummary" element={<RidersSummary />} />
|
||||
<Route path="reports/profitability" element={<Profitability />} />
|
||||
|
||||
<Route path="profile" element={<ViewProfile />} />
|
||||
</Route>
|
||||
</Route>
|
||||
|
||||
{/* Redirect top-level legacy aliases to the unified global shell */}
|
||||
<Route path="/overview" element={<Navigate to="/admin" replace />} />
|
||||
<Route path="/positions" element={<Navigate to="/admin/positions" replace />} />
|
||||
{/* `/positions` only matches the exact path, so the sub-routes need
|
||||
their own aliases or an inbound link lands on the 404 page. */}
|
||||
<Route path="/positions/new" element={<Navigate to="/admin/positions/new" replace />} />
|
||||
<Route path="/positions/:id" element={<LegacyPositionRedirect />} />
|
||||
<Route path="/candidates" element={<Navigate to="/admin/candidates" replace />} />
|
||||
<Route path="/hired" element={<Navigate to="/admin/hired" replace />} />
|
||||
<Route path="/talent-pool" element={<Navigate to="/admin/talent-pool" replace />} />
|
||||
<Route path="/university" element={<Navigate to="/admin/university" replace />} />
|
||||
{/* Same treatment as every other legacy alias: the challenge opens inside
|
||||
the application shell rather than on a bare page, so Forge → challenge
|
||||
keeps its navigation, header and page frame. Existing links to
|
||||
/university/:id are unchanged and still resolve here. */}
|
||||
<Route path="/university/:id" element={<LegacyCourseRedirect />} />
|
||||
<Route path="/analytics" element={<Navigate to="/admin/analytics" replace />} />
|
||||
<Route path="/activity" element={<Navigate to="/admin/activity" replace />} />
|
||||
<Route path="/tracking" element={<Navigate to="/admin/activity" replace />} />
|
||||
</Route>
|
||||
<Route path="*" element={<PageNotFound />} />
|
||||
</Routes>
|
||||
<Route path="*" element={<PageNotFound />} />
|
||||
</Routes>
|
||||
</Suspense>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -165,13 +136,12 @@ function App() {
|
||||
</Router>
|
||||
<Toaster />
|
||||
{/* The design system's `toast` helper wraps react-hot-toast, which needs
|
||||
its own renderer mounted. Without this every toast in the app fired
|
||||
into nothing — confirmations, errors and the "not in the demo"
|
||||
notices all silently did nothing. */}
|
||||
its own renderer mounted. Without this every toast in the app fires
|
||||
into nothing — including the data layer's failure notices. */}
|
||||
<HotToaster position="bottom-right" />
|
||||
</QueryClientProvider>
|
||||
</AuthProvider>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
export default App
|
||||
export default App;
|
||||
|
||||
Reference in New Issue
Block a user