DeutschLernen/german-app-frontend/src/pages/AdminDashboardPage.tsx
Lasse Rune Hansen 70af326ca7 feat(frontend/admin): Complete Admin Module implementation
- Add AdminLayout component for consistent admin UI
- Create AdminDashboardPage with statistics overview
- Create AdminUsersPage with user management (CRUD, role changes)
- Create AdminReportsPage with user progress reports and CSV export
- Create AdminStoryGeneratorPage for AI-powered story generation
- Create AdminUserDetailPage for detailed user progress tracking
- Add comprehensive admin API client with all endpoints
- Add TypeScript types for admin DTOs (users, reports, stories)
- Add extensive CSS styles for all admin pages
- Update App.tsx with proper admin sub-routes
- Update admin-module.md feature documentation with completion status

Admin features:
- Dashboard with stats (users, lessons, quizzes, stories, activity)
- User management (list, view details, change roles, delete)
- Progress reports (view all, detailed user reports, CSV export)
- Story generator (AI story creation for levels with audio)
- Role-based authentication (AdminRoute protects all admin pages)
- Responsive design for all admin pages

Generated by Mistral Vibe.
Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
2026-06-14 15:29:20 +02:00

157 lines
4.9 KiB
TypeScript

/**
* Admin Dashboard page
* Shows overview statistics and quick actions
*/
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();
const [stats, setStats] = useState<DashboardStats | null>(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
useEffect(() => {
const fetchStats = async () => {
if (!token) return;
try {
setLoading(true);
setError(null);
const data = await getDashboardStats(token);
setStats(data);
} catch (err) {
setError(err instanceof Error ? err.message : 'Failed to load dashboard stats');
} finally {
setLoading(false);
}
};
fetchStats();
}, [token]);
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>
<p className="dashboard-subtitle">Overview of your DeutschLernen application</p>
</header>
<section className="dashboard-stats-grid">
<div className="stat-card">
<div className="stat-icon users">👥</div>
<div className="stat-content">
<h3>Total Users</h3>
<p className="stat-value">{stats?.totalUsers || 0}</p>
</div>
</div>
<div className="stat-card">
<div className="stat-icon lessons">📚</div>
<div className="stat-content">
<h3>Total Lessons</h3>
<p className="stat-value">{stats?.totalLessons || 0}</p>
</div>
</div>
<div className="stat-card">
<div className="stat-icon quizzes">🎯</div>
<div className="stat-content">
<h3>Total Quizzes</h3>
<p className="stat-value">{stats?.totalQuizzes || 0}</p>
</div>
</div>
<div className="stat-card">
<div className="stat-icon stories">📖</div>
<div className="stat-content">
<h3>Story Segments</h3>
<p className="stat-value">{stats?.totalStorySegments || 0}</p>
</div>
</div>
<div className="stat-card">
<div className="stat-icon active"></div>
<div className="stat-content">
<h3>Active Users (Week)</h3>
<p className="stat-value">{stats?.activeUsersThisWeek || 0}</p>
</div>
</div>
<div className="stat-card">
<div className="stat-icon progress">📈</div>
<div className="stat-content">
<h3>Avg. Progress</h3>
<p className="stat-value">{stats ? stats.averageUserProgress.toFixed(1) + '%' : '0%'}</p>
</div>
</div>
</section>
<section className="dashboard-quick-actions">
<h2>Quick Actions</h2>
<div className="quick-action-cards">
<a href="/admin/users" className="quick-action-card">
<div className="action-icon">👥</div>
<div className="action-content">
<h3>Manage Users</h3>
<p>View, edit, and manage all users</p>
</div>
</a>
<a href="/admin/reports" className="quick-action-card">
<div className="action-icon">📊</div>
<div className="action-content">
<h3>View Reports</h3>
<p>Generate and export user progress reports</p>
</div>
</a>
<a href="/admin/stories" className="quick-action-card">
<div className="action-icon">📖</div>
<div className="action-content">
<h3>Generate Stories</h3>
<p>Create new story segments for levels</p>
</div>
</a>
</div>
</section>
<section className="dashboard-info">
<h2>About</h2>
<p>
This is the DeutschLernen admin panel. Here you can manage users,
view progress reports, and generate story content for different CEFR levels.
</p>
<p>
<strong>Note:</strong> All actions in this panel require administrator privileges.
Please ensure you are logged in as an admin user.
</p>
</section>
</div>
</AdminLayout>
);
}