Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 6 additions & 5 deletions public/contentScript.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,12 @@ function parseHTMLTableElem(tableEl) {
course.courseName = cells[2].innerText;
course.courseType = cells[3].innerText;
course.courseCredit = parseInt(cells[5].innerText);
if (cells[6].innerText ==="勞動服務通過"){
course.courseGrade = cells[6].innerText;
}else{
course.courseGrade = parseInt(cells[6].innerText);
}
// if (cells[6].innerText ==="勞動服務通過"){
// course.courseGrade = cells[6].innerText;
// }else{
// course.courseGrade = parseInt(cells[6].innerText);
// }
course.courseGrade = cells[6].innerText;
courseList.push(course);
}
console.log(courseList);
Expand Down
144 changes: 84 additions & 60 deletions src/GradReviewer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ function reviewCreativityAndEntrepreneurship(
criteriaPassedCourses: totalPassedCourses[criteria],
};
}

if (totalRecognizedCredits >= totalCreditRequirement && isRequiredPassed) {
isPassedFlags["CreativityAndEntrepreneurshipProgram"] = true;
} else {
Expand All @@ -204,6 +204,8 @@ function reviewCreativityAndEntrepreneurship(
return result;
}

let collegeRequired = new Set();

function reviewCollegeRequired(
courseList: Course[],
rules: { [key: string]: Rule }
Expand All @@ -223,6 +225,9 @@ function reviewCollegeRequired(
isPassedFlags[requiredCourse] = false;
continue;
}
recognizedCourses.forEach((course) => {
collegeRequired.add(course.courseID);
});
criteriaPassedCourses[requiredCourse] = recognizedCourses;
let recognizedCredits = recognizedCourses.reduce(
(sum, course) => sum + course.courseCredit,
Expand Down Expand Up @@ -368,32 +373,10 @@ function reviewCSMajor(courseList: Course[], rules: { [key: string]: Rule }) {
let result: ResultDict = {};
let isPassedFlags: IsPassedFlagsDict = {};
let criteriaPassedCourses: CriteriaPassedCoursesDict = {};
let majorRequired = new Set(collegeRequired);

for (const rule in rules) {
if (rule === "CEECSElective") {
// CEECS Elective is a special case, it should consider both the CEECS courses keywords and the courses' type as elctive
const ruleKeywords = rules[rule].courseKeywords;
let recognizedCourses = courseList.filter((course) => {
return ruleKeywords
.map((keyword: string) => new RegExp(keyword))
.some(
(regex: RegExp) =>
regex.test(course.courseID) && course.courseType === "選修"
); // Adding required course type checking
});
criteriaPassedCourses[rule] = recognizedCourses;
let recognizedCredit = recognizedCourses.reduce(
(sum, course) => sum + course.courseCredit,
0
);
if (recognizedCredit >= rules[rule].creditRequirement) {
isPassedFlags[rule] = true;
} else {
isPassedFlags[rule] = false;
}
result[rule] = {
isPassed: isPassedFlags[rule],
criteriaPassedCourses: criteriaPassedCourses[rule],
};
continue;
}
// Other rules are followed the same pattern as the general required courses rule
Expand All @@ -417,6 +400,8 @@ function reviewCSMajor(courseList: Course[], rules: { [key: string]: Rule }) {
recognizedCourses = recognizedCourses.slice(0, 1); // Only the first course is counted as those are equivalent courses and others are ignored
}

majorRequired.add(recognizedCourses[0].courseID);

let recognizedCredit = recognizedCourses.reduce(
(sum, course) => sum + course.courseCredit,
0
Expand All @@ -433,6 +418,33 @@ function reviewCSMajor(courseList: Course[], rules: { [key: string]: Rule }) {
criteriaPassedCourses: criteriaPassedCourses[rule],
};
}

// CEECS Elective is a special case, it should consider both the CEECS courses keywords and the courses' type as elctive
const rule = "CEECSElective";
const ruleKeywords = rules[rule].courseKeywords;
let recognizedCourses = courseList.filter((course) => {
return ruleKeywords
.map((keyword: string) => new RegExp(keyword))
.some(
(regex: RegExp) =>
regex.test(course.courseID) && !majorRequired.has(course.courseID)
); // Adding required course type checking
});
criteriaPassedCourses[rule] = recognizedCourses;
let recognizedCredit = recognizedCourses.reduce(
(sum, course) => sum + course.courseCredit,
0
);
if (recognizedCredit >= rules[rule].creditRequirement) {
isPassedFlags[rule] = true;
} else {
isPassedFlags[rule] = false;
}
result[rule] = {
isPassed: isPassedFlags[rule],
criteriaPassedCourses: criteriaPassedCourses[rule],
};

const isRulePassed = Object.values(isPassedFlags).every(
(value) => value === true
);
Expand All @@ -450,32 +462,9 @@ function reviewNetworkMajor(
let result: ResultDict = {};
let isPassedFlags: IsPassedFlagsDict = {};
let criteriaPassedCourses: CriteriaPassedCoursesDict = {};
let majorRequired = new Set(collegeRequired);
for (const rule in rules) {
if (rule === "CEECSElective") {
// CEECS Elective is a special case, it should consider both the CEECS courses keywords and the courses' type as elctive
const ruleKeywords = rules[rule].courseKeywords;
let recognizedCourses = courseList.filter((course) => {
return ruleKeywords
.map((keyword: string) => new RegExp(keyword))
.some(
(regex: RegExp) =>
regex.test(course.courseID) && course.courseType === "選修"
); // Adding required course type checking
});
criteriaPassedCourses[rule] = recognizedCourses;
let recognizedCredit = recognizedCourses.reduce(
(sum, course) => sum + course.courseCredit,
0
);
if (recognizedCredit >= rules[rule].creditRequirement) {
isPassedFlags[rule] = true;
} else {
isPassedFlags[rule] = false;
}
result[rule] = {
isPassed: isPassedFlags[rule],
criteriaPassedCourses: criteriaPassedCourses[rule],
};
continue;
}
// Other rules are followed the same pattern as the general required courses rule
Expand All @@ -498,6 +487,7 @@ function reviewNetworkMajor(
recognizedCourses.sort((a, b) => b.courseCredit - a.courseCredit); // Sort the courses by credit in descending order
recognizedCourses = recognizedCourses.slice(0, 1); // Only the first course is counted as those are equivalent courses and others are ignored
}
majorRequired.add(recognizedCourses[0].courseID);
let recognizedCredit = recognizedCourses.reduce(
(sum, course) => sum + course.courseCredit,
0
Expand All @@ -514,6 +504,31 @@ function reviewNetworkMajor(
criteriaPassedCourses: criteriaPassedCourses[rule],
};
}
const rule = "CEECSElective";
// CEECS Elective is a special case, it should consider both the CEECS courses keywords and the courses' type as elctive
const ruleKeywords = rules[rule].courseKeywords;
let recognizedCourses = courseList.filter((course) => {
return ruleKeywords
.map((keyword: string) => new RegExp(keyword))
.some(
(regex: RegExp) =>
regex.test(course.courseID) && !majorRequired.has(course.courseID)
); // Adding required course type checking
});
criteriaPassedCourses[rule] = recognizedCourses;
let recognizedCredit = recognizedCourses.reduce(
(sum, course) => sum + course.courseCredit,
0
);
if (recognizedCredit >= rules[rule].creditRequirement) {
isPassedFlags[rule] = true;
} else {
isPassedFlags[rule] = false;
}
result[rule] = {
isPassed: isPassedFlags[rule],
criteriaPassedCourses: criteriaPassedCourses[rule],
};
const isRulePassed = Object.values(isPassedFlags).every(
(value) => value === true
);
Expand Down Expand Up @@ -776,6 +791,7 @@ function reviewCOMajor(
let result: ResultDict = {};
let isPassedFlags: IsPassedFlagsDict = {};
let criteriaPassedCourses: CriteriaPassedCoursesDict = {};
let majorRequired = new Set(collegeRequired);

// For code clearity, we handle the COMajor rules differently as the EE Major did.
// 1. Required (The same as commonRequired pipeline)
Expand All @@ -800,6 +816,7 @@ function reviewCOMajor(
recognizedCourses.sort((a, b) => b.courseCredit - a.courseCredit); // Sort the courses by credit in descending order
recognizedCourses = recognizedCourses.slice(0, 1); // Only the first course is counted as those are equivalent courses and others are ignored
}
majorRequired.add(recognizedCourses[0].courseID);
let recognizedCredit = recognizedCourses[0].courseCredit;

if (recognizedCredit === required[requiredCourse].creditRequirement) {
Expand Down Expand Up @@ -832,6 +849,9 @@ function reviewCOMajor(
recognizedCourses.sort((a, b) => b.courseCredit - a.courseCredit); // Sort the courses by credit in descending order
recognizedCourses = recognizedCourses.slice(0, 1); // Only the first course is counted as those are equivalent courses and others are ignored
}
if (recognizedCourses.length !== 0){
majorRequired.add(recognizedCourses[0].courseID);
}
criteriaPassedCourses["asteriskRequiredElective"] =
criteriaPassedCourses["asteriskRequiredElective"].concat(
recognizedCourses
Expand Down Expand Up @@ -867,7 +887,7 @@ function reviewCOMajor(
(keyword: string) => new RegExp(keyword)
).some(
(regex: RegExp) =>
regex.test(course.courseID) && course.courseType === "選修"
regex.test(course.courseID) && !majorRequired.has(course.courseID)
);
});
criteriaPassedCourses["CEECSElective"] = CEECSElectiveRecognizedCourses;
Expand Down Expand Up @@ -992,7 +1012,7 @@ function createEESection(result: ResultDict | any, criteria: string) {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const isRulePassed = result["isRulePassed"];
const isRulePassedTextColor = isRulePassed ? "#96ee11" : "#ff5050";
const isRulePassedText = isRulePassed ? "Yes":"No";
const isRulePassedText = isRulePassed ? "Yes" : "No";
delete result["isRulePassed"];
// 1. Required (The same as commonRequired pipeline)
let resultWOAsteriskAndExperiment = Object.fromEntries(
Expand All @@ -1006,18 +1026,23 @@ function createEESection(result: ResultDict | any, criteria: string) {
// 2. Experiment Group (should display group and courses)
let resultExperimentGroup = result["ExperimentGroup"];
let isExperimentGroupPassed = resultExperimentGroup["isRulePassed"];
let isExperimentGroupPassedTextColor = isExperimentGroupPassed ? "#96ee11" : "#ff5050";
let isExperimentGroupPassedText = isExperimentGroupPassed ? "Yes":"No";
let isExperimentGroupPassedTextColor = isExperimentGroupPassed
? "#96ee11"
: "#ff5050";
let isExperimentGroupPassedText = isExperimentGroupPassed ? "Yes" : "No";

delete resultExperimentGroup["isRulePassed"];

// 3. AsteriskRequiredElective (should display category and courses)
let resultAsteriskRequiredElective = result["AsteriskRequiredElective"];
let isAsteriskRequiredElectivePassed = resultAsteriskRequiredElective["isRulePassed"];
let isAsteriskRequiredElectivePassedTextColor = isAsteriskRequiredElectivePassed ? "#96ee11" : "#ff5050";
let isAsteriskRequiredElectivePassedText = isAsteriskRequiredElectivePassed ? "Yes":"No";
let isAsteriskRequiredElectivePassed =
resultAsteriskRequiredElective["isRulePassed"];
let isAsteriskRequiredElectivePassedTextColor =
isAsteriskRequiredElectivePassed ? "#96ee11" : "#ff5050";
let isAsteriskRequiredElectivePassedText = isAsteriskRequiredElectivePassed
? "Yes"
: "No";


delete resultAsteriskRequiredElective["isRulePassed"];

let htmlString = `
Expand Down Expand Up @@ -1273,15 +1298,14 @@ function GradReviewer() {
)
);


const handleHTMLClick = () => {
const html = createHTMLFile(htmlSections);
const blob = new Blob([html], { type: "text/html" });
const link = document.createElement("a");
link.href = URL.createObjectURL(blob);
link.download = `IPEECS_GradReviewReport_${AllData.checkData.generalInfo.studentName}_${AllData.checkData.generalInfo.studentID}.html`;
link.click();
}
};

// const handlePDFClick = async () => {
// const html = createHTMLFile(htmlSections);
Expand All @@ -1300,7 +1324,7 @@ function GradReviewer() {
// // Create a PDF using jsPDF
// const imgData = canvas.toDataURL("image/png");
// const pdf = new jsPDF("p", "mm", "a4");

// pdf.addImage(imgData, "JPEG", 0, 0, canvas.width, canvas.height);
// pdf.save(
// `IPEECS_GradReviewReport_${AllData.checkData.generalInfo.studentName}_${AllData.checkData.generalInfo.studentID}.pdf`
Expand Down