homework: - Add data-access-scans, data-access-student, data-access-utils, data-access-exam-cross - Add excellent-submissions, homework-take-confirm-dialog, homework-take-sidebar components classes: - Add class-delete-dialog, class-error-boundary, class-form-dialog, class-form-utils - Add class-list-table, class-list-toolbar, class-skeleton - Add schedule-create-dialog, schedule-delete-dialog, schedule-edit-dialog, schedule-utils - Add data-access-teacher and hooks directory course-plans: - Add course-plan-calendar, sortable-week-row, template-picker-dialog components - Add lib directory
153 lines
4.5 KiB
TypeScript
153 lines
4.5 KiB
TypeScript
"use client"
|
|
|
|
import { useMemo } from "react"
|
|
import { toast } from "sonner"
|
|
import { useRouter } from "next/navigation"
|
|
import { useTranslations } from "next-intl"
|
|
|
|
import type { AdminClassListItem, TeacherOption } from "../types"
|
|
import { createGradeClassAction, deleteGradeClassAction, updateGradeClassAction } from "../actions"
|
|
import { useClassData } from "../hooks/use-class-data"
|
|
import { ClassDeleteDialog } from "./class-delete-dialog"
|
|
import { ClassFormDialog } from "./class-form-dialog"
|
|
import { ClassListTable } from "./class-list-table"
|
|
import { ClassListToolbar } from "./class-list-toolbar"
|
|
|
|
export function GradeClassesClient({
|
|
classes,
|
|
teachers,
|
|
managedGrades,
|
|
}: {
|
|
classes: AdminClassListItem[]
|
|
teachers: TeacherOption[]
|
|
managedGrades: { id: string; name: string; schoolId: string; schoolName: string | null }[]
|
|
}) {
|
|
const t = useTranslations("classes")
|
|
const router = useRouter()
|
|
const defaultTeacherId = useMemo(() => teachers[0]?.id ?? "", [teachers])
|
|
const defaultGradeId = useMemo(() => managedGrades[0]?.id ?? "", [managedGrades])
|
|
const data = useClassData({ defaultTeacherId, defaultGradeId })
|
|
|
|
const handleCreate = async (formData: FormData): Promise<void> => {
|
|
data.setIsWorking(true)
|
|
try {
|
|
const res = await createGradeClassAction(undefined, formData)
|
|
if (res.success) {
|
|
toast.success(res.message)
|
|
data.setCreateOpen(false)
|
|
router.refresh()
|
|
} else {
|
|
toast.error(res.message || t("list.failedCreate"))
|
|
}
|
|
} catch {
|
|
toast.error(t("list.failedCreate"))
|
|
} finally {
|
|
data.setIsWorking(false)
|
|
}
|
|
}
|
|
|
|
const handleUpdate = async (formData: FormData): Promise<void> => {
|
|
if (!data.editItem) return
|
|
data.setIsWorking(true)
|
|
try {
|
|
const res = await updateGradeClassAction(data.editItem.id, undefined, formData)
|
|
if (res.success) {
|
|
toast.success(res.message)
|
|
data.setEditItem(null)
|
|
router.refresh()
|
|
} else {
|
|
toast.error(res.message || t("list.failedUpdate"))
|
|
}
|
|
} catch {
|
|
toast.error(t("list.failedUpdate"))
|
|
} finally {
|
|
data.setIsWorking(false)
|
|
}
|
|
}
|
|
|
|
const handleDelete = async (): Promise<void> => {
|
|
if (!data.deleteItem) return
|
|
data.setIsWorking(true)
|
|
try {
|
|
const res = await deleteGradeClassAction(data.deleteItem.id)
|
|
if (res.success) {
|
|
toast.success(res.message)
|
|
data.setDeleteItem(null)
|
|
router.refresh()
|
|
} else {
|
|
toast.error(res.message || t("list.failedDelete"))
|
|
}
|
|
} catch {
|
|
toast.error(t("list.failedDelete"))
|
|
} finally {
|
|
data.setIsWorking(false)
|
|
}
|
|
}
|
|
|
|
return (
|
|
<>
|
|
<ClassListToolbar
|
|
count={classes.length}
|
|
onNew={() => data.setCreateOpen(true)}
|
|
isWorking={data.isWorking}
|
|
disabled={managedGrades.length === 0}
|
|
/>
|
|
|
|
<ClassListTable
|
|
classes={classes}
|
|
onEdit={data.setEditItem}
|
|
onDelete={data.setDeleteItem}
|
|
isWorking={data.isWorking}
|
|
emptyDescription={managedGrades.length === 0 ? t("grade.noManagedGradesDescription") : undefined}
|
|
/>
|
|
|
|
<ClassFormDialog
|
|
open={data.createOpen}
|
|
onOpenChange={data.setCreateOpen}
|
|
mode="create"
|
|
teachers={teachers}
|
|
grades={managedGrades}
|
|
onSubmit={handleCreate}
|
|
isWorking={data.isWorking}
|
|
teacherId={data.createTeacherId}
|
|
schoolId={data.createSchoolId}
|
|
gradeId={data.createGradeId}
|
|
onTeacherIdChange={data.setCreateTeacherId}
|
|
onSchoolIdChange={data.setCreateSchoolId}
|
|
onGradeIdChange={data.setCreateGradeId}
|
|
/>
|
|
|
|
<ClassFormDialog
|
|
open={Boolean(data.editItem)}
|
|
onOpenChange={(o) => {
|
|
if (!o) data.setEditItem(null)
|
|
}}
|
|
mode="edit"
|
|
editItem={data.editItem}
|
|
teachers={teachers}
|
|
grades={managedGrades}
|
|
onSubmit={handleUpdate}
|
|
isWorking={data.isWorking}
|
|
teacherId={data.editTeacherId}
|
|
schoolId={data.editSchoolId}
|
|
gradeId={data.editGradeId}
|
|
subjectTeachers={data.editSubjectTeachers}
|
|
onTeacherIdChange={data.setEditTeacherId}
|
|
onSchoolIdChange={data.setEditSchoolId}
|
|
onGradeIdChange={data.setEditGradeId}
|
|
onSubjectTeacherChange={data.setSubjectTeacher}
|
|
/>
|
|
|
|
<ClassDeleteDialog
|
|
open={Boolean(data.deleteItem)}
|
|
onOpenChange={(o) => {
|
|
if (!o) data.setDeleteItem(null)
|
|
}}
|
|
item={data.deleteItem}
|
|
onConfirm={handleDelete}
|
|
isWorking={data.isWorking}
|
|
/>
|
|
</>
|
|
)
|
|
}
|