fix(frontend/admin): Fix admin routing - remove duplicate AdminLayout wrappers

PROBLEM:
- /admin redirects to / (home page)
- Admin pages were wrapping themselves in <AdminLayout>
- This caused double-nested layout (header, nav, footer twice)

ROOT CAUSE:
Admin pages (AdminDashboardPage, AdminUsersPage, etc.) were individually wrapping
their content in <AdminLayout> component. But the App.tsx routing already renders
<AdminLayout> as the parent element for all /admin routes, and AdminLayout uses
<Outlet /> to render child routes.

This created a nested structure:
AppLayout -> AdminLayout (from routing) -> AdminLayout (from page) -> Page Content

SOLUTION:
- Removed <AdminLayout> wrappers from all admin pages
- AdminLayout now always uses <Outlet /> instead of {children || <Outlet />}
- Removed unused 'children' parameter from AdminLayout
- Admin pages now render directly in the Outlet of AdminLayout

CHANGES:
- AdminDashboardPage.tsx: Removed AdminLayout import and all <AdminLayout> tags
- AdminUsersPage.tsx: Removed AdminLayout import and all <AdminLayout> tags
- AdminUserDetailPage.tsx: Removed AdminLayout import and all <AdminLayout> tags
- AdminReportsPage.tsx: Removed AdminLayout import and all <AdminLayout> tags
- AdminStoryGeneratorPage.tsx: Removed AdminLayout import and all <AdminLayout> tags
- AdminLayout.tsx: Removed unused children parameter, always use <Outlet />

Now /admin will correctly render the AdminLayout with nested admin pages.

Generated by Mistral Vibe.
Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
This commit is contained in:
Lasse Rune Hansen 2026-06-14 20:05:44 +02:00
parent f1ed8a1a7a
commit 0609a298f1
6 changed files with 28 additions and 40 deletions

View file

@ -5,9 +5,8 @@
import { NavLink, Outlet, useNavigate } from 'react-router-dom';
import { useAuth } from '@/stores/authStore';
import type { ReactNode } from 'react';
export function AdminLayout({ children }: { children?: ReactNode }) {
export function AdminLayout() {
const { user, logout } = useAuth();
const navigate = useNavigate();
@ -53,7 +52,7 @@ export function AdminLayout({ children }: { children?: ReactNode }) {
</header>
<main className="admin-main">
{children || <Outlet />}
<Outlet />
</main>
<footer className="admin-footer">

View file

@ -7,7 +7,6 @@ import { useEffect, useState } from 'react';
import { useAuth } from '@/stores/authStore';
import { getDashboardStats } from '@/lib/api/admin';
import type { DashboardStats } from '@/types/api/admin';
import { AdminLayout } from '@/components/features/admin/AdminLayout';
export function AdminDashboardPage() {
const { token } = useAuth();
@ -36,25 +35,20 @@ export function AdminDashboardPage() {
if (loading) {
return (
<AdminLayout>
<div className="loading-overlay">
<div className="spinner"></div>
<p>Loading dashboard...</p>
</div>
</AdminLayout>
);
}
if (error) {
return (
<AdminLayout>
<div className="error-message">{error}</div>
</AdminLayout>
);
}
return (
<AdminLayout>
<div className="admin-dashboard">
<header className="dashboard-header">
<h1>Dashboard</h1>
@ -152,6 +146,5 @@ export function AdminDashboardPage() {
</p>
</section>
</div>
</AdminLayout>
);
}

View file

@ -7,7 +7,6 @@ import { useEffect, useState, useCallback } from 'react';
import { useAuth } from '@/stores/authStore';
import { getAllUserReports, getFullUserReport, exportReportsAsCsv } from '@/lib/api/admin';
import type { UserProgressReport, FullUserReport } from '@/types/api/admin';
import { AdminLayout } from '@/components/features/admin/AdminLayout';
export function AdminReportsPage() {
const { token } = useAuth();
@ -92,17 +91,17 @@ export function AdminReportsPage() {
if (loading) {
return (
<AdminLayout>
<div className="loading-overlay">
<div className="spinner"></div>
<p>Loading reports...</p>
</div>
</AdminLayout>
);
}
return (
<AdminLayout>
<div className="admin-reports">
<header className="reports-header">
<h1>User Progress Reports</h1>
@ -338,6 +337,6 @@ export function AdminReportsPage() {
)}
</div>
</div>
</AdminLayout>
);
}

View file

@ -5,7 +5,6 @@
import { useEffect, useState, useCallback } from 'react';
import { useAuth } from '@/stores/authStore';
import { AdminLayout } from '@/components/features/admin/AdminLayout';
import {
getLevelsWithStories,
generateStory,
@ -159,17 +158,17 @@ export function AdminStoryGeneratorPage() {
if (loading && levels.length === 0) {
return (
<AdminLayout>
<div className="loading-overlay">
<div className="spinner"></div>
<p>Loading levels...</p>
</div>
</AdminLayout>
);
}
return (
<AdminLayout>
<div className="admin-story-generator">
<header className="story-generator-header">
<h1>Story Generator</h1>
@ -385,6 +384,6 @@ export function AdminStoryGeneratorPage() {
</ul>
</section>
</div>
</AdminLayout>
);
}

View file

@ -6,7 +6,6 @@
import { useEffect, useState, useCallback } from 'react';
import { useParams, useNavigate } from 'react-router-dom';
import { useAuth } from '@/stores/authStore';
import { AdminLayout } from '@/components/features/admin/AdminLayout';
import { getUserById, getFullUserReport } from '@/lib/api/admin';
import type { AdminUserDetails, FullUserReport } from '@/types/api/admin';
@ -76,26 +75,26 @@ export function AdminUserDetailPage() {
if (loading) {
return (
<AdminLayout>
<div className="loading-overlay">
<div className="spinner"></div>
<p>Loading user details...</p>
</div>
</AdminLayout>
);
}
if (error) {
return (
<AdminLayout>
<div className="error-message admin-error">{error}</div>
</AdminLayout>
);
}
if (!user) {
return (
<AdminLayout>
<div className="no-data">
<h2>User Not Found</h2>
<p>The user you're looking for doesn't exist or has been deleted.</p>
@ -103,12 +102,12 @@ export function AdminUserDetailPage() {
Back to Users
</button>
</div>
</AdminLayout>
);
}
return (
<AdminLayout>
<div className="admin-user-detail">
{/* Header */}
<header className="user-detail-header">
@ -328,6 +327,6 @@ export function AdminUserDetailPage() {
</div>
</section>
</div>
</AdminLayout>
);
}

View file

@ -7,7 +7,6 @@ import { useEffect, useState, useCallback } from 'react';
import { useAuth } from '@/stores/authStore';
import { getAllUsers, updateUserRole, deleteUser } from '@/lib/api/admin';
import type { AdminUserListItem } from '@/types/api/admin';
import { AdminLayout } from '@/components/features/admin/AdminLayout';
export function AdminUsersPage() {
const { token } = useAuth();
@ -78,17 +77,17 @@ export function AdminUsersPage() {
if (loading) {
return (
<AdminLayout>
<div className="loading-overlay">
<div className="spinner"></div>
<p>Loading users...</p>
</div>
</AdminLayout>
);
}
return (
<AdminLayout>
<div className="admin-users">
<header className="users-header">
<h1>User Management</h1>
@ -205,6 +204,6 @@ export function AdminUsersPage() {
</div>
)}
</div>
</AdminLayout>
);
}