Phase 0: Add sidebar filtering and route guards for modules

- Updated AppSidebar to filter out disabled modules from navigation
- Added ModuleGuard to all module routes (planner, writer, thinker, automation)
- Modules now dynamically appear/disappear based on enable settings
- Routes are protected and redirect to settings if module is disabled
This commit is contained in:
IGNY8 VPS (Salman)
2025-11-16 18:48:23 +00:00
parent dbe8da589f
commit 9b3fb25bc9
2 changed files with 155 additions and 89 deletions

View File

@@ -4,6 +4,7 @@ import { HelmetProvider } from "react-helmet-async";
import AppLayout from "./layout/AppLayout";
import { ScrollToTop } from "./components/common/ScrollToTop";
import ProtectedRoute from "./components/auth/ProtectedRoute";
import ModuleGuard from "./components/common/ModuleGuard";
import GlobalErrorDisplay from "./components/common/GlobalErrorDisplay";
import LoadingStateMonitor from "./components/common/LoadingStateMonitor";
@@ -133,90 +134,122 @@ export default function App() {
{/* Planner Module */}
<Route path="/planner" element={
<Suspense fallback={null}>
<PlannerDashboard />
<ModuleGuard module="planner">
<PlannerDashboard />
</ModuleGuard>
</Suspense>
} />
<Route path="/planner/keywords" element={
<Suspense fallback={null}>
<Keywords />
<ModuleGuard module="planner">
<Keywords />
</ModuleGuard>
</Suspense>
} />
<Route path="/planner/clusters" element={
<Suspense fallback={null}>
<Clusters />
<ModuleGuard module="planner">
<Clusters />
</ModuleGuard>
</Suspense>
} />
<Route path="/planner/ideas" element={
<Suspense fallback={null}>
<Ideas />
<ModuleGuard module="planner">
<Ideas />
</ModuleGuard>
</Suspense>
} />
{/* Writer Module */}
<Route path="/writer" element={
<Suspense fallback={null}>
<ModuleGuard module="writer">
<WriterDashboard />
</Suspense>
</ModuleGuard>
</Suspense>
} />
<Route path="/writer/tasks" element={
<Suspense fallback={null}>
<ModuleGuard module="writer">
<Tasks />
</Suspense>
</ModuleGuard>
</Suspense>
} />
{/* Writer Content Routes - Order matters: list route must come before detail route */}
<Route path="/writer/content" element={
<Suspense fallback={null}>
<ModuleGuard module="writer">
<Content />
</Suspense>
</ModuleGuard>
</Suspense>
} />
{/* Content detail view - matches /writer/content/:id (e.g., /writer/content/10) */}
<Route path="/writer/content/:id" element={
<Suspense fallback={null}>
<ModuleGuard module="writer">
<ContentView />
</Suspense>
</ModuleGuard>
</Suspense>
} />
<Route path="/writer/drafts" element={<Navigate to="/writer/content" replace />} />
<Route path="/writer/images" element={
<Suspense fallback={null}>
<ModuleGuard module="writer">
<Images />
</Suspense>
</ModuleGuard>
</Suspense>
} />
<Route path="/writer/published" element={
<Suspense fallback={null}>
<ModuleGuard module="writer">
<Published />
</Suspense>
</ModuleGuard>
</Suspense>
} />
{/* Thinker Module */}
<Route path="/thinker" element={
<Suspense fallback={null}>
<ModuleGuard module="thinker">
<ThinkerDashboard />
</Suspense>
</ModuleGuard>
</Suspense>
} />
<Route path="/thinker/prompts" element={
<Suspense fallback={null}>
<ModuleGuard module="thinker">
<Prompts />
</Suspense>
</ModuleGuard>
</Suspense>
} />
<Route path="/thinker/author-profiles" element={
<Suspense fallback={null}>
<ModuleGuard module="thinker">
<AuthorProfiles />
</Suspense>
</ModuleGuard>
</Suspense>
} />
<Route path="/thinker/profile" element={
<Suspense fallback={null}>
<ModuleGuard module="thinker">
<ThinkerProfile />
</Suspense>
</ModuleGuard>
</Suspense>
} />
<Route path="/thinker/strategies" element={
<Suspense fallback={null}>
<ModuleGuard module="thinker">
<Strategies />
</Suspense>
</ModuleGuard>
</Suspense>
} />
<Route path="/thinker/image-testing" element={
<Suspense fallback={null}>
<ModuleGuard module="thinker">
<ImageTesting />
</Suspense>
</ModuleGuard>
</Suspense>
} />
{/* Billing Module */}
@@ -256,8 +289,10 @@ export default function App() {
{/* Other Pages */}
<Route path="/automation" element={
<Suspense fallback={null}>
<ModuleGuard module="automation">
<AutomationDashboard />
</Suspense>
</ModuleGuard>
</Suspense>
} />
<Route path="/schedules" element={
<Suspense fallback={null}>