This commit is contained in:
@@ -5,26 +5,21 @@ import { ClassAssignmentsWidget } from "@/modules/classes/components/class-detai
|
||||
import { ClassTrendsWidget } from "@/modules/classes/components/class-detail/class-trends-widget"
|
||||
import { ClassHeader } from "@/modules/classes/components/class-detail/class-header"
|
||||
import { ClassOverviewStats } from "@/modules/classes/components/class-detail/class-overview-stats"
|
||||
import { ClassQuickActions } from "@/modules/classes/components/class-detail/class-quick-actions"
|
||||
import { ClassScheduleWidget } from "@/modules/classes/components/class-detail/class-schedule-widget"
|
||||
import { ClassStudentsWidget } from "@/modules/classes/components/class-detail/class-students-widget"
|
||||
|
||||
export const dynamic = "force-dynamic"
|
||||
|
||||
type SearchParams = { [key: string]: string | string[] | undefined }
|
||||
|
||||
export default async function ClassDetailPage({
|
||||
params,
|
||||
searchParams,
|
||||
}: {
|
||||
params: Promise<{ id: string }>
|
||||
searchParams: Promise<SearchParams>
|
||||
}) {
|
||||
const { id } = await params
|
||||
|
||||
// Parallel data fetching
|
||||
const [insights, students, schedule] = await Promise.all([
|
||||
getClassHomeworkInsights({ classId: id, limit: 20 }), // Limit increased to 20 for better list view
|
||||
getClassHomeworkInsights({ classId: id, limit: 20 }),
|
||||
getClassStudents({ classId: id }),
|
||||
getClassSchedule({ classId: id }),
|
||||
])
|
||||
@@ -32,7 +27,7 @@ export default async function ClassDetailPage({
|
||||
if (!insights) return notFound()
|
||||
|
||||
// Fetch subject scores
|
||||
const studentScores = await getClassStudentSubjectScoresV2(id)
|
||||
const studentScores = await getClassStudentSubjectScoresV2({ classId: id })
|
||||
|
||||
// Data mapping for widgets
|
||||
const assignmentSummaries = insights.assignments.map(a => ({
|
||||
@@ -91,10 +86,7 @@ export default async function ClassDetailPage({
|
||||
<div className="grid grid-cols-1 gap-6 lg:grid-cols-3">
|
||||
{/* Main Content Area (Left 2/3) */}
|
||||
<div className="space-y-6 lg:col-span-2">
|
||||
<ClassTrendsWidget
|
||||
classId={insights.class.id}
|
||||
assignments={assignmentSummaries}
|
||||
/>
|
||||
<ClassTrendsWidget assignments={assignmentSummaries} />
|
||||
<ClassStudentsWidget
|
||||
classId={insights.class.id}
|
||||
students={studentSummaries}
|
||||
|
||||
@@ -1,9 +1,5 @@
|
||||
import { eq } from "drizzle-orm"
|
||||
import { getTeacherClasses } from "@/modules/classes/data-access"
|
||||
import { getClassSubjects, getTeacherClasses } from "@/modules/classes/data-access"
|
||||
import { MyClassesGrid } from "@/modules/classes/components/my-classes-grid"
|
||||
import { auth } from "@/auth"
|
||||
import { db } from "@/shared/db"
|
||||
import { grades } from "@/shared/db/schema"
|
||||
|
||||
export const dynamic = "force-dynamic"
|
||||
|
||||
@@ -12,11 +8,11 @@ export default function MyClassesPage() {
|
||||
}
|
||||
|
||||
async function MyClassesPageImpl() {
|
||||
const classes = await getTeacherClasses()
|
||||
const [classes, subjectOptions] = await Promise.all([getTeacherClasses(), getClassSubjects()])
|
||||
|
||||
return (
|
||||
<div className="flex h-full flex-col space-y-4 p-8">
|
||||
<MyClassesGrid classes={classes} canCreateClass={false} />
|
||||
<MyClassesGrid classes={classes} subjectOptions={subjectOptions} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -82,7 +82,6 @@ function StudentsResultsFallback() {
|
||||
|
||||
export default async function StudentsPage({ searchParams }: { searchParams: Promise<SearchParams> }) {
|
||||
const classes = await getTeacherClasses()
|
||||
const params = await searchParams
|
||||
|
||||
// Logic to determine default class (first one available)
|
||||
const defaultClassId = classes.length > 0 ? classes[0].id : undefined
|
||||
|
||||
@@ -1,37 +1,9 @@
|
||||
import { ExamForm } from "@/modules/exams/components/exam-form"
|
||||
import {
|
||||
Breadcrumb,
|
||||
BreadcrumbItem,
|
||||
BreadcrumbLink,
|
||||
BreadcrumbList,
|
||||
BreadcrumbPage,
|
||||
BreadcrumbSeparator,
|
||||
} from "@/shared/components/ui/breadcrumb"
|
||||
|
||||
export default function CreateExamPage() {
|
||||
return (
|
||||
<div className="flex flex-col space-y-8 p-8 max-w-[1200px] mx-auto">
|
||||
<div className="space-y-4">
|
||||
<Breadcrumb>
|
||||
<BreadcrumbList>
|
||||
<BreadcrumbItem>
|
||||
<BreadcrumbLink href="/teacher/exams/all">Exams</BreadcrumbLink>
|
||||
</BreadcrumbItem>
|
||||
<BreadcrumbSeparator />
|
||||
<BreadcrumbItem>
|
||||
<BreadcrumbPage>Create</BreadcrumbPage>
|
||||
</BreadcrumbItem>
|
||||
</BreadcrumbList>
|
||||
</Breadcrumb>
|
||||
|
||||
<div>
|
||||
<h1 className="text-3xl font-bold tracking-tight">Create Exam</h1>
|
||||
<p className="text-muted-foreground mt-2">
|
||||
Set up a new exam draft and choose your assembly method.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div className="flex justify-center items-center min-h-[calc(100vh-160px)] p-8 max-w-[1200px] mx-auto">
|
||||
<ExamForm />
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -5,7 +5,6 @@ import { HomeworkAssignmentExamContentCard } from "@/modules/homework/components
|
||||
import { HomeworkAssignmentQuestionErrorOverviewCard } from "@/modules/homework/components/homework-assignment-question-error-overview-card"
|
||||
import { Badge } from "@/shared/components/ui/badge"
|
||||
import { Button } from "@/shared/components/ui/button"
|
||||
import { Card, CardContent, CardHeader, CardTitle } from "@/shared/components/ui/card"
|
||||
import { formatDate } from "@/shared/lib/utils"
|
||||
import { ChevronLeft, Users, Calendar, BarChart3, CheckCircle2 } from "lucide-react"
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@ import { formatDate } from "@/shared/lib/utils"
|
||||
import { getHomeworkAssignments } from "@/modules/homework/data-access"
|
||||
import { getTeacherClasses } from "@/modules/classes/data-access"
|
||||
import { PenTool, PlusCircle } from "lucide-react"
|
||||
import { getTeacherIdForMutations } from "@/modules/classes/data-access"
|
||||
|
||||
export const dynamic = "force-dynamic"
|
||||
|
||||
@@ -27,9 +28,10 @@ const getParam = (params: SearchParams, key: string) => {
|
||||
export default async function AssignmentsPage({ searchParams }: { searchParams: Promise<SearchParams> }) {
|
||||
const sp = await searchParams
|
||||
const classId = getParam(sp, "classId") || undefined
|
||||
const creatorId = await getTeacherIdForMutations()
|
||||
|
||||
const [assignments, classes] = await Promise.all([
|
||||
getHomeworkAssignments({ classId: classId && classId !== "all" ? classId : undefined }),
|
||||
getHomeworkAssignments({ creatorId, classId: classId && classId !== "all" ? classId : undefined }),
|
||||
classId && classId !== "all" ? getTeacherClasses() : Promise.resolve([]),
|
||||
])
|
||||
const hasAssignments = assignments.length > 0
|
||||
|
||||
@@ -23,6 +23,7 @@ async function QuestionBankResults({ searchParams }: { searchParams: Promise<Sea
|
||||
const q = getParam(params, "q")
|
||||
const type = getParam(params, "type")
|
||||
const difficulty = getParam(params, "difficulty")
|
||||
const knowledgePointId = getParam(params, "kp")
|
||||
|
||||
const questionType: QuestionType | undefined =
|
||||
type === "single_choice" ||
|
||||
@@ -37,10 +38,16 @@ async function QuestionBankResults({ searchParams }: { searchParams: Promise<Sea
|
||||
q: q || undefined,
|
||||
type: questionType,
|
||||
difficulty: difficulty && difficulty !== "all" ? Number(difficulty) : undefined,
|
||||
knowledgePointId: knowledgePointId && knowledgePointId !== "all" ? knowledgePointId : undefined,
|
||||
pageSize: 200,
|
||||
})
|
||||
|
||||
const hasFilters = Boolean(q || (type && type !== "all") || (difficulty && difficulty !== "all"))
|
||||
const hasFilters = Boolean(
|
||||
q ||
|
||||
(type && type !== "all") ||
|
||||
(difficulty && difficulty !== "all") ||
|
||||
(knowledgePointId && knowledgePointId !== "all")
|
||||
)
|
||||
|
||||
if (questions.length === 0) {
|
||||
return (
|
||||
|
||||
Reference in New Issue
Block a user