shoc-frontend-new/src/App.js
Adam Moussa 0167a1aa75 Add vendor pages and dispatch UI
- Vendor CRUD: list page with search, create/edit form with trade specialty chips
- Vendor routes, sidebar nav item with truck icon
- vendorApi in services/api.js
- Dispatch button on WO view page opens DispatchModal
- DispatchModal: vendor multi-select filtered by trade, NTE field, description
- Dispatches CollapsibleSection with PO table on WO view page
- fetchVendorsDropdown and dispatchToVendor API functions
- dispatches included in getWorkOrderById response mapping
2026-04-17 11:37:49 -04:00

149 lines
6 KiB
JavaScript

import React, { useState } from "react";
import { BrowserRouter, Routes, Route, Navigate } from "react-router-dom";
import Sidebar from "./components/Sidebar";
import Topbar from "./components/Topbar";
import Dashboard from "./pages/Dashboard";
// AUTH
import LoginPage from "./pages/auth/LoginPage";
import { isAuthenticated } from "./services/authService";
// CONTACTS
import ContactsList from "./pages/contacts/list/List";
import ContactFormPage from "./pages/contacts/form/ContactFormPage";
// ACCOUNTS
import AccountList from "./pages/accounts/list/List";
import AccountFormPage from "./pages/accounts/form/AccountFormPage";
// EMPLOYEES
import EmployeeList from "./pages/employees/list/List";
import EmployeeFormPage from "./pages/employees/form/EmployeeFormPage";
// LOCATIONS
import LocationsList from "./pages/locations/list/List";
import LocationFormPage from "./pages/locations/form/LocationFormPage";
// WORK ORDERS
import WorkOrdersList from "./pages/workorders/list/List";
import WorkOrderViewPage from "./pages/workorders/view/WorkOrderViewPage";
import WorkOrderFormPage from "./pages/workorders/form/WorkOrderFormPage";
// FOLLOW UPS
import FollowUpList from "./pages/followup/list/List";
import FollowUpFormPage from "./pages/followup/form/FollowUpFormPage";
// PM SCHEDULES
import PMScheduleList from "./pages/PmSchedule/list/List";
import PMScheduleFormPage from "./pages/PmSchedule/form/PmScheduleFormPage";
// ASSETS
import AssetsList from "./pages/assets/list/List";
import AssetFormPage from "./pages/assets/form/AssetFormPage";
// CALENDAR
import CalendarPage from "./pages/calendar/list/CalendarPage";
import EventFormPage from "./pages/calendar/form/EventFormPage";
// VENDORS
import VendorsList from "./pages/vendors/list/List";
import VendorFormPage from "./pages/vendors/form/VendorFormPage";
// SETTINGS
import DropdownOptionsPage from "./pages/settings/DropdownOptionsPage";
// Protected Route Component
function ProtectedRoute({ children }) {
return isAuthenticated() ? children : <Navigate to="/login" replace />;
}
export default function App() {
const [navCollapsed, setNavCollapsed] = useState(false);
return (
<BrowserRouter>
<Routes>
{/* Public Routes */}
<Route path="/login" element={<LoginPage />} />
{/* Protected Routes */}
<Route
path="/*"
element={
<ProtectedRoute>
<div className={`app ${navCollapsed ? "nav-collapsed" : ""}`}>
<Sidebar />
<div className="mainArea">
<Topbar onToggleNav={() => setNavCollapsed(v => !v)} />
<div className="contentWrapper">
<Routes>
<Route path="/" element={<Dashboard />} />
<Route path="/dashboard" element={<Dashboard />} />
{/* CONTACTS */}
<Route path="/contacts" element={<ContactsList />} />
<Route path="/contacts/new" element={<ContactFormPage />} />
<Route path="/contacts/edit/:id" element={<ContactFormPage />} />
{/* ACCOUNTS */}
<Route path="/accounts" element={<AccountList />} />
<Route path="/accounts/new" element={<AccountFormPage />} />
<Route path="/accounts/edit/:id" element={<AccountFormPage />} />
{/* EMPLOYEES */}
<Route path="/employees" element={<EmployeeList />} />
<Route path="/employees/new" element={<EmployeeFormPage />} />
<Route path="/employees/edit/:id" element={<EmployeeFormPage />} />
{/* LOCATIONS */}
<Route path="/locations" element={<LocationsList />} />
<Route path="/locations/new" element={<LocationFormPage />} />
<Route path="/locations/edit/:id" element={<LocationFormPage />} />
{/* WORK ORDERS */}
<Route path="/workorders" element={<WorkOrdersList />} />
<Route path="/workorders/new" element={<WorkOrderFormPage />} />
<Route path="/workorders/:id" element={<WorkOrderViewPage />} />
<Route path="/workorders/edit/:id" element={<WorkOrderFormPage />} />
{/* FOLLOW UPS */}
<Route path="/followups" element={<FollowUpList />} />
<Route path="/followups/new" element={<FollowUpFormPage />} />
<Route path="/followups/edit/:id" element={<FollowUpFormPage />} />
{/* PM SCHEDULES */}
<Route path="/pmschedules" element={<PMScheduleList />} />
<Route path="/pmschedules/new" element={<PMScheduleFormPage />} />
<Route path="/pmschedules/edit/:id" element={<PMScheduleFormPage />} />
{/* ASSETS */}
<Route path="/assets" element={<AssetsList />} />
<Route path="/assets/new" element={<AssetFormPage />} />
<Route path="/assets/edit/:id" element={<AssetFormPage />} />
{/* VENDORS */}
<Route path="/vendors" element={<VendorsList />} />
<Route path="/vendors/new" element={<VendorFormPage />} />
<Route path="/vendors/edit/:id" element={<VendorFormPage />} />
{/* CALENDAR */}
<Route path="/calendar" element={<CalendarPage />} />
<Route path="/calendar/new" element={<EventFormPage />} />
<Route path="/calendar/edit/:id" element={<EventFormPage />} />
{/* SETTINGS */}
<Route path="/settings/dropdowns" element={<DropdownOptionsPage />} />
</Routes>
</div>
</div>
</div>
</ProtectedRoute>
}
/>
</Routes>
</BrowserRouter>
);
}