Skip to content

Commit c68c028

Browse files
committed
Fix Calendar Flashing Bug and Fix Default Start Date of Calendar Bug
1 parent bb34a1d commit c68c028

File tree

3 files changed

+55
-59
lines changed

3 files changed

+55
-59
lines changed

course-matrix/frontend/src/pages/TimetableBuilder/Calendar.tsx

Lines changed: 36 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -23,29 +23,28 @@ import {
2323
} from "@/components/ui/dialog";
2424
import { Input } from "@/components/ui/input";
2525
import { Label } from "@/components/ui/label";
26-
import { UseFormReturn } from "react-hook-form";
26+
import { useForm } from "react-hook-form";
2727
import { TimetableFormSchema } from "@/models/timetable-form";
28-
import { useCreateTimetableMutation } from "@/api/timetableApiSlice";
28+
import { useGetTimetablesQuery, useCreateTimetableMutation } from "@/api/timetableApiSlice";
2929
import { useCreateRestrictionMutation } from "@/api/restrictionsApiSlice";
3030
import { z } from "zod";
31-
import { useEffect, useState } from "react";
31+
import React, { useEffect, useRef } from "react";
3232
import { useGetNumberOfCourseSectionsQuery } from "@/api/coursesApiSlice";
3333
import {
3434
useCreateEventMutation,
3535
useGetEventsQuery,
36-
useUpdateEventMutation,
3736
useDeleteEventMutation,
3837
} from "@/api/eventsApiSlice";
3938
import { useGetOfferingEventsQuery } from "@/api/offeringsApiSlice";
4039
import { useNavigate, useSearchParams } from "react-router-dom";
4140
import { Event, Timetable, TimetableEvents } from "@/utils/type-utils";
41+
import { TimetableForm } from "@/models/timetable-form";
42+
import { getSemesterStartAndEndDates } from "@/utils/semester-utils";
4243

4344
interface CalendarProps {
44-
timetablesData: Timetable[];
45-
semesterStartDate: string;
46-
semesterEndDate: string;
47-
userEvents: Event[];
48-
form: UseFormReturn<z.infer<typeof TimetableFormSchema>>;
45+
semester: string;
46+
selectedCourses: TimetableForm["courses"];
47+
newOfferingIds: number[];
4948
}
5049

5150
function parseEvent(id: number, event: Event, calendarId: string) {
@@ -68,31 +67,38 @@ function parseEvent(id: number, event: Event, calendarId: string) {
6867
};
6968
}
7069

