feat(frontend): router restructure /admin → /lessons with redirects
This commit is contained in:
@@ -114,7 +114,7 @@ function TreeRow({ n, depth }: { n: LessonTreeNode; depth: number }) {
|
||||
>⋮⋮</span>
|
||||
)}
|
||||
<span className={`h-2 w-2 rounded-full ${depth === 0 ? 'bg-brand-500' : 'bg-brand-300'}`} />
|
||||
<Link to={`/admin/lessons/${n.id}`} className="flex-1 truncate font-medium text-slate-800 dark:text-slate-100">
|
||||
<Link to={`/lessons/${n.id}`} className="flex-1 truncate font-medium text-slate-800 dark:text-slate-100">
|
||||
{n.name}
|
||||
<span className="ml-2 rounded-full bg-brand-100 px-2 py-0.5 text-xs font-semibold text-brand-700 dark:bg-brand-900/30 dark:text-brand-200">
|
||||
{n.cardCount}
|
||||
|
||||
@@ -33,7 +33,7 @@ export function MarketplacePage() {
|
||||
async function fork(id: number) {
|
||||
try {
|
||||
const f = await lessonsApi.fork(id);
|
||||
navigate(`/admin/lessons/${f.id}`);
|
||||
navigate(`/lessons/${f.id}`);
|
||||
}
|
||||
catch (e) { alert(e instanceof ApiClientError ? e.message : 'Forken mislukt'); }
|
||||
}
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
import { lazy, Suspense, type ComponentType } from 'react';
|
||||
import { createBrowserRouter, Navigate } from 'react-router-dom';
|
||||
import { createBrowserRouter, Navigate, useParams } from 'react-router-dom';
|
||||
import { Layout } from './components/Layout.js';
|
||||
import { AuthBoundary } from './components/AuthBoundary.js';
|
||||
import { RoleGuard } from './components/RoleGuard.js';
|
||||
|
||||
// Tiny loading placeholder reused for every lazy route boundary.
|
||||
function PageFallback() {
|
||||
return (
|
||||
<div className="flex h-full items-center justify-center p-12">
|
||||
@@ -13,8 +12,6 @@ function PageFallback() {
|
||||
);
|
||||
}
|
||||
|
||||
// `React.lazy` requires a default export; our pages use named exports, so we
|
||||
// adapt with a small helper that picks the named export from the module.
|
||||
function lazyPage<K extends string>(
|
||||
loader: () => Promise<Record<K, ComponentType>>,
|
||||
name: K,
|
||||
@@ -33,8 +30,8 @@ function lazyPage<K extends string>(
|
||||
}
|
||||
|
||||
const Dashboard = lazyPage(() => import('./pages/Dashboard.js'), 'DashboardPage');
|
||||
const Admin = lazyPage(() => import('./pages/Admin.js'), 'AdminPage');
|
||||
const AdminLesson = lazyPage(() => import('./pages/AdminLesson.js'), 'AdminLessonPage');
|
||||
const Lessons = lazyPage(() => import('./pages/Lessons.js'), 'LessonsPage');
|
||||
const LessonDetail = lazyPage(() => import('./pages/LessonDetail.js'), 'LessonDetailPage');
|
||||
const PracticeSetup = lazyPage(() => import('./pages/PracticeSetup.js'), 'PracticeSetupPage');
|
||||
const Practice = lazyPage(() => import('./pages/Practice.js'), 'PracticePage');
|
||||
const PracticeDone = lazyPage(() => import('./pages/PracticeDone.js'), 'PracticeDonePage');
|
||||
@@ -53,12 +50,17 @@ const ForgotPassword = lazyPage(() => import('./pages/auth/ForgotPassword.js'),
|
||||
const ResetPassword = lazyPage(() => import('./pages/auth/ResetPassword.js'), 'ResetPasswordPage');
|
||||
const AcceptInvite = lazyPage(() => import('./pages/auth/AcceptInvite.js'), 'AcceptInvitePage');
|
||||
|
||||
function AdminToLessons() { return <Navigate to="/lessons" replace />; }
|
||||
function AdminLessonRedirect() {
|
||||
const { id } = useParams();
|
||||
return <Navigate to={`/lessons/${id ?? ''}`} replace />;
|
||||
}
|
||||
|
||||
export const router = createBrowserRouter([
|
||||
{
|
||||
path: '/',
|
||||
element: <Layout />,
|
||||
children: [
|
||||
// Public auth routes
|
||||
{ path: 'login', element: <Login /> },
|
||||
{ path: 'register', element: <Register /> },
|
||||
{ path: 'verify-email', element: <VerifyEmail /> },
|
||||
@@ -66,13 +68,16 @@ export const router = createBrowserRouter([
|
||||
{ path: 'reset-password', element: <ResetPassword /> },
|
||||
{ path: 'accept-invite', element: <AcceptInvite /> },
|
||||
|
||||
// Authenticated routes
|
||||
{
|
||||
element: <AuthBoundary />,
|
||||
children: [
|
||||
{ index: true, element: <Dashboard /> },
|
||||
{ path: 'admin', element: <Admin /> },
|
||||
{ path: 'admin/lessons/:id', element: <AdminLesson /> },
|
||||
{ path: 'lessons', element: <Lessons /> },
|
||||
{ path: 'lessons/:id', element: <LessonDetail /> },
|
||||
|
||||
{ path: 'admin', element: <AdminToLessons /> },
|
||||
{ path: 'admin/lessons/:id', element: <AdminLessonRedirect /> },
|
||||
|
||||
{ path: 'practice/:lessonId/setup', element: <PracticeSetup /> },
|
||||
{ path: 'practice/:lessonId', element: <Practice /> },
|
||||
{ path: 'practice/:lessonId/done', element: <PracticeDone /> },
|
||||
|
||||
Reference in New Issue
Block a user