@@ -135,16 +151,16 @@ export default function RoleLayout({ navGroups, role }: RoleLayoutProps) {
-
{user?.name}
+
{user?.name ?? t("userMenu.userFallback")}
{user?.email}
navigate(`/${role}/profile`)}>
- Profile
+ {t("userMenu.profile")}
- Logout
+ {t("userMenu.logout")}
diff --git a/src/components/StudentLayout.tsx b/src/components/StudentLayout.tsx
index 9fca00f..201c060 100644
--- a/src/components/StudentLayout.tsx
+++ b/src/components/StudentLayout.tsx
@@ -2,47 +2,52 @@ import RoleLayout, { NavGroup } from "./RoleLayout";
import ExamPopup from "./student/ExamPopup";
import {
LayoutDashboard, BookOpen, ClipboardList, BarChart3,
- CalendarCheck, Calendar, User, Target, GraduationCap, ListChecks,
+ CalendarCheck, Calendar, User, Target, ListChecks,
MessageSquare, Megaphone, Mail, TrendingUp,
} from "lucide-react";
+/**
+ * Student portal shell. Nav items hold i18n keys which `RoleLayout`
+ * resolves via `useTranslation`, so switching language does not require
+ * re-mounting the layout.
+ */
const navGroups: NavGroup[] = [
{
- label: "Learning",
+ labelKey: "sidebarGroup.learning",
items: [
- { title: "Dashboard", url: "/student/dashboard", icon: LayoutDashboard },
- { title: "My Courses", url: "/student/courses", icon: BookOpen },
- { title: "Subject Registration", url: "/student/subject-registration", icon: ListChecks },
- { title: "Assignments", url: "/student/assignments", icon: ClipboardList },
+ { titleKey: "nav.dashboard", url: "/student/dashboard", icon: LayoutDashboard },
+ { titleKey: "nav.myCourses", url: "/student/courses", icon: BookOpen },
+ { titleKey: "nav.subjectRegistration", url: "/student/subject-registration", icon: ListChecks },
+ { titleKey: "nav.assignments", url: "/student/assignments", icon: ClipboardList },
],
},
{
- label: "Adaptive Learning",
+ labelKey: "sidebarGroup.adaptiveLearning",
items: [
- { title: "My Subjects", url: "/student/subjects", icon: Target },
+ { titleKey: "nav.mySubjects", url: "/student/subjects", icon: Target },
],
},
{
- label: "Progress",
+ labelKey: "sidebarGroup.progress",
items: [
- { title: "Grades", url: "/student/grades", icon: BarChart3 },
- { title: "Attendance", url: "/student/attendance", icon: CalendarCheck },
- { title: "Timetable", url: "/student/timetable", icon: Calendar },
- { title: "My Journey", url: "/student/journey", icon: TrendingUp },
+ { titleKey: "nav.grades", url: "/student/grades", icon: BarChart3 },
+ { titleKey: "nav.attendance", url: "/student/attendance", icon: CalendarCheck },
+ { titleKey: "nav.timetable", url: "/student/timetable", icon: Calendar },
+ { titleKey: "nav.myJourney", url: "/student/journey", icon: TrendingUp },
],
},
{
- label: "Communication",
+ labelKey: "sidebarGroup.communication",
items: [
- { title: "Discussions", url: "/student/discussions", icon: MessageSquare },
- { title: "Messages", url: "/student/messages", icon: Mail },
- { title: "Announcements", url: "/student/announcements", icon: Megaphone },
+ { titleKey: "nav.discussions", url: "/student/discussions", icon: MessageSquare },
+ { titleKey: "nav.messages", url: "/student/messages", icon: Mail },
+ { titleKey: "nav.announcements", url: "/student/announcements", icon: Megaphone },
],
},
{
- label: "Account",
+ labelKey: "sidebarGroup.account",
items: [
- { title: "Profile", url: "/student/profile", icon: User },
+ { titleKey: "nav.profile", url: "/student/profile", icon: User },
],
},
];
diff --git a/src/components/TeacherLayout.tsx b/src/components/TeacherLayout.tsx
index a939eb8..768d481 100644
--- a/src/components/TeacherLayout.tsx
+++ b/src/components/TeacherLayout.tsx
@@ -1,39 +1,40 @@
import RoleLayout, { NavGroup } from "./RoleLayout";
import {
- LayoutDashboard, BookOpen, ClipboardList, FileText,
+ LayoutDashboard, BookOpen, ClipboardList,
CalendarCheck, Users, Calendar, User, MessageSquare,
- Megaphone, Wand2, Library,
+ Megaphone, Library,
} from "lucide-react";
+/** Teacher portal shell. See `StudentLayout` for the nav-config rationale. */
const navGroups: NavGroup[] = [
{
- label: "Teaching",
+ labelKey: "sidebarGroup.teaching",
items: [
- { title: "Dashboard", url: "/teacher/dashboard", icon: LayoutDashboard },
- { title: "Courses", url: "/teacher/courses", icon: BookOpen },
- { title: "Resource Library", url: "/teacher/library", icon: Library },
- { title: "Assignments", url: "/teacher/assignments", icon: ClipboardList },
+ { titleKey: "nav.dashboard", url: "/teacher/dashboard", icon: LayoutDashboard },
+ { titleKey: "nav.courses", url: "/teacher/courses", icon: BookOpen },
+ { titleKey: "nav.resourceLibrary", url: "/teacher/library", icon: Library },
+ { titleKey: "nav.assignments", url: "/teacher/assignments", icon: ClipboardList },
],
},
{
- label: "Management",
+ labelKey: "sidebarGroup.management",
items: [
- { title: "Attendance", url: "/teacher/attendance", icon: CalendarCheck },
- { title: "Students", url: "/teacher/students", icon: Users },
- { title: "Timetable", url: "/teacher/timetable", icon: Calendar },
+ { titleKey: "nav.attendance", url: "/teacher/attendance", icon: CalendarCheck },
+ { titleKey: "nav.students", url: "/teacher/students", icon: Users },
+ { titleKey: "nav.timetable", url: "/teacher/timetable", icon: Calendar },
],
},
{
- label: "Communication",
+ labelKey: "sidebarGroup.communication",
items: [
- { title: "Discussions", url: "/teacher/discussions", icon: MessageSquare },
- { title: "Announcements", url: "/teacher/announcements", icon: Megaphone },
+ { titleKey: "nav.discussions", url: "/teacher/discussions", icon: MessageSquare },
+ { titleKey: "nav.announcements", url: "/teacher/announcements", icon: Megaphone },
],
},
{
- label: "Account",
+ labelKey: "sidebarGroup.account",
items: [
- { title: "Profile", url: "/teacher/profile", icon: User },
+ { titleKey: "nav.profile", url: "/teacher/profile", icon: User },
],
},
];
diff --git a/src/components/ThemeToggle.tsx b/src/components/ThemeToggle.tsx
index 3569fed..bb7ef40 100644
--- a/src/components/ThemeToggle.tsx
+++ b/src/components/ThemeToggle.tsx
@@ -1,6 +1,7 @@
import { Moon, Sun, Monitor } from "lucide-react";
import { useTheme } from "next-themes";
import { useEffect, useState } from "react";
+import { useTranslation } from "react-i18next";
import { Button } from "@/components/ui/button";
import {
@@ -20,6 +21,7 @@ import {
export function ThemeToggle() {
const { theme, setTheme, resolvedTheme } = useTheme();
const [mounted, setMounted] = useState(false);
+ const { t } = useTranslation();
useEffect(() => {
setMounted(true);
@@ -33,7 +35,8 @@ export function ThemeToggle() {