Round 20: Student Portal, District Management, userId field, styling enhancements, bug fixes
- Added userId field to Student model with User relation - Created Student Portal view with 6 tabs (competencies, goals, achievements, schedule, homework, feedback) - Created StudentGoal model + CRUD API with role-based access - Created District Management view with CRUD, analytics, school assignment - Enhanced auth page: animated gradient, floating particles, glassmorphism, staggered entrance - Enhanced dashboard: time-based greeting, animated stat cards, class overview, school branding - Enhanced student portal: hero section, circular progress, streak counter, celebration particles - Fixed student-goals API 403 for STUDENT role (name-matching fallback for legacy data) - Added userId filter to students API with OR fallback - Added nav.student-portal i18n key - 100+ new i18n keys in DE and EN - All lint checks pass
This commit is contained in:
1 parent
9680cc9244
commit
04ae7aa80c
23 files changed
+4624
-2868
No files matched your search
@@ -59,6 +59,7 @@ import {
|
||||
Library as LibraryIcon,
|
||||
Trophy,
|
||||
FolderOpen,
|
||||
Building2,
|
||||
} from 'lucide-react';
|
||||
import {
|
||||
Sidebar,
|
||||
@@ -131,6 +132,7 @@ import { Skeleton } from '@/components/ui/skeleton';
|
||||
|
||||
// Static imports for lightweight views
|
||||
import DashboardView from './dashboard-view';
|
||||
import StudentPortalView from './student-portal-view';
|
||||
import ClassesView from './classes-view';
|
||||
import CompetencyGridView from './competency-grid-view';
|
||||
import ProgressEntriesView from './progress-entries-view';
|
||||
@@ -153,6 +155,7 @@ import PortfolioView from './portfolio-view';
|
||||
import TimetableView from './timetable-view';
|
||||
import ResourceLibraryView from './resource-library-view';
|
||||
import CompetitionsView from './competitions-view';
|
||||
import DistrictManagementView from './district-management-view';
|
||||
|
||||
// Dynamic imports for heavy components with loading skeletons
|
||||
const AnalyticsView = dynamic(() => import('./analytics-view'), {
|
||||
@@ -218,6 +221,7 @@ const navSections: NavSection[] = [
|
||||
labelKey: 'polish.nav_setup',
|
||||
items: [
|
||||
{ key: 'competencies', icon: BookOpen, labelKey: 'nav.competencies' },
|
||||
{ key: 'districts', icon: Building2, labelKey: 'nav.districts' },
|
||||
{ key: 'settings', icon: Settings, labelKey: 'nav.settings' },
|
||||
],
|
||||
},
|
||||
@@ -230,6 +234,7 @@ const studentNavSections: NavSection[] = [
|
||||
labelKey: 'student.dashboard_title',
|
||||
items: [
|
||||
{ key: 'dashboard', icon: LayoutDashboard, labelKey: 'nav.dashboard' },
|
||||
{ key: 'student-portal', icon: GraduationCap, labelKey: 'student_portal.title' },
|
||||
{ key: 'notebooks', icon: BookOpen, labelKey: 'nav.student_notebooks' },
|
||||
{ key: 'flower', icon: Flower2, labelKey: 'nav.student_competencies' },
|
||||
{ key: 'grading', icon: Calculator, labelKey: 'nav.student_grades' },
|
||||
@@ -361,6 +366,7 @@ function AnnouncementBanner({ schoolId }: { schoolId: string | null }) {
|
||||
function renderView(view: ViewName) {
|
||||
switch (view) {
|
||||
case 'dashboard': return <DashboardView />;
|
||||
case 'student-portal': return <StudentPortalView />;
|
||||
case 'classes': return <ClassesView />;
|
||||
case 'competencies': return <CompetencyGridView />;
|
||||
case 'progress': return <ProgressEntriesView />;
|
||||
@@ -387,6 +393,7 @@ function renderView(view: ViewName) {
|
||||
case 'timetable': return <TimetableView />;
|
||||
case 'resources': return <ResourceLibraryView />;
|
||||
case 'competitions': return <CompetitionsView />;
|
||||
case 'districts': return <DistrictManagementView />;
|
||||
default: return <DashboardView />;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user