- Add Role property to User entity with migration - Create BootstrapController for first admin user creation - Remove [AllowAnonymous] from all learning content controllers - Create AdminController with admin-only endpoints - Create AdminService for user management - Create UserReportService for progress reports - Add UserRepository implementation - Update AuthService with role support feat(frontend): Implement authentication system - Add AuthStore with React context for auth state management - Create Login, Register, Landing, and Home pages - Add ProtectedRoute and AdminRoute components - Create Auth API types and client - Configure Vite with @/ path alias - Add comprehensive CSS styles for auth and landing pages BREAKING CHANGE: All learning content now requires authentication. Users must register and sign in before accessing lessons, quizzes, and stories. Generated by Mistral Vibe. Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
105 lines
3.3 KiB
TypeScript
105 lines
3.3 KiB
TypeScript
/**
|
|
* Home page for authenticated users
|
|
* Shows overview of available content
|
|
*/
|
|
|
|
import { useNavigate } from 'react-router-dom';
|
|
import { useAuth, useIsAdmin } from '@/stores/authStore';
|
|
|
|
export function HomePage() {
|
|
const { user, logout } = useAuth();
|
|
const isAdmin = useIsAdmin();
|
|
const navigate = useNavigate();
|
|
|
|
return (
|
|
<div className="home-page">
|
|
<header className="home-header">
|
|
<h1>Welcome to DeutschLernen</h1>
|
|
<p className="welcome-message">
|
|
Hello, {user?.username}! You're currently at level {user?.currentLevel}.
|
|
</p>
|
|
<p className="user-stats">
|
|
Points: {user?.totalPoints} | Streak: {user?.streak} days
|
|
</p>
|
|
</header>
|
|
|
|
<div className="home-content">
|
|
<section className="content-section">
|
|
<h2>Continue Learning</h2>
|
|
<div className="quick-access">
|
|
<button
|
|
onClick={() => navigate('/lessons')}
|
|
className="quick-access-card"
|
|
>
|
|
<span className="card-icon">📚</span>
|
|
<span className="card-title">Lessons</span>
|
|
<span className="card-description">Practice vocabulary and grammar</span>
|
|
</button>
|
|
|
|
<button
|
|
onClick={() => navigate('/story/1')}
|
|
className="quick-access-card"
|
|
>
|
|
<span className="card-icon">📖</span>
|
|
<span className="card-title">Stories</span>
|
|
<span className="card-description">Read engaging German stories</span>
|
|
</button>
|
|
|
|
<button
|
|
onClick={() => navigate('/quizzes')}
|
|
className="quick-access-card"
|
|
>
|
|
<span className="card-icon">🎯</span>
|
|
<span className="card-title">Quizzes</span>
|
|
<span className="card-description">Test your knowledge</span>
|
|
</button>
|
|
</div>
|
|
</section>
|
|
|
|
<section className="content-section">
|
|
<h2>Your Progress</h2>
|
|
<div className="progress-overview">
|
|
<div className="progress-card">
|
|
<h3>Level {user?.currentLevel}</h3>
|
|
<p>Current CEFR level</p>
|
|
</div>
|
|
<div className="progress-card">
|
|
<h3>{user?.totalPoints} pts</h3>
|
|
<p>Total points earned</p>
|
|
</div>
|
|
<div className="progress-card">
|
|
<h3>{user?.streak} days</h3>
|
|
<p>Current learning streak</p>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
{isAdmin && (
|
|
<section className="content-section admin-section">
|
|
<h2>Admin Dashboard</h2>
|
|
<p>You have administrator access to manage users and content.</p>
|
|
<div className="admin-actions">
|
|
<button
|
|
onClick={() => navigate('/admin')}
|
|
className="btn btn-admin"
|
|
>
|
|
Go to Admin Panel
|
|
</button>
|
|
</div>
|
|
</section>
|
|
)}
|
|
|
|
<section className="content-section">
|
|
<div className="user-actions">
|
|
<button
|
|
onClick={() => logout()}
|
|
className="btn btn-secondary"
|
|
>
|
|
Sign Out
|
|
</button>
|
|
</div>
|
|
</section>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|