Skip to content

Commit

Permalink
Add luxon, refactor date parsing/formatting
Browse files Browse the repository at this point in the history
Use luxon for enrollment automation implementation

Update resource aggregation date display
  • Loading branch information
smartspot2 committed Jul 23, 2023
1 parent aed030a commit 44bca40
Show file tree
Hide file tree
Showing 25 changed files with 509 additions and 471 deletions.
31 changes: 9 additions & 22 deletions csm_web/frontend/src/components/CourseMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import { useUserInfo } from "../utils/queries/base";
import { Course as CourseType, UserInfo } from "../utils/types";
import Course from "./course/Course";
import LoadingSpinner from "./LoadingSpinner";
import { DateTime } from "luxon";
import { DEFAULT_LONG_LOCALE_OPTIONS, DEFAULT_TIMEZONE } from "../utils/datetime";

const CourseMenu = () => {
const { data: jsonCourses, isSuccess: coursesLoaded } = useCourses();
Expand Down Expand Up @@ -33,7 +35,7 @@ const CourseMenu = () => {
if (userInfoLoaded) {
let priorityEnrollment = undefined;
if (jsonUserInfo.priorityEnrollment) {
priorityEnrollment = new Date(Date.parse(jsonUserInfo.priorityEnrollment));
priorityEnrollment = DateTime.fromISO(jsonUserInfo.priorityEnrollment);
}
const convertedUserInfo: UserInfo = {
...jsonUserInfo,
Expand All @@ -46,15 +48,15 @@ const CourseMenu = () => {
}

let show_enrollment_times = false;
const enrollment_times_by_course: Array<{ courseName: string; enrollmentDate: Date }> = [];
const enrollment_times_by_course: Array<{ courseName: string; enrollmentDate: DateTime }> = [];

if (courses !== null) {
for (const course of courses.values()) {
show_enrollment_times ||= !course.enrollmentOpen;

Check warning on line 55 in csm_web/frontend/src/components/CourseMenu.tsx

View workflow job for this annotation

GitHub Actions / ESLint

csm_web/frontend/src/components/CourseMenu.tsx#L55

'show_enrollment_times' is assigned a value but never used (@typescript-eslint/no-unused-vars)
if (!course.enrollmentOpen) {
enrollment_times_by_course.push({
courseName: course.name,
enrollmentDate: new Date(Date.parse(course.enrollmentStart))
enrollmentDate: DateTime.fromISO(course.enrollmentStart, { zone: DEFAULT_TIMEZONE })
});
}
}
Expand Down Expand Up @@ -97,7 +99,7 @@ interface CourseMenuContentProps {
courses: Map<number, CourseType> | null;
coursesLoaded: boolean;
userInfo: UserInfo | null;
enrollment_times_by_course: Array<{ courseName: string; enrollmentDate: Date }>;
enrollment_times_by_course: Array<{ courseName: string; enrollmentDate: DateTime }>;
}

enum CourseMenuSidebarTabs {
Expand Down Expand Up @@ -217,7 +219,7 @@ const EnrollmentMenu = ({ courses }: EnrollmentMenuProps) => {
interface EnrollmentTimesProps {
coursesLoaded: boolean;
userInfo: UserInfo | null;
enrollmentTimes: Array<{ courseName: string; enrollmentDate: Date }>;
enrollmentTimes: Array<{ courseName: string; enrollmentDate: DateTime }>;
}

/**
Expand All @@ -237,19 +239,6 @@ const EnrollmentTimes = ({
return null;
}

/**
* Formatting for the enrollment times.
*/
const date_locale_string_options: Intl.DateTimeFormatOptions = {
weekday: "long",
month: "numeric",
day: "numeric",
hour: "numeric",
minute: "numeric",
hour12: true,
timeZoneName: "short"
};

if (enrollmentTimes.length === 0) {
return null;
}
Expand All @@ -266,16 +255,14 @@ const EnrollmentTimes = ({
<em>Priority</em>
</div>
<div className="enrollment-time">
<em>{`${userInfo.priorityEnrollment.toLocaleDateString("en-US", date_locale_string_options)}`}</em>
<em>{`${userInfo.priorityEnrollment.toLocaleString(DEFAULT_LONG_LOCALE_OPTIONS)}`}</em>
</div>
</div>
)}
{enrollmentTimes.map(({ courseName, enrollmentDate }) => (
<div className="enrollment-row" key={courseName}>
<div className="enrollment-course">{courseName}</div>
<div className="enrollment-time">
{`${enrollmentDate.toLocaleDateString("en-US", date_locale_string_options)}`}
</div>
<div className="enrollment-time">{`${enrollmentDate.toLocaleString(DEFAULT_LONG_LOCALE_OPTIONS)}`}</div>
</div>
))}
</div>
Expand Down
19 changes: 5 additions & 14 deletions csm_web/frontend/src/components/course/Course.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import { WhitelistModal } from "./WhitelistModal";
import { SettingsModal } from "./SettingsModal";

import PencilIcon from "../../../static/frontend/img/pencil.svg";
import { DateTime } from "luxon";
import { DEFAULT_LONG_LOCALE_OPTIONS } from "../../utils/datetime";

const DAY_OF_WEEK_ABREVIATIONS: { [day: string]: string } = Object.freeze({
Monday: "M",
Expand All @@ -35,8 +37,8 @@ interface CourseProps {
* CourseMenu is done with its API requests, making the user suffer twice the latency for no reason.
*/
courses: Map<number, CourseType> | null;
enrollmentTimes: Array<{ courseName: string; enrollmentDate: Date }>;
priorityEnrollment: Date | undefined;
enrollmentTimes: Array<{ courseName: string; enrollmentDate: DateTime }>;
priorityEnrollment: DateTime | undefined;
}

const Course = ({ courses, priorityEnrollment, enrollmentTimes }: CourseProps): React.ReactElement | null => {
Expand Down Expand Up @@ -118,20 +120,9 @@ const Course = ({ courses, priorityEnrollment, enrollmentTimes }: CourseProps):
currDaySections = currDaySections.filter(({ numStudentsEnrolled, capacity }) => numStudentsEnrolled < capacity);
}

// copied from CourseMenu.tsx
const date_locale_string_options: Intl.DateTimeFormatOptions = {
weekday: "long",
month: "numeric",
day: "numeric",
hour: "numeric",
minute: "numeric",
hour12: true,
timeZoneName: "short"
};

const enrollmentDate =
priorityEnrollment ?? enrollmentTimes.find(({ courseName }) => courseName == course.name)?.enrollmentDate;
const enrollmentTimeString = enrollmentDate?.toLocaleDateString("en-US", date_locale_string_options) ?? "";
const enrollmentTimeString = enrollmentDate?.toLocaleString(DEFAULT_LONG_LOCALE_OPTIONS) ?? "";

return (
<div id="course-section-selector">
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { Interval } from "luxon";

export interface Time {
day: string;
startTime: number;
endTime: number;
interval: Interval;
isLinked: boolean;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
import { Interval } from "luxon";
import React, { useEffect, useState } from "react";

import { Profile } from "../../utils/types";
import LoadingSpinner from "../LoadingSpinner";
import { Calendar } from "./calendar/Calendar";
import { CalendarEvent, CalendarEventSingleTime } from "./calendar/CalendarTypes";
import { Slot } from "./EnrollmentAutomationTypes";
import { formatInterval, formatTime, MAX_PREFERENCE, parseTime } from "./utils";
import { MAX_PREFERENCE, parseTime } from "./utils";
import { useMatcherPreferenceMutation, useMatcherPreferences, useMatcherSlots } from "../../utils/queries/matcher";
import { formatInterval } from "../../utils/datetime";

import CheckCircle from "../../../static/frontend/img/check_circle.svg";
import ErrorCircle from "../../../static/frontend/img/x_circle.svg";
import { useMatcherPreferenceMutation, useMatcherPreferences, useMatcherSlots } from "../../utils/queries/matcher";

enum Status {
NONE,
Expand Down Expand Up @@ -56,8 +59,7 @@ export function MentorSectionPreferences({
for (const time of slot.times) {
times.push({
day: time.day,
startTime: parseTime(time.startTime),
endTime: parseTime(time.endTime),
interval: Interval.fromDateTimes(parseTime(time.startTime), parseTime(time.endTime)),
isLinked: time.isLinked
});
}
Expand Down Expand Up @@ -153,7 +155,7 @@ export function MentorSectionPreferences({

return (
<React.Fragment>
<span className="calendar-event-detail-time">{formatInterval(event.time.startTime, event.time.endTime)}</span>
<span className="calendar-event-detail-time">{formatInterval(event.time.interval)}</span>
{detail}
</React.Fragment>
);
Expand All @@ -176,7 +178,7 @@ export function MentorSectionPreferences({
{event.times.map((time, time_idx) => (
<li key={time_idx} className="matcher-selected-time-container">
<span className="matcher-selected-time">
{time.day} {formatTime(time.startTime)}&#8211;{formatTime(time.endTime)}
{time.day} {formatInterval(time.interval)}
</span>
</li>
))}
Expand Down
Loading

0 comments on commit 44bca40

Please sign in to comment.