diff --git a/app/src/components/ScheduleBuilder.tsx b/app/src/components/ScheduleBuilder.tsx index c3f97d5..5ee5301 100644 --- a/app/src/components/ScheduleBuilder.tsx +++ b/app/src/components/ScheduleBuilder.tsx @@ -72,6 +72,8 @@ export default class ScheduleBuilder extends Component { prevState.selections.filter(notEmpty), ) ) { + console.log(`Updating local storage data for "selections:${this.state.soc?.getSOCProgramString()},${this.state.soc?.getSOCTermString()}"`) + localStorage.setItem(`selections:${this.state.soc?.getSOCProgramString()},${this.state.soc?.getSOCTermString()}`, JSON.stringify(this.state.selections)); if (this.state.generator) { // Make sure generator is not null this.state.generator.loadSelections( @@ -110,6 +112,21 @@ export default class ScheduleBuilder extends Component { }), ); this.reset(); // Make sure to only show info from the current SOC + await this.loadStoredSelections(termStr, programStr); + } + + async loadStoredSelections(termStr: string, programStr: string) { + console.log(`Searching for local storage data for "selections:${programStr},${termStr}"`) + const data = localStorage.getItem(`selections:${programStr},${termStr}`); + if (data != null) { + console.log("Stored selection data found", JSON.parse(data)); + let selectionArray = JSON.parse(data).map((selectionJson: Section[]): Selection => { + return Selection.parseJSON(selectionJson);; + }); + this.setState({ selections: selectionArray }); + } else { + console.log("Stored selection data not present.") + } } async handleDrop(ind: number, uid: string) { @@ -130,11 +147,16 @@ export default class ScheduleBuilder extends Component { (section) => !this.state.selections.some( // TODO: extract to a Selections class - (sel) => sel.includes(section), + (sel) => { + return sel.map((sec) => sec.uid === section.uid).some((truthVal) => truthVal); + } ), ); this.newSelection(ind, sectionsToAdd); // Add the section that have not been added } + else { + alert("Error dragging course or section to selections from search results. Please try re-running your search.") + } } } diff --git a/app/src/scripts/scheduleGenerator.tsx b/app/src/scripts/scheduleGenerator.tsx index 210bfc7..c995eeb 100644 --- a/app/src/scripts/scheduleGenerator.tsx +++ b/app/src/scripts/scheduleGenerator.tsx @@ -1,7 +1,17 @@ import { Section, SOC_Generic } from "@scripts/soc"; import { Term } from "@constants/soc"; -export class Selection extends Array
{} + + + + +export class Selection extends Array
{ + static parseJSON(selectionJson: Section[]): Selection { + return selectionJson.map((sectionJson: Section) => { + return Section.parseJSON(sectionJson); + }); + } +} export class Schedule extends Array
{ term: Term; diff --git a/app/src/scripts/soc/meet.ts b/app/src/scripts/soc/meet.ts index d79b2a4..0a5586e 100644 --- a/app/src/scripts/soc/meet.ts +++ b/app/src/scripts/soc/meet.ts @@ -72,6 +72,36 @@ export class MeetTime { this.periodEnd >= other.periodBegin ); } + + static parseMeetings = (meetingsJson: Meetings): Meetings => { + let meetings = noMeetings(); + meetingsJson.M.forEach((meetTimeJson: MeetTime) => meetings.M.push(MeetTime.parseMeetTime(meetTimeJson))); + meetingsJson.T.forEach((meetTimeJson: MeetTime) => meetings.T.push(MeetTime.parseMeetTime(meetTimeJson))); + meetingsJson.W.forEach((meetTimeJson: MeetTime) => meetings.W.push(MeetTime.parseMeetTime(meetTimeJson))); + meetingsJson.R.forEach((meetTimeJson: MeetTime) => meetings.R.push(MeetTime.parseMeetTime(meetTimeJson))); + meetingsJson.F.forEach((meetTimeJson: MeetTime) => meetings.F.push(MeetTime.parseMeetTime(meetTimeJson))); + meetingsJson.S.forEach((meetTimeJson: MeetTime) => meetings.S.push(MeetTime.parseMeetTime(meetTimeJson))); + return meetings; + } + + static parseMeetTime = (meetTimeJson: MeetTime): MeetTime => { + let meetTime = new MeetTime(Term.Spring, this.emptyMeetTime(), false); + return Object.assign(meetTime, meetTimeJson); + } + + static emptyMeetTime = () => { + return { + meetNo: 0, + meetDays: [], + meetTimeBegin: "", + meetTimeEnd: "", + meetPeriodBegin: "", + meetPeriodEnd: "", + meetBuilding: "", + meetBldgCode: "", + meetRoom: "", + } + } } export type Meetings = Record; @@ -85,4 +115,4 @@ export function noMeetings(): Meetings { [API_Day.Fri]: [], [API_Day.Sat]: [], }; -} +} \ No newline at end of file diff --git a/app/src/scripts/soc/section.ts b/app/src/scripts/soc/section.ts index eaffe88..8163d19 100644 --- a/app/src/scripts/soc/section.ts +++ b/app/src/scripts/soc/section.ts @@ -73,4 +73,55 @@ export class Section { this.type == API_Section_Type.MostlyOnline ); } -} + + static parseJSON = (sectionJson: Section): Section => { + let section = new Section("0#0", Term.Fall, this.emptyApiSection(), "MAS3114"); + section = Object.assign(section, sectionJson); + section.credits = new MinMax( + sectionJson.credits.min, + sectionJson.credits.max, + ); + section.meetings = MeetTime.parseMeetings(sectionJson.meetings); + return section; + } + + static emptyApiSection = (): API_Section => { + return { + number: "", + classNumber: 0, + gradBasis: 0, + acadCareer: 0, + display: "", + credits: 0, + credits_min: 0, + credits_max: 0, + note: "", + dNote: "", + genEd: [], + quest: [], + sectWeb: API_Section_Type.PrimarilyClassroom, + rotateTitle: "", + deptCode: 0, + deptName: "", + openSeats: 0, + courseFee: 0, + lateFlag: "", + EEP: "", + LMS: "", + instructors: [], + meetTimes: [], + addEligible: "", + grWriting: "", + finalExam: "", + dropaddDeadline: "", + pastDeadline: false, + startDate: "", + endDate: "", + waitList: { + isEligible: "", + cap: 0, + total: 0, + } + } + } +} \ No newline at end of file diff --git a/app/src/scripts/soc/soc.tsx b/app/src/scripts/soc/soc.tsx index 30084a7..ecfc402 100644 --- a/app/src/scripts/soc/soc.tsx +++ b/app/src/scripts/soc/soc.tsx @@ -40,6 +40,16 @@ export abstract class SOC_Generic { throw new Error("SOC initializer not implemented."); } + /* TERM AND PROGRAM */ + + getSOCTermString = (): string => { + return this.info.termStr; + } + + getSOCProgramString = (): string => { + return getProgramString(this.info.program); + } + /* UID */ /**