|
| 1 | +import { Link, Navigate, Route, Routes } from "react-router" |
| 2 | +import { Section, Spinner } from "@cozystack/ui" |
| 3 | +import { useAdminAccess } from "./sidebar-sections.tsx" |
| 4 | +import { ClusterUsagePage } from "./ClusterUsagePage.tsx" |
| 5 | +import { ClusterUsageResourcePage } from "./ClusterUsageResourcePage.tsx" |
| 6 | +import { BackupResourceListPage } from "./BackupResourceListPage.tsx" |
| 7 | +import { BackupResourceEditPage } from "./BackupResourceEditPage.tsx" |
| 8 | +import { BackupPlanCreatePage } from "./BackupPlanCreatePage.tsx" |
| 9 | +import { BackupJobCreatePage } from "./BackupJobCreatePage.tsx" |
| 10 | +import { BackupCreatePage } from "./BackupCreatePage.tsx" |
| 11 | +import { BackupRestoreJobCreatePage } from "./BackupRestoreJobCreatePage.tsx" |
| 12 | + |
| 13 | +/** |
| 14 | + * Admin portal: cluster-wide operator views (Cluster Usage and Backups), |
| 15 | + * moved out of the tenant-facing Console section. Mounted at /admin/* and |
| 16 | + * gated by useAdminAccess (nodes/list) — the shell hides the nav tab for |
| 17 | + * non-operators, and this guard blocks direct-URL access too: while the |
| 18 | + * access review is in flight we show a spinner, and a denied review |
| 19 | + * renders a 403 notice instead of leaking any admin screen. |
| 20 | + */ |
| 21 | +export function AdminPage() { |
| 22 | + const { allowed, isLoading } = useAdminAccess() |
| 23 | + |
| 24 | + if (isLoading) { |
| 25 | + return ( |
| 26 | + <div className="flex items-center gap-2 p-6 text-sm text-slate-500"> |
| 27 | + <Spinner /> Loading… |
| 28 | + </div> |
| 29 | + ) |
| 30 | + } |
| 31 | + |
| 32 | + if (!allowed) { |
| 33 | + return ( |
| 34 | + <div className="p-6"> |
| 35 | + <Section> |
| 36 | + <div className="px-2 py-4 text-sm text-slate-700"> |
| 37 | + You do not have permission to access the Admin portal.{" "} |
| 38 | + <Link to="/console" className="text-blue-700 underline hover:text-blue-800"> |
| 39 | + Back to console |
| 40 | + </Link> |
| 41 | + . |
| 42 | + </div> |
| 43 | + </Section> |
| 44 | + </div> |
| 45 | + ) |
| 46 | + } |
| 47 | + |
| 48 | + return ( |
| 49 | + <Routes> |
| 50 | + <Route index element={<Navigate to="cluster-usage" replace />} /> |
| 51 | + <Route path="cluster-usage" element={<ClusterUsagePage />} /> |
| 52 | + <Route path="cluster-usage/r/*" element={<ClusterUsageResourcePage />} /> |
| 53 | + <Route |
| 54 | + path="backups/plans" |
| 55 | + element={<BackupResourceListPage resourceType="plans" title="Plans" />} |
| 56 | + /> |
| 57 | + <Route path="backups/plans/create" element={<BackupPlanCreatePage />} /> |
| 58 | + <Route |
| 59 | + path="backups/plans/:name/edit" |
| 60 | + element={<BackupResourceEditPage resourceType="plans" title="Plans" />} |
| 61 | + /> |
| 62 | + <Route |
| 63 | + path="backups/backupjobs" |
| 64 | + element={<BackupResourceListPage resourceType="backupjobs" title="Backup Jobs" />} |
| 65 | + /> |
| 66 | + <Route path="backups/backupjobs/create" element={<BackupJobCreatePage />} /> |
| 67 | + <Route |
| 68 | + path="backups/backupjobs/:name/edit" |
| 69 | + element={<BackupResourceEditPage resourceType="backupjobs" title="Backup Jobs" />} |
| 70 | + /> |
| 71 | + <Route |
| 72 | + path="backups/backups" |
| 73 | + element={<BackupResourceListPage resourceType="backups" title="Backups" />} |
| 74 | + /> |
| 75 | + <Route path="backups/backups/create" element={<BackupCreatePage />} /> |
| 76 | + <Route |
| 77 | + path="backups/backups/:name/edit" |
| 78 | + element={<BackupResourceEditPage resourceType="backups" title="Backups" />} |
| 79 | + /> |
| 80 | + <Route |
| 81 | + path="backups/restorejobs" |
| 82 | + element={<BackupResourceListPage resourceType="restorejobs" title="Restore Jobs" />} |
| 83 | + /> |
| 84 | + <Route path="backups/restorejobs/create" element={<BackupRestoreJobCreatePage />} /> |
| 85 | + <Route |
| 86 | + path="backups/restorejobs/:name/edit" |
| 87 | + element={<BackupResourceEditPage resourceType="restorejobs" title="Restore Jobs" />} |
| 88 | + /> |
| 89 | + </Routes> |
| 90 | + ) |
| 91 | +} |
0 commit comments