|
3 | 3 | import { Button } from "@/components/ui/button"; |
4 | 4 | import { Field } from "@/components/ui/field"; |
5 | 5 | import { toaster, Toaster } from "@/components/ui/toaster"; |
| 6 | +import { createClient } from "@/utils/supabase/client"; |
6 | 7 | import type { GradingAssignmentDefaultProfile } from "@/utils/supabase/DatabaseTypes"; |
7 | 8 | import { |
8 | 9 | Box, |
@@ -77,6 +78,14 @@ const normalizeCcEmails = (value: unknown): GradingCcEmails => { |
77 | 78 |
|
78 | 79 | const toCcText = (value: unknown): string => normalizeCcEmails(value).emails.join(", "); |
79 | 80 |
|
| 81 | +const numberInputValueAs = (emptyFallback: number | null) => (value: unknown) => { |
| 82 | + if (value === "" || value === null || value === undefined) { |
| 83 | + return emptyFallback; |
| 84 | + } |
| 85 | + const n = Number(value); |
| 86 | + return Number.isFinite(n) ? n : emptyFallback; |
| 87 | +}; |
| 88 | + |
80 | 89 | export default function GradingAssignmentDefaultsPage() { |
81 | 90 | const { course_id } = useParams(); |
82 | 91 | const classId = Number(course_id); |
@@ -182,7 +191,26 @@ export default function GradingAssignmentDefaultsPage() { |
182 | 191 | }); |
183 | 192 |
|
184 | 193 | const handleDelete = async (id: number) => { |
185 | | - const confirmed = window.confirm("Delete this grading default profile?"); |
| 194 | + const supabase = createClient(); |
| 195 | + const { count, error: countError } = await supabase |
| 196 | + .from("assignments") |
| 197 | + .select("*", { count: "exact", head: true }) |
| 198 | + .eq("grading_default_profile_id", id); |
| 199 | + |
| 200 | + if (countError) { |
| 201 | + toaster.error({ |
| 202 | + title: "Could not check assignment references", |
| 203 | + description: countError.message |
| 204 | + }); |
| 205 | + return; |
| 206 | + } |
| 207 | + |
| 208 | + const refCount = count ?? 0; |
| 209 | + const refNote = |
| 210 | + refCount > 0 |
| 211 | + ? ` ${refCount} assignment${refCount === 1 ? "" : "s"} reference this profile; those assignments will show no saved profile after deletion.` |
| 212 | + : ""; |
| 213 | + const confirmed = window.confirm(`Delete this grading default profile?${refNote}`); |
186 | 214 | if (!confirmed) { |
187 | 215 | return; |
188 | 216 | } |
@@ -287,8 +315,8 @@ export default function GradingAssignmentDefaultsPage() { |
287 | 315 | <Input |
288 | 316 | type="number" |
289 | 317 | {...register("auto_assign_review_due_hours", { |
290 | | - valueAsNumber: true, |
291 | | - min: { value: 0, message: "Must be at least 0 hours" } |
| 318 | + min: { value: 0, message: "Must be at least 0 hours" }, |
| 319 | + setValueAs: numberInputValueAs(72) |
292 | 320 | })} |
293 | 321 | /> |
294 | 322 | </Field> |
@@ -326,8 +354,8 @@ export default function GradingAssignmentDefaultsPage() { |
326 | 354 | <Input |
327 | 355 | type="number" |
328 | 356 | {...register("late_grading_reminder_interval_hours", { |
329 | | - valueAsNumber: true, |
330 | | - min: { value: 1, message: "Must be at least 1 hour" } |
| 357 | + min: { value: 1, message: "Must be at least 1 hour" }, |
| 358 | + setValueAs: numberInputValueAs(null) |
331 | 359 | })} |
332 | 360 | /> |
333 | 361 | </Field> |
|
0 commit comments