Round 19: Competition system, German curriculum learning, enhanced notebooks, student dashboard

- Fix portfolio-view.tsx: replace entry.isPublic with form.isPublic (runtime error)
- Add Competition system: 5 Prisma models (Competition, CompetitionParticipant, CompetitionReward, CompetitionLeaderboard, RewardClaim)
- Add German curriculum learning: 4 Prisma models (SubjectTopic, SubjectLesson, LessonQuestion, StudentAnswer)
- Add 12 API routes for competitions and rewards
- Add 7 API routes for subject topics, lessons, questions, and student answers
- Create competitions-view.tsx with full CRUD, leaderboard, rewards, registration
- Enhance notebooks-view.tsx with 'Lernen' tab for German curriculum subjects
- Add student-specific dashboard with Papier sparen banner, notebook quick access, learning progress
- Add competitions to teacher and student navigation
- Add 130+ i18n keys for DE and EN (competitions, rewards, learning, environment)
- Enhanced student nav with competitions and notebooks
- DSGVO-compliant reward claims with status lifecycle
This commit is contained in:
Mustafa Cetin committed 2026-07-29 14:18:18 +00:00
1 parent 74404708e5
commit 849b48a5a4
22 files changed
+6543 -5

No files matched your search

+5
View File
@@ -57,6 +57,7 @@ import {
Briefcase,
Clock as ClockIcon,
Library as LibraryIcon,
Trophy,
} from 'lucide-react';
import {
Sidebar,
@@ -150,6 +151,7 @@ import HomeworkView from './homework-view';
import PortfolioView from './portfolio-view';
import TimetableView from './timetable-view';
import ResourceLibraryView from './resource-library-view';
import CompetitionsView from './competitions-view';
// Dynamic imports for heavy components with loading skeletons
const AnalyticsView = dynamic(() => import('./analytics-view'), {
@@ -207,6 +209,7 @@ const navSections: NavSection[] = [
{ key: 'portfolio', icon: Briefcase, labelKey: 'nav.portfolio' },
{ key: 'timetable', icon: ClockIcon, labelKey: 'nav.timetable' },
{ key: 'resources', icon: LibraryIcon, labelKey: 'nav.resources' },
{ key: 'competitions', icon: Trophy, labelKey: 'nav.competitions' },
],
},
{
@@ -233,6 +236,7 @@ const studentNavSections: NavSection[] = [
{ key: 'attendance', icon: CalendarCheck, labelKey: 'nav.student_attendance' },
{ key: 'portfolio', icon: Briefcase, labelKey: 'nav.portfolio' },
{ key: 'calendar', icon: CalendarIconNav, labelKey: 'nav.calendar' },
{ key: 'competitions', icon: Trophy, labelKey: 'nav.competitions' },
],
},
];
@@ -376,6 +380,7 @@ function renderView(view: ViewName) {
case 'portfolio': return <PortfolioView />;
case 'timetable': return <TimetableView />;
case 'resources': return <ResourceLibraryView />;
case 'competitions': return <CompetitionsView />;
default: return <DashboardView />;
}
}