feat(app): add lesson-plans, practice, and grade dashboard routes
- Add admin/lesson-plans, parent/lesson-plans, student/lesson-plans routes - Add student/practice and teacher/practice routes for adaptive practice - Add management/grade/dashboard and management/grade/practice routes - Add teacher/lesson-plans error and loading boundaries - Update existing admin, parent, student, teacher pages with new features - Update globals.css and proxy middleware
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import Link from "next/link"
|
||||
import { BookOpen, PenTool, Library, ArrowRight } from "lucide-react"
|
||||
import { BookOpen, PenTool, Library, ArrowRight, UserX } from "lucide-react"
|
||||
import { getTranslations } from "next-intl/server"
|
||||
|
||||
import { getStudentClasses } from "@/modules/classes/data-access"
|
||||
import { getStudentHomeworkAssignments } from "@/modules/homework/data-access"
|
||||
@@ -7,16 +8,16 @@ import { getCurrentStudentUser } from "@/modules/users/data-access"
|
||||
import { getTextbooks } from "@/modules/textbooks/data-access"
|
||||
import { Card, CardContent, CardHeader, CardTitle } from "@/shared/components/ui/card"
|
||||
import { EmptyState } from "@/shared/components/ui/empty-state"
|
||||
import { UserX } from "lucide-react"
|
||||
|
||||
export const dynamic = "force-dynamic"
|
||||
|
||||
export default async function StudentLearningPage() {
|
||||
const t = await getTranslations("student")
|
||||
const student = await getCurrentStudentUser()
|
||||
if (!student) {
|
||||
return (
|
||||
<div className="space-y-8">
|
||||
<EmptyState title="No user found" description="Create a student user to see learning." icon={UserX} />
|
||||
<EmptyState title={t("learning.noUser")} description={t("learning.noUserDesc")} icon={UserX} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -40,33 +41,33 @@ export default async function StudentLearningPage() {
|
||||
|
||||
const cards = [
|
||||
{
|
||||
title: "Courses",
|
||||
description: "Your enrolled classes.",
|
||||
title: t("learning.courses"),
|
||||
description: t("learning.coursesDesc"),
|
||||
icon: BookOpen,
|
||||
href: "/student/learning/courses",
|
||||
stat: `${classes.length} enrolled`,
|
||||
stat: t("learning.enrolled", { count: classes.length }),
|
||||
},
|
||||
{
|
||||
title: "Assignments",
|
||||
description: "Homework and practice.",
|
||||
title: t("learning.assignments"),
|
||||
description: t("learning.assignmentsDesc"),
|
||||
icon: PenTool,
|
||||
href: "/student/learning/assignments",
|
||||
stat: `${pendingCount} pending${dueSoonCount > 0 ? ` · ${dueSoonCount} due soon` : ""}`,
|
||||
stat: t("learning.pending", { count: pendingCount }) + (dueSoonCount > 0 ? t("learning.dueSoon", { count: dueSoonCount }) : ""),
|
||||
},
|
||||
{
|
||||
title: "Textbooks",
|
||||
description: "Browse course materials.",
|
||||
title: t("learning.textbooks"),
|
||||
description: t("learning.textbooksDesc"),
|
||||
icon: Library,
|
||||
href: "/student/learning/textbooks",
|
||||
stat: `${textbooks.length} available`,
|
||||
stat: t("learning.available", { count: textbooks.length }),
|
||||
},
|
||||
]
|
||||
|
||||
return (
|
||||
<div className="space-y-8">
|
||||
<div>
|
||||
<h2 className="text-2xl font-bold tracking-tight">My Learning</h2>
|
||||
<p className="text-muted-foreground">Your learning hub: courses, assignments, and textbooks.</p>
|
||||
<h2 className="text-2xl font-bold tracking-tight">{t("learning.title")}</h2>
|
||||
<p className="text-muted-foreground">{t("learning.description")}</p>
|
||||
</div>
|
||||
|
||||
<div className="grid gap-6 md:grid-cols-2 lg:grid-cols-3">
|
||||
|
||||
Reference in New Issue
Block a user