Files
NextEdu/src/modules/student/components/student-schedule-view.tsx
SpecialX 8c2fe14c20 refactor(modules): update classes, course-plans, diagnostic, questions, settings, student, layout
- Update classes data-access (invitations, main) for invitation management

- Update course-plans actions, data-access, and types

- Update diagnostic data-access for report queries

- Update questions data-access for question bank queries

- Update settings actions, ai-provider-settings-card, data-access, and types

- Update student course-filters, student-courses-view, student-schedule-filters, student-schedule-view

- Update layout app-sidebar, site-header, and navigation config
2026-06-24 12:03:35 +08:00

98 lines
3.2 KiB
TypeScript

import { Card, CardContent, CardHeader, CardTitle } from "@/shared/components/ui/card"
import { EmptyState } from "@/shared/components/ui/empty-state"
import { CalendarX } from "lucide-react"
import { ScheduleList } from "@/shared/components/schedule/schedule-list"
import { cn } from "@/shared/lib/utils"
import { useTranslations } from "next-intl"
import type { StudentScheduleItem } from "@/modules/classes/types"
const WEEKDAY_KEYS: Array<{ key: 1 | 2 | 3 | 4 | 5 | 6 | 7; label: string }> = [
{ key: 1, label: "mon" },
{ key: 2, label: "tue" },
{ key: 3, label: "wed" },
{ key: 4, label: "thu" },
{ key: 5, label: "fri" },
{ key: 6, label: "sat" },
{ key: 7, label: "sun" },
]
const getTodayWeekday = (): 1 | 2 | 3 | 4 | 5 | 6 | 7 => {
// getDay() returns 0 (Sun) - 6 (Sat); convert to 1 (Mon) - 7 (Sun)
const WEEKDAY_MAP = [7, 1, 2, 3, 4, 5, 6] as const
const day = new Date().getDay()
if (day < 0 || day > 6) {
throw new Error(`Invalid day from getDay(): ${day}`)
}
return WEEKDAY_MAP[day]
}
export function StudentScheduleView({ items }: { items: StudentScheduleItem[] }) {
const t = useTranslations("student")
if (items.length === 0) {
return (
<EmptyState
icon={CalendarX}
title={t("scheduleView.noSchedule")}
description={t("scheduleView.noScheduleDesc")}
className="h-80"
/>
)
}
const todayKey = getTodayWeekday()
const itemsByDay = new Map<number, StudentScheduleItem[]>()
for (const item of items) {
const list = itemsByDay.get(item.weekday) ?? []
list.push(item)
itemsByDay.set(item.weekday, list)
}
for (const list of itemsByDay.values()) {
list.sort((a, b) => a.startTime.localeCompare(b.startTime))
}
return (
<div className="grid gap-4 lg:grid-cols-2">
{WEEKDAY_KEYS.map((d) => {
const dayItems = itemsByDay.get(d.key) ?? []
const isToday = d.key === todayKey
return (
<Card
key={d.key}
className={cn(
isToday && "border-primary ring-1 ring-primary/30 shadow-sm"
)}
>
<CardHeader className="pb-3">
<CardTitle className="flex items-center gap-2 text-sm font-medium">
<span>{t(`weekdays.${d.label}`)}</span>
{isToday && (
<span className="rounded-full bg-primary px-2 py-0.5 text-[10px] font-semibold uppercase tracking-wide text-primary-foreground">
{t("scheduleView.today")}
</span>
)}
</CardTitle>
</CardHeader>
<CardContent>
{dayItems.length === 0 ? (
<div className="text-sm text-muted-foreground">{t("scheduleView.noClasses")}</div>
) : (
<ScheduleList
items={dayItems.map((item) => ({
...item,
href: `/student/learning/courses/${encodeURIComponent(item.classId)}`,
}))}
variant="card"
spacingClassName="space-y-3"
/>
)}
</CardContent>
</Card>
)
})}
</div>
)
}