diff --git a/src/app/(dashboard)/student/dashboard/page.tsx b/src/app/(dashboard)/student/dashboard/page.tsx
index 8dded85..251c0e6 100644
--- a/src/app/(dashboard)/student/dashboard/page.tsx
+++ b/src/app/(dashboard)/student/dashboard/page.tsx
@@ -1,6 +1,7 @@
import { StudentDashboard } from "@/modules/dashboard/components/student-dashboard/student-dashboard-view"
import { getStudentClasses, getStudentSchedule } from "@/modules/classes/data-access"
-import { getDemoStudentUser, getStudentDashboardGrades, getStudentHomeworkAssignments } from "@/modules/homework/data-access"
+import { getStudentDashboardGrades, getStudentHomeworkAssignments } from "@/modules/homework/data-access"
+import { getCurrentStudentUser } from "@/modules/users/data-access"
import { EmptyState } from "@/shared/components/ui/empty-state"
import { Inbox } from "lucide-react"
@@ -12,7 +13,7 @@ const toWeekday = (d: Date): 1 | 2 | 3 | 4 | 5 | 6 | 7 => {
}
export default async function StudentDashboardPage() {
- const student = await getDemoStudentUser()
+ const student = await getCurrentStudentUser()
if (!student) {
return (
diff --git a/src/app/(dashboard)/student/elective/page.tsx b/src/app/(dashboard)/student/elective/page.tsx
index 438856e..3bb85dc 100644
--- a/src/app/(dashboard)/student/elective/page.tsx
+++ b/src/app/(dashboard)/student/elective/page.tsx
@@ -1,31 +1,13 @@
-import { auth } from "@/auth"
-import { Inbox } from "lucide-react"
+import { getAuthContext } from "@/shared/lib/auth-guard"
import { getAvailableCoursesForStudent, getStudentSelections } from "@/modules/elective/data-access-selections"
import { StudentSelectionView } from "@/modules/elective/components/student-selection-view"
-import { EmptyState } from "@/shared/components/ui/empty-state"
export const dynamic = "force-dynamic"
export default async function StudentElectivePage() {
- const session = await auth()
- const studentId = String(session?.user?.id ?? "")
-
- if (!studentId) {
- return (
-
-
-
Elective Courses
-
Browse and select elective courses.
-
-
-
- )
- }
+ const ctx = await getAuthContext()
+ const studentId = ctx.userId
const [availableCourses, mySelections] = await Promise.all([
getAvailableCoursesForStudent(studentId),
diff --git a/src/app/(dashboard)/student/learning/assignments/[assignmentId]/page.tsx b/src/app/(dashboard)/student/learning/assignments/[assignmentId]/page.tsx
index 6f64c1c..fed8879 100644
--- a/src/app/(dashboard)/student/learning/assignments/[assignmentId]/page.tsx
+++ b/src/app/(dashboard)/student/learning/assignments/[assignmentId]/page.tsx
@@ -1,6 +1,7 @@
import { notFound } from "next/navigation"
-import { getDemoStudentUser, getStudentHomeworkTakeData } from "@/modules/homework/data-access"
+import { getStudentHomeworkTakeData } from "@/modules/homework/data-access"
+import { getCurrentStudentUser } from "@/modules/users/data-access"
import { HomeworkTakeView } from "@/modules/homework/components/homework-take-view"
import { HomeworkReviewView } from "@/modules/homework/components/student-homework-review-view"
import { formatDate } from "@/shared/lib/utils"
@@ -13,7 +14,7 @@ export default async function StudentAssignmentTakePage({
params: Promise<{ assignmentId: string }>
}) {
const { assignmentId } = await params
- const student = await getDemoStudentUser()
+ const student = await getCurrentStudentUser()
if (!student) return notFound()
const data = await getStudentHomeworkTakeData(assignmentId, student.id)
diff --git a/src/app/(dashboard)/student/learning/assignments/page.tsx b/src/app/(dashboard)/student/learning/assignments/page.tsx
index bb5805d..3a04bb6 100644
--- a/src/app/(dashboard)/student/learning/assignments/page.tsx
+++ b/src/app/(dashboard)/student/learning/assignments/page.tsx
@@ -5,7 +5,8 @@ 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 { getDemoStudentUser, getStudentHomeworkAssignments } from "@/modules/homework/data-access"
+import { getStudentHomeworkAssignments } from "@/modules/homework/data-access"
+import { getCurrentStudentUser } from "@/modules/users/data-access"
import { Inbox } from "lucide-react"
export const dynamic = "force-dynamic"
@@ -39,7 +40,7 @@ const getActionVariant = (status: string): "default" | "secondary" | "outline" =
const isAnswered = (status: string) => status === "submitted" || status === "graded"
export default async function StudentAssignmentsPage() {
- const student = await getDemoStudentUser()
+ const student = await getCurrentStudentUser()
if (!student) {
return (
diff --git a/src/app/(dashboard)/student/learning/courses/page.tsx b/src/app/(dashboard)/student/learning/courses/page.tsx
index 1d676d5..a7cd409 100644
--- a/src/app/(dashboard)/student/learning/courses/page.tsx
+++ b/src/app/(dashboard)/student/learning/courses/page.tsx
@@ -1,14 +1,14 @@
import { Inbox } from "lucide-react"
import { getStudentClasses } from "@/modules/classes/data-access"
-import { getDemoStudentUser } from "@/modules/homework/data-access"
+import { getCurrentStudentUser } from "@/modules/users/data-access"
import { StudentCoursesView } from "@/modules/student/components/student-courses-view"
import { EmptyState } from "@/shared/components/ui/empty-state"
export const dynamic = "force-dynamic"
export default async function StudentCoursesPage() {
- const student = await getDemoStudentUser()
+ const student = await getCurrentStudentUser()
if (!student) {
return (
diff --git a/src/app/(dashboard)/student/learning/textbooks/[id]/page.tsx b/src/app/(dashboard)/student/learning/textbooks/[id]/page.tsx
index c0f26ee..793a0c5 100644
--- a/src/app/(dashboard)/student/learning/textbooks/[id]/page.tsx
+++ b/src/app/(dashboard)/student/learning/textbooks/[id]/page.tsx
@@ -6,7 +6,7 @@ import { getTextbookById, getChaptersByTextbookId, getKnowledgePointsByTextbookI
import { TextbookReader } from "@/modules/textbooks/components/textbook-reader"
import { Badge } from "@/shared/components/ui/badge"
import { EmptyState } from "@/shared/components/ui/empty-state"
-import { getDemoStudentUser } from "@/modules/homework/data-access"
+import { getCurrentStudentUser } from "@/modules/users/data-access"
export const dynamic = "force-dynamic"
@@ -15,7 +15,7 @@ export default async function StudentTextbookDetailPage({
}: {
params: Promise<{ id: string }>
}) {
- const student = await getDemoStudentUser()
+ const student = await getCurrentStudentUser()
if (!student) {
return (
diff --git a/src/app/(dashboard)/student/learning/textbooks/page.tsx b/src/app/(dashboard)/student/learning/textbooks/page.tsx
index 1910e1c..208f947 100644
--- a/src/app/(dashboard)/student/learning/textbooks/page.tsx
+++ b/src/app/(dashboard)/student/learning/textbooks/page.tsx
@@ -3,7 +3,7 @@ import { BookOpen, Inbox } from "lucide-react"
import { getTextbooks } from "@/modules/textbooks/data-access"
import { TextbookCard } from "@/modules/textbooks/components/textbook-card"
import { TextbookFilters } from "@/modules/textbooks/components/textbook-filters"
-import { getDemoStudentUser } from "@/modules/homework/data-access"
+import { getCurrentStudentUser } from "@/modules/users/data-access"
import { EmptyState } from "@/shared/components/ui/empty-state"
export const dynamic = "force-dynamic"
@@ -20,7 +20,7 @@ export default async function StudentTextbooksPage({
}: {
searchParams: Promise
}) {
- const [student, sp] = await Promise.all([getDemoStudentUser(), searchParams])
+ const [student, sp] = await Promise.all([getCurrentStudentUser(), searchParams])
if (!student) {
return (
diff --git a/src/app/(dashboard)/student/schedule/page.tsx b/src/app/(dashboard)/student/schedule/page.tsx
index 7440997..13a6238 100644
--- a/src/app/(dashboard)/student/schedule/page.tsx
+++ b/src/app/(dashboard)/student/schedule/page.tsx
@@ -1,7 +1,7 @@
import { Inbox } from "lucide-react"
import { getStudentClasses, getStudentSchedule } from "@/modules/classes/data-access"
-import { getDemoStudentUser } from "@/modules/homework/data-access"
+import { getCurrentStudentUser } from "@/modules/users/data-access"
import { StudentScheduleFilters } from "@/modules/student/components/student-schedule-filters"
import { StudentScheduleView } from "@/modules/student/components/student-schedule-view"
import { EmptyState } from "@/shared/components/ui/empty-state"
@@ -15,7 +15,7 @@ export default async function StudentSchedulePage({
}: {
searchParams: Promise
}) {
- const student = await getDemoStudentUser()
+ const student = await getCurrentStudentUser()
if (!student) {
return (
diff --git a/src/modules/announcements/actions.ts b/src/modules/announcements/actions.ts
index 8c96067..809298d 100644
--- a/src/modules/announcements/actions.ts
+++ b/src/modules/announcements/actions.ts
@@ -3,7 +3,7 @@
import { revalidatePath } from "next/cache"
import { createId } from "@paralleldrive/cuid2"
-import { requireAuth, requirePermission, PermissionDeniedError } from "@/shared/lib/auth-guard"
+import { requirePermission, PermissionDeniedError } from "@/shared/lib/auth-guard"
import { Permissions } from "@/shared/types/permissions"
import type { ActionState } from "@/shared/types/action-state"
@@ -218,7 +218,7 @@ export async function getAnnouncementsAction(
params?: GetAnnouncementsParams
): Promise
> {
try {
- await requireAuth()
+ await requirePermission(Permissions.ANNOUNCEMENT_READ)
const data = await getAnnouncements(params)
return { success: true, data }
} catch (e) {
diff --git a/src/modules/announcements/data-access.ts b/src/modules/announcements/data-access.ts
index 2df4332..0826a5d 100644
--- a/src/modules/announcements/data-access.ts
+++ b/src/modules/announcements/data-access.ts
@@ -8,8 +8,6 @@ import { announcements, users } from "@/shared/db/schema"
import type {
Announcement,
AnnouncementInsertData,
- AnnouncementStatus,
- AnnouncementType,
AnnouncementUpdateData,
GetAnnouncementsParams,
} from "./types"
@@ -17,6 +15,8 @@ import type {
const toIso = (d: Date | null | undefined): string | null =>
d ? d.toISOString() : null
+const toIsoRequired = (d: Date): string => d.toISOString()
+
const mapRow = (
row: {
id: string
@@ -43,8 +43,8 @@ const mapRow = (
authorId: row.authorId,
authorName: row.authorName,
publishedAt: toIso(row.publishedAt),
- createdAt: toIso(row.createdAt) as string,
- updatedAt: toIso(row.updatedAt) as string,
+ createdAt: toIsoRequired(row.createdAt),
+ updatedAt: toIsoRequired(row.updatedAt),
})
export const getAnnouncements = cache(
@@ -56,10 +56,10 @@ export const getAnnouncements = cache(
const conditions = []
if (params?.status) {
- conditions.push(eq(announcements.status, params.status as AnnouncementStatus))
+ conditions.push(eq(announcements.status, params.status))
}
if (params?.type) {
- conditions.push(eq(announcements.type, params.type as AnnouncementType))
+ conditions.push(eq(announcements.type, params.type))
}
const rows = await db
@@ -85,7 +85,8 @@ export const getAnnouncements = cache(
.offset(offset)
return rows.map(mapRow)
- } catch {
+ } catch (error) {
+ console.error("getAnnouncements failed:", error)
return []
}
}
@@ -115,7 +116,8 @@ export const getAnnouncementById = cache(
.limit(1)
return row ? mapRow(row) : null
- } catch {
+ } catch (error) {
+ console.error("getAnnouncementById failed:", error)
return null
}
}
diff --git a/src/modules/attendance/components/attendance-sheet.tsx b/src/modules/attendance/components/attendance-sheet.tsx
index 8036835..7a66c4e 100644
--- a/src/modules/attendance/components/attendance-sheet.tsx
+++ b/src/modules/attendance/components/attendance-sheet.tsx
@@ -43,6 +43,9 @@ const STATUS_OPTIONS: AttendanceStatus[] = [
"excused",
]
+const isAttendanceStatus = (v: string): v is AttendanceStatus =>
+ v === "present" || v === "absent" || v === "late" || v === "early_leave" || v === "excused"
+
function SubmitButton() {
const { pending } = useFormStatus()
return (
@@ -180,7 +183,11 @@ export function AttendanceSheet({