71-
function Calendar({
72-
timetablesData,
73-
semesterStartDate,
74-
semesterEndDate,
75-
userEvents,
76-
form,
77-
}: CalendarProps) {
70+
const Calendar = React.memo<CalendarProps>(({
71+
semester,
72+
selectedCourses,
73+
newOfferingIds,
74+
}) => {
75+
const form = useForm<z.infer<typeof TimetableFormSchema>>();
76+
7877
const navigate = useNavigate();
7978
const [queryParams] = useSearchParams();
8079
const isEditingTimetable = queryParams.has("edit");
8180
const editingTimetableId = parseInt(queryParams.get("edit") ?? "0");
82-
const newOfferingIds = form.watch("offeringIds") ?? [];
8381

8482
const [createTimetable] = useCreateTimetableMutation();
8583
const [createEvent] = useCreateEventMutation();
86-
const [updateEvent] = useUpdateEventMutation();
8784
const [deleteEvent] = useDeleteEventMutation();
8885
const [createRestriction] = useCreateRestrictionMutation();
8986

87+
const semesterStartDate = getSemesterStartAndEndDates(semester).start;
88+
const semesterEndDate = getSemesterStartAndEndDates(semester).end;
89+
9090
const { data: courseEventsData } = useGetOfferingEventsQuery({
9191
offering_ids: newOfferingIds.join(","),
9292
semester_start_date: semesterStartDate,
9393
semester_end_date: semesterEndDate,
9494
}) as { data: Event[] };
95+
96+
const { data: timetablesData } = useGetTimetablesQuery() as {
97+
data: Timetable[];
98+
};
99+
95100
const courseEvents = courseEventsData ?? [];
101+
const userEvents: Event[] = [];
96102

97103
let index = 1;
98104
const courseEventsParsed = courseEvents.map((event) =>
@@ -109,6 +115,7 @@ function Calendar({
109115
createViewMonthGrid(),
110116
createViewMonthAgenda(),
111117
],
118+
selectedDate: semesterStartDate,
112119
defaultView: viewWeek.name,
113120
events: [...courseEventsParsed, ...userEventsParsed],
114121
calendars: {
@@ -143,15 +150,14 @@ function Calendar({
143150
),
144151
].sort((a, b) => a - b);
145152

146-
const semester = form.watch("semester") ?? "";
147-
const [timetableTitle, setTimetableTitle] = useState("");
148-
149-
const selectedCourses = form.watch("courses") ?? [];
153+
const timetableTitleRef = useRef<HTMLInputElement>(null);
150154
const selectedCourseIds = selectedCourses.map((course) => course.id);
155+
151156
const { data: numberOfSectionsData } = useGetNumberOfCourseSectionsQuery({
152157
course_ids: selectedCourseIds.join(","),
153158
semester: semester,
154159
});
160+
155161
const totalNumberOfSections =
156162
numberOfSectionsData?.totalNumberOfCourseSections ?? 0;
157163

@@ -162,13 +168,11 @@ function Calendar({
162168
if (!isEditingTimetable) {
163169
return;
164170
}
165-
setTimetableTitle(
166-
timetablesData?.find((timetable) => timetable.id === editingTimetableId)
167-
?.timetable_title ?? "",
168-
);
169-
}, [timetablesData, editingTimetableId, timetableTitle, isEditingTimetable]);
171+
}, [timetablesData, editingTimetableId, isEditingTimetable]);
170172

171173
const handleCreate = async () => {
174+
const timetableTitle = timetableTitleRef.current?.value ?? "";
175+
172176
// Create timetable
173177
const { data, error } = await createTimetable({
174178
timetable_title: timetableTitle,
@@ -249,8 +253,9 @@ function Calendar({
249253
console.error(createError);
250254
}
251255
}
252-
253256
form.setValue("offeringIds", newOfferingIds);
257+
258+
navigate("/home");
254259
};
255260

256261
return (
@@ -281,7 +286,7 @@ function Calendar({
281286
<Input
282287
id="timetableName"
283288
placeholder="Placeholder name"
284-
onChange={(e) => setTimetableTitle(e.target.value.trim())}
289+
ref={timetableTitleRef}
285290
/>
286291
<DialogFooter>
287292
<DialogClose asChild>
@@ -290,7 +295,7 @@ function Calendar({
290295
<DialogClose asChild>
291296
<Button
292297
onClick={handleCreate}
293-
disabled={timetableTitle === ""}
298+
disabled={timetableTitleRef.current?.value === ""}
294299
>
295300
Save
296301
</Button>
@@ -319,6 +324,6 @@ function Calendar({
319324
<ScheduleXCalendar calendarApp={calendar} />
320325
</div>
321326
);
322-
}
327+
});
323328

324329
export default Calendar;

course-matrix/frontend/src/pages/TimetableBuilder/TimetableBuilder.tsx

Lines changed: 3 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -51,22 +51,6 @@ type FormContextType = UseFormReturn<z.infer<typeof TimetableFormSchema>>;
5151
export const FormContext = createContext<FormContextType | null>(null);
5252
const SEARCH_LIMIT = 1000;
5353

54-
function getSemesterStartAndEndDates(semester: string) {
55-
return {
56-
start:
57-
semester === "Summer 2025"
58-
? "2025-05-02"
59-
: semester === "Fall 2025"
60-
? "2025-09-03"
61-
: "2026-01-06",
62-
end:
63-
semester === "Summer 2025"
64-
? "2025-08-07"
65-
: semester === "Fall 2025"
66-
? "2025-12-03"
67-
: "2026-04-04",
68-
};
69-
}
7054

7155
/**
7256
* TimetableBuilder Component
@@ -122,7 +106,8 @@ const TimetableBuilder = () => {
122106
const enabledRestrictions = form.watch("restrictions") || [];
123107
const searchQuery = form.watch("search");
124108
const debouncedSearchQuery = useDebounceValue(searchQuery, 250);
125-
const selectedSemester = form.getValues("semester");
109+
const selectedSemester = form.watch("semester");
110+
const offeringIds = form.watch("offeringIds");
126111

127112
// console.log("Selected courses", selectedCourses);
128113
// console.log("Enabled restrictions", enabledRestrictions);
@@ -167,10 +152,6 @@ const TimetableBuilder = () => {
167152
}) as {
168153
data: TimetableEvents;
169154
};
170-
const userEvents = timetableEventsData?.userEvents || [];
171-
172-
const semesterStartDate = getSemesterStartAndEndDates(selectedSemester).start;
173-
const semesterEndDate = getSemesterStartAndEndDates(selectedSemester).end;
174155

175156
const [loadedCourses, setLoadedCourses] = useState(false);
176157
const [loadedOfferingIds, setLoadedOfferingIds] = useState(false);
@@ -526,13 +507,7 @@ const TimetableBuilder = () => {
526507
</Form>
527508
</div>
528509
<div className="w-3/5">
529-
<Calendar
530-
timetablesData={timetablesData}
531-
semesterStartDate={semesterStartDate}
532-
semesterEndDate={semesterEndDate}
533-
userEvents={userEvents}
534-
form={form}
535-
/>
510+
<Calendar semester={selectedSemester} selectedCourses={selectedCourses} newOfferingIds={offeringIds} />
536511
</div>
537512

538513
{showFilters && (
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
export function getSemesterStartAndEndDates(semester: string) {
2+
return {
3+
start:
4+
semester === "Summer 2025"
5+
? "2025-05-02"
6+
: semester === "Fall 2025"
7+
? "2025-09-03"
8+
: "2026-01-06",
9+
end:
10+
semester === "Summer 2025"
11+
? "2025-08-07"
12+
: semester === "Fall 2025"
13+
? "2025-12-03"
14+
: "2026-04-04",
15+
};
16+
}

0 commit comments

Comments
 (0)