Skip to content

Commit 49b0692

Browse files
committed
feedback
1 parent 6caafa8 commit 49b0692

7 files changed

Lines changed: 598 additions & 379 deletions

File tree

app/course/[course_id]/manage/assignments/[assignment_id]/edit/page.tsx

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -99,11 +99,16 @@ export default function EditAssignment() {
9999
values.eval_config = undefined;
100100
values.allow_early = undefined;
101101
values.deadline_offset = undefined;
102+
const reminderInterval = values.late_grading_reminder_interval_hours;
102103
values.late_grading_reminder_interval_hours = values.late_grading_reminders_enabled
103-
? (values.late_grading_reminder_interval_hours ?? 12)
104+
? typeof reminderInterval === "number" && Number.isFinite(reminderInterval)
105+
? reminderInterval
106+
: 12
104107
: null;
105-
values.late_grading_reply_to = values.late_grading_reply_to || null;
106-
values.late_grading_cc_emails = values.late_grading_cc_emails || { emails: [] };
108+
const replyTrimmed =
109+
typeof values.late_grading_reply_to === "string" ? values.late_grading_reply_to.trim() : "";
110+
values.late_grading_reply_to = replyTrimmed.length > 0 ? replyTrimmed : null;
111+
values.late_grading_cc_emails = values.late_grading_cc_emails ?? { emails: [] };
107112
await form.refineCore.onFinish(values);
108113
await revalidateCourseDerivedCachesClient(Number.parseInt(course_id as string, 10));
109114
if (values.template_repo) {

app/course/[course_id]/manage/assignments/new/form.tsx

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,15 @@ export type AssignmentFormValues = Assignment & {
5555
allow_early?: boolean | null;
5656
};
5757

58+
/** Coerce number inputs so toggling visibility never leaves `NaN` in form state (NaN breaks `??` fallbacks). */
59+
const numberInputValueAs = (emptyFallback: number | null) => (value: unknown) => {
60+
if (value === "" || value === null || value === undefined) {
61+
return emptyFallback;
62+
}
63+
const n = Number(value);
64+
return Number.isFinite(n) ? n : emptyFallback;
65+
};
66+
5867
const normalizeCcEmails = (value: unknown): GradingCcEmails => {
5968
if (value && typeof value === "object" && "emails" in value) {
6069
const emails = (value as { emails?: unknown }).emails;
@@ -598,7 +607,8 @@ function GradingAutomationSubform({
598607
} = useList<GradingAssignmentDefaultProfile>({
599608
resource: "grading_assignment_default_profiles",
600609
filters: [{ field: "class_id", operator: "eq", value: courseId }],
601-
pagination: { pageSize: 200 }
610+
pagination: { pageSize: 200 },
611+
queryOptions: { enabled: Number.isFinite(courseId) }
602612
});
603613
const profiles = useMemo(() => profileData?.data ?? [], [profileData?.data]);
604614
const profileMap = useMemo(
@@ -748,7 +758,7 @@ function GradingAutomationSubform({
748758
{...register("auto_assign_review_due_hours", {
749759
required: autoAssignAtDeadline ? "This is required when auto assign is enabled" : false,
750760
min: { value: 0, message: "Must be at least 0 hours" },
751-
valueAsNumber: true
761+
setValueAs: numberInputValueAs(72)
752762
})}
753763
/>
754764
</Field>
@@ -789,7 +799,7 @@ function GradingAutomationSubform({
789799
{...register("late_grading_reminder_interval_hours", {
790800
required: remindersEnabled ? "This is required when reminders are enabled" : false,
791801
min: { value: 1, message: "Must be at least 1 hour" },
792-
valueAsNumber: true
802+
setValueAs: numberInputValueAs(null)
793803
})}
794804
/>
795805
</Field>

app/course/[course_id]/manage/course/grading-assignment-defaults/page.tsx

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import { Button } from "@/components/ui/button";
44
import { Field } from "@/components/ui/field";
55
import { toaster, Toaster } from "@/components/ui/toaster";
6+
import { createClient } from "@/utils/supabase/client";
67
import type { GradingAssignmentDefaultProfile } from "@/utils/supabase/DatabaseTypes";
78
import {
89
Box,
@@ -77,6 +78,14 @@ const normalizeCcEmails = (value: unknown): GradingCcEmails => {
7778

7879
const toCcText = (value: unknown): string => normalizeCcEmails(value).emails.join(", ");
7980

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+
8089
export default function GradingAssignmentDefaultsPage() {
8190
const { course_id } = useParams();
8291
const classId = Number(course_id);
@@ -182,7 +191,26 @@ export default function GradingAssignmentDefaultsPage() {
182191
});
183192

184193
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}`);
186214
if (!confirmed) {
187215
return;
188216
}
@@ -287,8 +315,8 @@ export default function GradingAssignmentDefaultsPage() {
287315
<Input
288316
type="number"
289317
{...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)
292320
})}
293321
/>
294322
</Field>
@@ -326,8 +354,8 @@ export default function GradingAssignmentDefaultsPage() {
326354
<Input
327355
type="number"
328356
{...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)
331359
})}
332360
/>
333361
</Field>

0 commit comments

Comments
 (0)