Files
LynkedUpPro_CRM/src/App.jsx
T
2026-05-21 16:52:58 +05:30

382 lines
13 KiB
React

import React from 'react';
import { Routes, Route, Navigate, useLocation } from 'react-router-dom';
import { useAuth } from './context/AuthContext';
import Layout from './components/Layout';
import Login from './pages/Login';
import Landing from './pages/Landing';
import Dashboard from './pages/Dashboard';
import Maps from './pages/Maps';
import AdminSchedule from './pages/AdminSchedule';
import CustomerProfile from './pages/CustomerProfile';
import LeaderboardPage from './pages/LeaderboardPage';
import ErrorBoundary from './components/ErrorBoundary';
import SmoothScroll from './components/SmoothScroll';
import { Toaster } from 'sonner';
import NotFound from './pages/NotFound';
import OwnerSnapshot from './pages/owner/OwnerSnapshot';
import PeopleDirectory from './pages/owner/PeopleDirectory';
import VendorDirectory from './pages/owner/VendorDirectory';
import DocumentManagement from './pages/owner/DocumentManagement';
import OwnerProjectList from './pages/owner/OwnerProjectList';
import OwnerProjectDetail from './pages/owner/OwnerProjectDetail';
import OrgSettings from './pages/owner/OrgSettings';
import SubcontractorTasksPage from './pages/owner/SubcontractorTasksPage';
import PlaceholderDashboard from './pages/PlaceholderDashboard';
import ProCanvas from './pages/ProCanvas';
import ProjectList from './pages/contractor/ProjectList';
import AiAssistantPage from './pages/AiAssistantPage';
import EstimateBuilder from './pages/EstimateBuilder';
// New Dashboards
import VendorDashboard from './pages/vendor/VendorDashboard';
import VendorOrders from './pages/vendor/VendorOrders';
import ContractorDashboard from './pages/contractor/ContractorDashboard';
import SubContractorDashboard from './pages/subcontractor/SubContractorDashboard';
import SubcontractorTaskDetailPage from './pages/subcontractor/SubcontractorTaskDetailPage';
import CreateLeadPage from './pages/CreateLeadPage';
import LeadsListPage from './pages/LeadsListPage';
import LynkDispatchPage from './pages/LynkDispatchPage';
import EstimatesPage from './pages/EstimatesPage';
import KanbanPage from './pages/KanbanPage';
import LeadProjectPage from './pages/LeadProjectPage';
// ... (existing imports)
const ProtectedRoute = ({ children, allowedRoles }) => {
const { user, isAuthenticated } = useAuth();
const location = useLocation();
if (!isAuthenticated) {
return <Navigate to="/login" state={{ from: location }} replace />;
}
if (allowedRoles && !allowedRoles.includes(user.role)) {
// If user is employee but wrong role, go to their default dashboard
// For now, just redirect to home or show unauthorized
return <Navigate to="/" replace />;
}
return children;
};
function App() {
return (
<ErrorBoundary>
<Toaster position="top-right" richColors closeButton expand={true} />
<SmoothScroll>
<Routes>
<Route element={<Layout />}>
{/* Public Routes */}
<Route path="/" element={<Landing />} />
<Route path="/login" element={<Login />} />
<Route
path="/chat-assistant"
element={
<ProtectedRoute allowedRoles={['OWNER', 'ADMIN', 'FIELD_AGENT', 'CONTRACTOR', 'SUBCONTRACTOR', 'CUSTOMER']}>
<AiAssistantPage />
</ProtectedRoute>
}
/>
{/* Protected Field Agent Routes */}
<Route path="/portal/profile" element={
<ProtectedRoute allowedRoles={['CUSTOMER']}>
<CustomerProfile />
</ProtectedRoute>
} />
<Route
path="/emp/fa/dashboard"
element={
<ProtectedRoute allowedRoles={['FIELD_AGENT', 'ADMIN', 'OWNER']}>
<Dashboard />
</ProtectedRoute>
}
/>
<Route
path="/emp/fa/maps"
element={
<ProtectedRoute allowedRoles={['FIELD_AGENT', 'ADMIN', 'OWNER']}>
<Maps />
</ProtectedRoute>
}
/>
<Route
path="/emp/fa/pro-canvas"
element={
<ProtectedRoute allowedRoles={['FIELD_AGENT', 'ADMIN', 'OWNER']}>
<ProCanvas />
</ProtectedRoute>
}
/>
<Route
path="/emp/fa/estimates"
element={
<ProtectedRoute allowedRoles={['FIELD_AGENT', 'ADMIN', 'OWNER']}>
<EstimatesPage />
</ProtectedRoute>
}
/>
<Route
path="/emp/fa/kanban"
element={
<ProtectedRoute allowedRoles={['FIELD_AGENT', 'ADMIN', 'OWNER']}>
<KanbanPage />
</ProtectedRoute>
}
/>
<Route
path="/emp/fa/leads/:leadId"
element={
<ProtectedRoute allowedRoles={['FIELD_AGENT', 'ADMIN', 'OWNER']}>
<LeadProjectPage />
</ProtectedRoute>
}
/>
<Route
path="/emp/fa/estimate"
element={
<ProtectedRoute allowedRoles={['FIELD_AGENT', 'ADMIN', 'OWNER']}>
<EstimateBuilder />
</ProtectedRoute>
}
/>
<Route
path="/emp/fa/leads"
element={
<ProtectedRoute allowedRoles={['FIELD_AGENT', 'ADMIN', 'OWNER']}>
<LeadsListPage />
</ProtectedRoute>
}
/>
<Route
path="/emp/fa/leads/new"
element={
<ProtectedRoute allowedRoles={['FIELD_AGENT', 'ADMIN', 'OWNER']}>
<CreateLeadPage />
</ProtectedRoute>
}
/>
{/* Owner Routes */}
<Route path="/owner/snapshot" element={
<ProtectedRoute allowedRoles={['OWNER']}>
<OwnerSnapshot />
</ProtectedRoute>
} />
<Route path="/owner/people" element={
<ProtectedRoute allowedRoles={['OWNER']}>
<PeopleDirectory />
</ProtectedRoute>
} />
<Route path="/owner/vendors" element={
<ProtectedRoute allowedRoles={['OWNER']}>
<VendorDirectory />
</ProtectedRoute>
} />
<Route path="/owner/documents" element={
<ProtectedRoute allowedRoles={['OWNER']}>
<DocumentManagement />
</ProtectedRoute>
} />
<Route path="/owner/projects" element={
<ProtectedRoute allowedRoles={['OWNER']}>
<OwnerProjectList />
</ProtectedRoute>
} />
<Route path="/owner/projects/:projectId" element={
<ProtectedRoute allowedRoles={['OWNER']}>
<OwnerProjectDetail />
</ProtectedRoute>
} />
<Route path="/owner/maps" element={
<ProtectedRoute allowedRoles={['OWNER']}>
<Maps />
</ProtectedRoute>
} />
<Route path="/owner/pro-canvas" element={
<ProtectedRoute allowedRoles={['OWNER']}>
<ProCanvas />
</ProtectedRoute>
} />
<Route path="/owner/estimates" element={
<ProtectedRoute allowedRoles={['OWNER']}>
<EstimatesPage />
</ProtectedRoute>
} />
<Route path="/owner/kanban" element={
<ProtectedRoute allowedRoles={['OWNER']}>
<KanbanPage />
</ProtectedRoute>
} />
<Route path="/owner/leads/:leadId" element={
<ProtectedRoute allowedRoles={['OWNER']}>
<LeadProjectPage />
</ProtectedRoute>
} />
<Route path="/owner/estimate" element={
<ProtectedRoute allowedRoles={['OWNER']}>
<EstimateBuilder />
</ProtectedRoute>
} />
<Route path="/owner/settings" element={
<ProtectedRoute allowedRoles={['OWNER']}>
<OrgSettings />
</ProtectedRoute>
} />
<Route path="/admin/settings" element={
<ProtectedRoute allowedRoles={['ADMIN']}>
<OrgSettings />
</ProtectedRoute>
} />
<Route path="/owner/subcontractor-tasks" element={
<ProtectedRoute allowedRoles={['OWNER']}>
<SubcontractorTasksPage />
</ProtectedRoute>
} />
<Route path="/admin/subcontractor-tasks" element={
<ProtectedRoute allowedRoles={['ADMIN', 'OWNER']}>
<SubcontractorTasksPage />
</ProtectedRoute>
} />
{/* Protected Admin Routes — Owner has full admin access */}
<Route
path="/admin/dashboard"
element={
<ProtectedRoute allowedRoles={['ADMIN', 'OWNER']}>
<Dashboard />
</ProtectedRoute>
}
/>
<Route
path="/admin/schedule"
element={
<ProtectedRoute allowedRoles={['ADMIN', 'OWNER']}>
<AdminSchedule />
</ProtectedRoute>
}
/>
<Route
path="/admin/leaderboard"
element={
<ProtectedRoute allowedRoles={['ADMIN', 'OWNER']}>
<LeaderboardPage />
</ProtectedRoute>
}
/>
<Route
path="/admin/dispatch"
element={
<ProtectedRoute allowedRoles={['ADMIN', 'OWNER']}>
<LynkDispatchPage />
</ProtectedRoute>
}
/>
<Route
path="/owner/dispatch"
element={
<ProtectedRoute allowedRoles={['OWNER']}>
<LynkDispatchPage />
</ProtectedRoute>
}
/>
<Route
path="/admin/maps"
element={
<ProtectedRoute allowedRoles={['ADMIN', 'OWNER']}>
<Maps />
</ProtectedRoute>
}
/>
<Route
path="/admin/pro-canvas"
element={
<ProtectedRoute allowedRoles={['ADMIN', 'OWNER']}>
<ProCanvas />
</ProtectedRoute>
}
/>
<Route
path="/admin/estimates"
element={
<ProtectedRoute allowedRoles={['ADMIN', 'OWNER']}>
<EstimatesPage />
</ProtectedRoute>
}
/>
<Route
path="/admin/kanban"
element={
<ProtectedRoute allowedRoles={['ADMIN', 'OWNER']}>
<KanbanPage />
</ProtectedRoute>
}
/>
<Route
path="/admin/leads/:leadId"
element={
<ProtectedRoute allowedRoles={['ADMIN', 'OWNER']}>
<LeadProjectPage />
</ProtectedRoute>
}
/>
<Route
path="/admin/estimate"
element={
<ProtectedRoute allowedRoles={['ADMIN', 'OWNER']}>
<EstimateBuilder />
</ProtectedRoute>
}
/>
{/* Contractor Routes */}
<Route path="/contractor/dashboard" element={
<ProtectedRoute allowedRoles={['CONTRACTOR']}>
<ContractorDashboard />
</ProtectedRoute>
} />
<Route path="/contractor/projects" element={
<ProtectedRoute allowedRoles={['CONTRACTOR']}>
<ProjectList />
</ProtectedRoute>
} />
{/* Vendor Routes */}
<Route path="/vendor/dashboard" element={
<ProtectedRoute allowedRoles={['VENDOR']}>
<VendorDashboard />
</ProtectedRoute>
} />
<Route path="/vendor/orders" element={
<ProtectedRoute allowedRoles={['VENDOR']}>
<VendorOrders />
</ProtectedRoute>
} />
{/* Subcontractor Routes */}
<Route path="/subcontractor/dashboard" element={
<ProtectedRoute allowedRoles={['SUBCONTRACTOR']}>
<SubContractorDashboard />
</ProtectedRoute>
} />
<Route path="/subcontractor/projects" element={
<ProtectedRoute allowedRoles={['SUBCONTRACTOR']}>
<ProjectList />
</ProtectedRoute>
} />
<Route path="/subcontractor/tasks/:taskId" element={
<ProtectedRoute allowedRoles={['SUBCONTRACTOR']}>
<SubcontractorTaskDetailPage />
</ProtectedRoute>
} />
</Route>
{/* Catch all */}
<Route path="*" element={<NotFound />} />
</Routes>
</SmoothScroll>
</ErrorBoundary >
);
}
export default App;