diff --git a/Frontend/src/App.jsx b/Frontend/src/App.jsx index c0b210073..11fb2ee97 100644 --- a/Frontend/src/App.jsx +++ b/Frontend/src/App.jsx @@ -1,97 +1,144 @@ -import { - BrowserRouter, - Routes, - Route, - Navigate, - useLocation -} from "react-router-dom"; -import React, { useEffect } from "react"; -import { AnimatePresence } from "framer-motion"; -import { NotFound } from "./components/ui/not-found-2"; -import useTicketStore from "./store/ticketStore"; -import Toaster from "./components/shared/Toaster"; -import BugReportWidget from "./components/shared/BugReportWidget"; -import useRealtimeNotifications from "./hooks/useRealtimeNotifications"; - -// Auth Components -import Login from "./pages/Login"; -import ForgotPassword from "./pages/ForgotPassword"; -import ResetPassword from "./pages/ResetPassword"; -import Signup from "./pages/Signup"; -import AdminSignup from "./pages/AdminSignup"; -import AdminLobby from "./pages/AdminLobby"; -import UserLobby from "./pages/UserLobby"; -import LandingPage from "./pages/LandingPage"; -import ContactSales from "./pages/ContactSales"; - -// Legacy components -import DuplicateDetection from "./user/pages/DuplicateDetection"; -import AutoResolveChat from "./user/pages/AutoResolveChat"; -import Resolved from "./user/pages/Resolved"; -import TicketTracking from "./user/pages/TicketTracking"; -// Layouts -import UserLayout from "./user/UserLayout"; -import AdminLayout from "./admin/layout/AdminLayout"; - -// User Pages -import Dashboard from "./user/pages/Dashboard"; -import CreateTicket from "./user/pages/CreateTicket"; -import MyTickets from "./user/pages/MyTickets"; -import TicketResult from "./user/pages/TicketResult"; -import Profile from "./user/pages/Profile"; -import TicketDetail from "./user/pages/TicketDetail"; -import TicketProcessing from "./user/pages/AIProcessing"; // Renamed generic import just in case, but keeping AIProcessing -import AIProcessing from "./user/pages/AIProcessing"; -import AIUnderstanding from "./user/pages/AIUnderstanding"; -import Notifications from "./user/pages/Notifications"; -import Help from "./user/pages/Help"; -import DocsPortal from "./docs/pages/DocsPortal"; - -// New Showcase Pages -import ApiReference from "./pages/ApiReference"; -import Changelog from "./pages/Changelog"; -import StatusPage from "./pages/StatusPage"; -import AboutUs from "./pages/AboutUs"; -import Careers from "./pages/Careers"; -import CookiePolicy from "./pages/legal/CookiePolicy"; - -// NEW Admin Pages (Refactored) -import AdminDashboard from "./admin/pages/AdminDashboard"; -import AdminTickets from "./admin/pages/AdminTickets"; -import AdminTicketDetail from "./admin/pages/AdminTicketDetail"; -import AdminUsers from "./admin/pages/AdminUsers"; -import AdminAnalytics from "./admin/pages/AdminAnalytics"; -import AdminProfile from "./admin/pages/AdminProfile"; -import AdminSettings from "./admin/pages/AdminSettings"; -import MasterBugReports from "./master-admin/pages/MasterBugReports"; - -// Feature Pages -import AutoCategorizationFeature from "./pages/features/AutoCategorizationFeature"; -import PriorityDetectionFeature from "./pages/features/PriorityDetectionFeature"; -import SmartResolutionFeature from "./pages/features/SmartResolutionFeature"; - -// Legal Pages -import TermsOfService from "./pages/legal/TermsOfService"; -import PrivacyPolicy from "./pages/legal/PrivacyPolicy"; -import Security from "./pages/legal/Security"; -import AdminProtectedRoute from "./components/shared/AdminProtectedRoute"; -import MasterAdminProtectedRoute from "./components/shared/MasterAdminProtectedRoute"; -import ProtectedRoute from "./components/shared/ProtectedRoute"; -import useAuthStore from "./store/authStore"; -import NotApproved from "./pages/NotApproved"; - -// Master Admin Components -import MasterAdminLogin from "./pages/MasterAdminLogin"; -import MasterAdminLayout from "./master-admin/layout/MasterAdminLayout"; -import MasterAdminDashboard from "./master-admin/pages/MasterAdminDashboard"; -import PendingAdminRequests from "./master-admin/pages/PendingAdminRequests"; -import AllCompanies from "./master-admin/pages/AllCompanies"; -import AllAdmins from "./master-admin/pages/AllAdmins"; - +/** + * App.jsx — Unified React Router configuration for HELPDESK.AI + * Consolidates all routes and fix syntax/duplication issues. + */ + +import React, { lazy, Suspense, useEffect, useState } from 'react'; +import { BrowserRouter, Routes, Route, Navigate, useLocation } from 'react-router-dom'; +import { PageSkeleton, MinimalSkeleton } from './components/ui/page-skeleton'; +import { NotFound } from './components/ui/not-found-2'; +import Toaster from './components/shared/Toaster'; +import BugReportWidget from './components/shared/BugReportWidget'; +import useAuthStore from './store/authStore'; +import useKeyboardShortcuts from './hooks/useKeyboardShortcuts'; +import ShortcutsHelp from './components/shared/ShortcutsHelp'; +import BackToTop from './components/shared/BackToTop'; +import ScrollToTopButton from './components/ScrollToTopButton'; + +// --------------------------------------------------------------------------- +// Eagerly-loaded auth pages +// --------------------------------------------------------------------------- +import Login from './pages/Login'; +import ForgotPassword from './pages/ForgotPassword'; +import ResetPassword from './pages/ResetPassword'; +import Signup from './pages/Signup'; +import AdminSignup from './pages/AdminSignup'; +import LandingPage from './pages/LandingPage'; +import NotApproved from './pages/NotApproved'; +import AuthCallback from './pages/AuthCallback'; + +// Route guards +import AdminProtectedRoute from './components/shared/AdminProtectedRoute'; +import MasterAdminProtectedRoute from './components/shared/MasterAdminProtectedRoute'; +import ProtectedRoute from './components/shared/ProtectedRoute'; + +// --------------------------------------------------------------------------- +// Lazily-loaded layouts +// --------------------------------------------------------------------------- +const UserLayout = lazy(() => import('./user/UserLayout')); +const AdminLayout = lazy(() => import('./admin/layout/AdminLayout')); +const MasterAdminLayout = lazy(() => import('./master-admin/layout/MasterAdminLayout')); + +// --------------------------------------------------------------------------- +// Lazily-loaded pages +// --------------------------------------------------------------------------- +const AdminLobby = lazy(() => import('./pages/AdminLobby')); +const UserLobby = lazy(() => import('./pages/UserLobby')); +const MasterAdminLogin = lazy(() => import('./pages/MasterAdminLogin')); + +const Dashboard = lazy(() => import('./user/pages/Dashboard')); +const CreateTicket = lazy(() => import('./user/pages/CreateTicket')); +const MyTickets = lazy(() => import('./user/pages/MyTickets')); +const TicketResult = lazy(() => import('./user/pages/TicketResult')); +const Profile = lazy(() => import('./user/pages/Profile')); +const TicketDetail = lazy(() => import('./user/pages/TicketDetail')); +const AIProcessing = lazy(() => import('./user/pages/AIProcessing')); +const AIUnderstanding = lazy(() => import('./user/pages/AIUnderstanding')); +const Notifications = lazy(() => import('./user/pages/Notifications')); +const Help = lazy(() => import('./user/pages/Help')); +const DuplicateDetection = lazy(() => import('./user/pages/DuplicateDetection')); +const AutoResolveChat = lazy(() => import('./user/pages/AutoResolveChat')); +const Resolved = lazy(() => import('./user/pages/Resolved')); +const TicketTracking = lazy(() => import('./user/pages/TicketTracking')); + +const AdminDashboard = lazy(() => import('./admin/pages/AdminDashboard')); +const AdminTickets = lazy(() => import('./admin/pages/AdminTickets')); +const AdminTicketDetail = lazy(() => import('./admin/pages/AdminTicketDetail')); +const AdminUsers = lazy(() => import('./admin/pages/AdminUsers')); +const AdminAnalytics = lazy(() => import('./admin/pages/AdminAnalytics')); +const AdminProfile = lazy(() => import('./admin/pages/AdminProfile')); +const AdminSettings = lazy(() => import('./admin/pages/AdminSettings')); +const AdminScorecard = lazy(() => import('./admin/components/AgentScorecard')); +const SLAPage = lazy(() => import('./admin/pages/SLAPage')); + +const MasterAdminDashboard = lazy(() => import('./master-admin/pages/MasterAdminDashboard')); +const AllAdmins = lazy(() => import('./master-admin/pages/AllAdmins')); +const AllCompanies = lazy(() => import('./master-admin/pages/AllCompanies')); +const PendingAdminRequests = lazy(() => import('./master-admin/pages/PendingAdminRequests')); +const MasterBugReports = lazy(() => import('./master-admin/pages/MasterBugReports')); + +const ContactSales = lazy(() => import('./pages/ContactSales')); +const ApiReference = lazy(() => import('./pages/ApiReference')); +const Changelog = lazy(() => import('./pages/Changelog')); +const StatusPage = lazy(() => import('./pages/StatusPage')); +const AboutUs = lazy(() => import('./pages/AboutUs')); +const Careers = lazy(() => import('./pages/Careers')); +const DocsPortal = lazy(() => import('./docs/pages/DocsPortal')); + +const AutoCategorizationFeature = lazy(() => import('./pages/features/AutoCategorizationFeature')); +const PriorityDetectionFeature = lazy(() => import('./pages/features/PriorityDetectionFeature')); +const SmartResolutionFeature = lazy(() => import('./pages/features/SmartResolutionFeature')); + +const TermsOfService = lazy(() => import('./pages/legal/TermsOfService')); +const PrivacyPolicy = lazy(() => import('./pages/legal/PrivacyPolicy')); +const Security = lazy(() => import('./pages/legal/Security')); +const CookiePolicy = lazy(() => import('./pages/legal/CookiePolicy')); + +// Tenant Core Workspace Layout Shells +const UserLayout = lazy(() => import('./user/UserLayout')); +const AdminLayout = lazy(() => import('./admin/layout/AdminLayout')); +const MasterAdminLayout = lazy(() => import('./master-admin/layout/MasterAdminLayout')); + +// User Telemetry Target Node Matrix +const Dashboard = lazy(() => import('./user/pages/Dashboard')); +const CreateTicket = lazy(() => import('./user/pages/CreateTicket')); +const MyTickets = lazy(() => import('./user/pages/MyTickets')); +const TicketResult = lazy(() => import('./user/pages/TicketResult')); +const Profile = lazy(() => import('./user/pages/Profile')); +const TicketDetail = lazy(() => import('./user/pages/TicketDetail')); +const AIProcessing = lazy(() => import('./user/pages/AIProcessing')); +const AIUnderstanding = lazy(() => import('./user/pages/AIUnderstanding')); +const Notifications = lazy(() => import('./user/pages/Notifications')); +const Help = lazy(() => import('./user/pages/Help')); +const DuplicateDetection = lazy(() => import('./user/pages/DuplicateDetection')); +const AutoResolveChat = lazy(() => import('./user/pages/AutoResolveChat')); +const Resolved = lazy(() => import('./user/pages/Resolved')); +const TicketTracking = lazy(() => import('./user/pages/TicketTracking')); + +// Operational Support Admin Nodes +const AdminDashboard = lazy(() => import('./admin/pages/AdminDashboard')); +const AdminTickets = lazy(() => import('./admin/pages/AdminTickets')); +const AdminTicketDetail = lazy(() => import('./admin/pages/AdminTicketDetail')); +const AdminUsers = lazy(() => import('./admin/pages/AdminUsers')); +const AdminAnalytics = lazy(() => import('./admin/pages/AdminAnalytics')); +const AdminProfile = lazy(() => import('./admin/pages/AdminProfile')); +const AdminSettings = lazy(() => import('./admin/pages/AdminSettings')); +const AdminScorecard = lazy(() => import('./admin/pages/AdminScorecard')); +const SLAPage = lazy(() => import('./admin/pages/SLAPage')); + +// Master Root Governance Matrix +const MasterAdminLogin = lazy(() => import('./pages/MasterAdminLogin')); +const MasterAdminDashboard = lazy(() => import('./master-admin/pages/MasterAdminDashboard')); +const PendingAdminRequests = lazy(() => import('./master-admin/pages/PendingAdminRequests')); +const AllCompanies = lazy(() => import('./master-admin/pages/AllCompanies')); +const AllAdmins = lazy(() => import('./master-admin/pages/AllAdmins')); +const MasterBugReports = lazy(() => import('./master-admin/pages/MasterBugReports')); + +// Dynamic Inline Fallbacks +const NotFoundPage = lazy(() => import('./components/ui/not-found-2').then((module) => ({ default: module.NotFound }))); function TitleUpdater() { const location = useLocation(); - useEffect(() => { const path = location.pathname; let title = 'HELPDESK.AI'; @@ -106,10 +153,12 @@ function TitleUpdater() { else if (path.startsWith('/admin/settings')) title = 'Settings | Admin'; // Master Admin Routes else if (path.startsWith('/master-admin/dashboard')) title = 'Master Dashboard'; - else if (path.startsWith('/master-admin/admin-requests')) title = 'Pending Requests | Master Admin'; + else if (path.startsWith('/master-admin/admin-requests')) + title = 'Pending Requests | Master Admin'; else if (path.startsWith('/master-admin/companies')) title = 'Companies | Master Admin'; else if (path.startsWith('/master-admin/all-admins')) title = 'All Admins | Master Admin'; - else if (path.startsWith('/master-admin/bug-reports')) title = 'System Bug Radar | Master Admin'; + else if (path.startsWith('/master-admin/bug-reports')) + title = 'System Bug Radar | Master Admin'; // User Routes else if (path.startsWith('/ticket/')) title = 'Ticket Detail'; else if (path.startsWith('/ai-understanding')) title = 'AI Understanding'; @@ -128,84 +177,146 @@ function TitleUpdater() { else if (path === '/cookie-policy') title = 'Cookie Policy'; // Public / Lobby Routes else if (path === '/login') title = 'Login'; - else if (path === '/signup') title = 'Create Account'; - else if (path === '/admin-signup') title = 'Admin Signup'; - else if (path === '/user-lobby') title = 'User Lobby'; - else if (path === '/admin-lobby') title = 'Admin Lobby'; - else if (path === '/') title = 'Welcome'; - - document.title = title === 'HELPDESK.AI' ? title : `${title} | HELPDESK.AI`; + else if (path === '/signup') title = 'Sign Up'; + document.title = `${title} | HELPDESK.AI`; }, [location]); - return null; } -// Scrolls to top on every route change function ScrollToTop() { const { pathname } = useLocation(); useEffect(() => { - window.scrollTo({ top: 0, behavior: 'instant' }); + window.scrollTo(0, 0); }, [pathname]); return null; } -function AppLayout() { - const { user, profile } = useAuthStore(); +class ErrorBoundary extends React.Component { + constructor(props) { + super(props); + this.state = { hasError: false }; + } + static getDerivedStateFromError() { return { hasError: true }; } + componentDidCatch(error, info) { console.error(error, info); } + render() { + if (this.state.hasError) return ( +
+ Press ? anytime to toggle this help +
+Navigate faster with keyboard shortcuts
++ Press Ctrl + / to toggle this help +
+ +