feat: UTRP v2 migration (#292)

* feat: wip add course by url

* chore: update imports

* feat: add useCourseFromUrl hook

* chore: extract logic into async function

* feat: add checkLoginStatus.ts

* feat: add useCourseMigration hook

* feat: working course migration

* fix: active schedule bug

* feat: refactor logic and add to onUpdate

* feat: update ui style

* feat: add changelog functionality to settings

* chore: update packages

* feat: migration + sentry stuffs

* feat: improve migration flow

* docs: add sentry jsdocs

* chore: fix lint and format

* chore: cleanup + fix race condition

---------

Co-authored-by: Samuel Gunter <sgunter@utexas.edu>
Co-authored-by: Razboy20 <razboy20@gmail.com>
This commit is contained in:
doprz
2024-10-14 21:30:37 -05:00
committed by GitHub
parent e774f316e3
commit d22237d561
23 changed files with 1980 additions and 1865 deletions

View File

@@ -0,0 +1,35 @@
import type { Course } from '@shared/types/Course';
import { useFlattenedCourseSchedule } from './useFlattenedCourseSchedule';
/**
* Custom hook that retrieves a course from the URL parameters.
*
* This hook extracts the `uniqueId` parameter from the URL, finds the corresponding
* course in the active schedule, and returns it. If the `uniqueId` is not found or
* does not correspond to any course, it returns `null`. After retrieving the course,
* it removes the `uniqueId` parameter from the URL.
*
* @returns The course corresponding to the `uniqueId` in the URL, or `null` if not found.
*/
export default function useCourseFromUrl(): Course | null {
const { activeSchedule } = useFlattenedCourseSchedule();
const getCourseFromUrl = (): Course | null => {
const urlParams = new URLSearchParams(window.location.search);
const uniqueIdRaw = urlParams.get('uniqueId');
if (uniqueIdRaw === null) return null;
const uniqueId = Number(uniqueIdRaw);
const course = activeSchedule.courses.find(course => course.uniqueId === uniqueId);
if (course === undefined) return null;
urlParams.delete('uniqueId');
const newUrl = `${window.location.pathname}?${urlParams}`.replace(/\?$/, '');
window.history.replaceState({}, '', newUrl);
return course;
};
return getCourseFromUrl();
}

View File

@@ -93,7 +93,7 @@ export async function replaceSchedule(oldSchedule: UserSchedule, newSchedule: Us
}
/**
* Switches the active schedule to the one with the specified name.
* Switches the active schedule to the one with the specified id.
* @param id - The id of the schedule to switch to.
* @returns A promise that resolves when the active schedule has been switched.
*/
@@ -103,3 +103,15 @@ export async function switchSchedule(id: string): Promise<void> {
const activeIndex = schedules.findIndex(s => s.id === id);
await UserScheduleStore.set('activeIndex', activeIndex);
}
/**
* Switches the active schedule to the one with the specified name.
* @param name - The name of the schedule to switch to.
* @returns A promise that resolves when the active schedule has been switched.
*/
export async function switchScheduleByName(name: string): Promise<void> {
console.log('Switching schedule...');
const schedules = await UserScheduleStore.get('schedules');
const activeIndex = schedules.findIndex(s => s.name === name);
await UserScheduleStore.set('activeIndex', activeIndex);
}