fix exam grading
This commit is contained in:
@@ -1299,7 +1299,7 @@ export function AdminClassAssignmentPage() {
|
||||
const [schoolYears, setSchoolYears] = useState<string[]>([])
|
||||
const [selectedYear, setSelectedYear] = useState('')
|
||||
const [loading, setLoading] = useState(true)
|
||||
const [message, setMessage] = useState<string | null>(null)
|
||||
const [message] = useState<string | null>(null)
|
||||
const [error, setError] = useState<string | null>(null)
|
||||
const [selectedSemester, setSelectedSemester] = useState('')
|
||||
const [expandedSections, setExpandedSections] = useState<Set<string>>(new Set(['0']))
|
||||
@@ -1818,17 +1818,6 @@ export function AdminDailyAttendancePage() {
|
||||
})),
|
||||
)
|
||||
}, [normalizedSearch, sections])
|
||||
const studentSuggestions = useMemo(() => {
|
||||
const seen = new Set<string>()
|
||||
return sections.flatMap((section) =>
|
||||
section.students.flatMap((student) => {
|
||||
const label = `${student.schoolId} - ${student.name}${section.className ? ` (${section.className})` : ''}`
|
||||
if (seen.has(label)) return []
|
||||
seen.add(label)
|
||||
return [label]
|
||||
}),
|
||||
)
|
||||
}, [sections])
|
||||
const selectedSearchMatch = searchMatches[0] ?? null
|
||||
const displayedGrade = gradeGroups.find((group) => group.key === activeGradeKey) ?? gradeGroups[0]
|
||||
const gradeSections = displayedGrade?.sections ?? []
|
||||
@@ -1984,7 +1973,9 @@ export function AdminDailyAttendancePage() {
|
||||
if (!current) return current
|
||||
const secId = String(section.sectionId)
|
||||
const stuId = String(student.id)
|
||||
const prevEntries: typeof current.attendance_data = JSON.parse(JSON.stringify(current.attendance_data ?? {}))
|
||||
const prevEntries = JSON.parse(
|
||||
JSON.stringify(current.attendance_data ?? {}),
|
||||
) as NonNullable<typeof current.attendance_data>
|
||||
if (!prevEntries[secId]) prevEntries[secId] = {}
|
||||
const existing = (prevEntries[secId][stuId] ?? []).filter((e) => String(e.date ?? '').slice(0, 10) !== date)
|
||||
prevEntries[secId][stuId] = [
|
||||
@@ -2457,7 +2448,6 @@ export function AdminDailyAttendanceAnalysisPage() {
|
||||
|
||||
export function AdminExamDraftsPage() {
|
||||
const [data, setData] = useState<Awaited<ReturnType<typeof fetchExamDraftAdminData>> | null>(null)
|
||||
const [loading, setLoading] = useState(true)
|
||||
const [error, setError] = useState<string | null>(null)
|
||||
const [message, setMessage] = useState<string | null>(null)
|
||||
const [activeTab, setActiveTab] = useState<'submissions' | 'legacy'>('submissions')
|
||||
@@ -2471,7 +2461,6 @@ export function AdminExamDraftsPage() {
|
||||
const [reviewState, setReviewState] = useState<Record<number, { review_status: string; admin_comments: string; final_file: File | null }>>({})
|
||||
|
||||
async function load() {
|
||||
setLoading(true)
|
||||
try {
|
||||
const result = await fetchExamDraftAdminData()
|
||||
setData(result)
|
||||
@@ -2483,8 +2472,6 @@ export function AdminExamDraftsPage() {
|
||||
setError(null)
|
||||
} catch (e) {
|
||||
setError(e instanceof Error ? e.message : 'Unable to load exam drafts.')
|
||||
} finally {
|
||||
setLoading(false)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3324,7 +3311,15 @@ export function AdminManageUsersPage() {
|
||||
<td>{id}</td>
|
||||
<td>{name || '—'}</td>
|
||||
<td>{String(user.email ?? '—')}</td>
|
||||
<td>{(row.roles ?? []).map((r) => String(r.name ?? '')).filter(Boolean).join(', ') || '—'}</td>
|
||||
<td>
|
||||
{(row.roles ?? [])
|
||||
.map((role) => {
|
||||
if (typeof role === 'string') return role
|
||||
return String(role.name ?? role.slug ?? '')
|
||||
})
|
||||
.filter(Boolean)
|
||||
.join(', ') || '—'}
|
||||
</td>
|
||||
<td><button className="btn btn-sm btn-danger" type="button" onClick={() => void deleteUser(id).then(load)}>Delete</button></td>
|
||||
</tr>
|
||||
)
|
||||
@@ -3594,13 +3589,27 @@ export function AdminPaypalTransactionsPage() {
|
||||
)
|
||||
}
|
||||
|
||||
function submissionBadgeClass(status?: string | null) {
|
||||
const normalized = String(status ?? '').toLowerCase()
|
||||
if (normalized === 'submitted') return 'bg-success'
|
||||
if (normalized === 'partial') return 'bg-warning text-dark'
|
||||
function submissionBadgeClass(status?: {
|
||||
label?: string | null
|
||||
badge?: string | null
|
||||
completed?: boolean
|
||||
} | null) {
|
||||
const badge = String(status?.badge ?? '').trim()
|
||||
if (badge !== '') return badge
|
||||
if (status?.completed === true) return 'bg-success'
|
||||
if (status?.completed === false) return 'bg-danger'
|
||||
return 'bg-secondary'
|
||||
}
|
||||
|
||||
function submissionBadgeLabel(status?: {
|
||||
label?: string | null
|
||||
detail?: string | null
|
||||
} | null) {
|
||||
const label = String(status?.label ?? '').trim() || 'Missing'
|
||||
const detail = String(status?.detail ?? '').trim()
|
||||
return detail !== '' ? `${label} (${detail})` : label
|
||||
}
|
||||
|
||||
export function AdminRemovedStudentsPage() {
|
||||
const [schoolYear, setSchoolYear] = useState('')
|
||||
const [activeStudents, setActiveStudents] = useState<RemovedStudentRow[]>([])
|
||||
@@ -4830,11 +4839,11 @@ export function AdminTeacherSubmissionsPage() {
|
||||
</td>
|
||||
<td>{row.class_section ?? '—'}</td>
|
||||
<td>{(row.teachers ?? []).map((teacher) => teacher.label).join(', ') || '—'}</td>
|
||||
<td><span className={`badge ${submissionBadgeClass(row.midterm_score_status)}`}>{row.midterm_score_status ?? 'missing'}</span></td>
|
||||
<td><span className={`badge ${submissionBadgeClass(row.midterm_comment_status)}`}>{row.midterm_comment_status ?? 'missing'}</span></td>
|
||||
<td><span className={`badge ${submissionBadgeClass(row.participation_status)}`}>{row.participation_status ?? 'missing'}</span></td>
|
||||
<td><span className={`badge ${submissionBadgeClass(row.ptap_comment_status)}`}>{row.ptap_comment_status ?? 'missing'}</span></td>
|
||||
<td><span className={`badge ${submissionBadgeClass(row.attendance_status)}`}>{row.attendance_status ?? 'missing'}</span></td>
|
||||
<td><span className={`badge ${submissionBadgeClass(row.midterm_score_status)}`}>{submissionBadgeLabel(row.midterm_score_status)}</span></td>
|
||||
<td><span className={`badge ${submissionBadgeClass(row.midterm_comment_status)}`}>{submissionBadgeLabel(row.midterm_comment_status)}</span></td>
|
||||
<td><span className={`badge ${submissionBadgeClass(row.participation_status)}`}>{submissionBadgeLabel(row.participation_status)}</span></td>
|
||||
<td><span className={`badge ${submissionBadgeClass(row.ptap_comment_status)}`}>{submissionBadgeLabel(row.ptap_comment_status)}</span></td>
|
||||
<td><span className={`badge ${submissionBadgeClass(row.attendance_status)}`}>{submissionBadgeLabel(row.attendance_status)}</span></td>
|
||||
<td>{(row.missing_items ?? []).join(', ') || '—'}</td>
|
||||
<td>{row.student_count ?? 0}</td>
|
||||
</tr>
|
||||
|
||||
Reference in New Issue
Block a user