Files
ServerKit/frontend/src/components/ModuleRoute.jsx
T
Juan DenisandClaude Opus 4.8 3e373511b7 feat(extensions): Phase 1 — seed marketplace (GPU + Workflow), module toggles
- One-shot auto-install migration (extension_migration.py): converted builtins
  auto-install on upgrade, marketplace-only on fresh install, user uninstall
  respected
- Convert GPU Monitor → serverkit-gpu and Workflow Builder → serverkit-workflows
  (manifest-driven nav/route/title/palette; pages + backend stay core, D2)
- Module toggles (#14): module_service + /api/v1/modules + 503 guards on
  email/wordpress; frontend useModules hook, sidebar gating, ModuleRoute guard,
  Settings → Modules card
- Marketplace curation polish (#15): by-ServerKit badge, real category chips,
  detail modal with icon + screenshots
- Tests: test_extension_migration.py, test_module_toggles.py (backend suite green)

Tab-grouped conversions (#8/#9/#10/#12/#13) deferred to after the Phase 3
tab-slot primitive (#27) to avoid a grouped-UX regression — see plan doc.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 21:34:54 -04:00

20 lines
645 B
React

import { Navigate } from 'react-router-dom';
import useModules from '../hooks/useModules';
// Route guard for the optional feature modules (Email, WordPress). When the
// named module has been disabled by an admin, its routes redirect to the
// dashboard instead of rendering a dead page. While module state is still
// loading it is treated as enabled, so a valid deep link never flashes a
// redirect before state arrives.
const ModuleRoute = ({ name, children }) => {
const { isEnabled } = useModules();
if (!isEnabled(name)) {
return <Navigate to="/" replace />;
}
return children;
};
export default ModuleRoute;