diff --git a/data.js b/data.js index 45ef9e7..245b89c 100644 --- a/data.js +++ b/data.js @@ -783,5 +783,13 @@ modulesData = } ], "totalCredits": 60 + }, + "year3": { + "modules": [], + "totalCredits": 60 + }, + "year4": { + "modules": [], + "totalCredits": 60 } } diff --git a/index.html b/index.html index 80bd7ad..e27f033 100644 --- a/index.html +++ b/index.html @@ -17,6 +17,8 @@

Imperial CS Tracker

+ +
diff --git a/script.js b/script.js index c2f6a8f..1eee737 100644 --- a/script.js +++ b/script.js @@ -19,15 +19,85 @@ function loadCourseData(course) { const data = modulesData[course]; html = "ModuleTasksScore" for(const module of data.modules){ - for(const task of module.tasks){ - if(task.id=='a'){ - html += `${module.name}
(${module.credits} credits - ${(module.credits/data.totalCredits*100).toFixed(2)}%)
0.00%

--/100% of module
--/--% of all
--/--% of module
--/--% of all` - }else{ - html += `` + for (const task of module.tasks) { + // Module cell + if (task.id == 'a') { + html += ` + + ${module.name}
+ (${module.credits} credits - ${(module.credits / data.totalCredits * 100).toFixed(2)}%)
+ 0.00%

+
+ --/100% of module
+ --/--% of all +
+ --/--% of module
+ --/--% of all + ${(course === 'year3' || course === 'year4') ? `
` : ''} + `; + } else { + html += ``; + } + + // Task cells + const isCustomYear = (course === 'year3' || course === 'year4'); + if (isCustomYear) { + html += ` + ${task.name}
+ (${(task.weight * 100).toFixed(2)}%)
+ + +
+
+ Score: /${task.maxScore} +
+
+ Weight: % +
+
+
+ --/100% of ${task.type === 'test' ? 'exam' : 'coursework'}
+ --/100% of module
+ --/100% of all + + `; + } else { + html += ` + ${task.name}
+ (${(task.weight * 100).toFixed(2)}%)
+ (${task.date}) + + + /${task.maxScore} +
+ --/100% of task
+ --/100% of module
+ --/100% of all + + `; } - html += `${task.name}
(${(task.weight*100).toFixed(2)}%)
(${task.date}) /${task.maxScore}
--/100% of task
--/100% of module
--/100% of all` } } + + // Add the new module section for year 3 and year 4 + if (course === 'year3' || course === 'year4') { + html += ` + + +

Add New Module

+
+
+
+
+ + + + `; + } return html } @@ -122,7 +192,105 @@ function update(){ saveCourseScore(currentCourse); } +function addNewModule() { + const moduleName = document.getElementById('newModuleName').value; + const moduleCredits = parseFloat(document.getElementById('newModuleCredits').value); + const courseworkCount = parseInt(document.getElementById('newTaskCount').value); + + if (!moduleName || isNaN(moduleCredits) || isNaN(courseworkCount) || courseworkCount < 0) { + alert('Please fill in all fields correctly'); + return; + } + + const hasExam = document.getElementById('hasExam').value === 'yes'; + const examWeight = hasExam ? 0.8 : 0; // 80% weight for exam if it exists + const remainingWeight = 1 - examWeight; + + const newModule = { + id: modulesData[currentCourse].modules.length, + name: moduleName, + credits: moduleCredits, + tasks: [] + }; + + for (let i = 0; i < courseworkCount; i++) { + newModule.tasks.push({ + id: String.fromCharCode(97 + i), // a, b, c, ... + name: `CW${i + 1}`, + type: 'cw', + maxScore: 100, + weight: remainingWeight / courseworkCount, + date: 'TBD' + }); + } + + if (hasExam) { + newModule.tasks.push({ + id: String.fromCharCode(97 + courseworkCount), + name: 'Final Exam', + type: 'test', + maxScore: 100, + weight: examWeight, + date: 'TBD' + }); + } + + modulesData[currentCourse].modules.push(newModule); + modulesData[currentCourse].totalCredits = modulesData[currentCourse].modules.reduce((sum, module) => sum + module.credits, 0); + saveCourseData(currentCourse); + switchCourse(currentCourse); +} + +function deleteModule(moduleId) { + modulesData[currentCourse].modules = modulesData[currentCourse].modules.filter(m => m.id !== moduleId); + modulesData[currentCourse].totalCredits = modulesData[currentCourse].modules.reduce((sum, module) => sum + module.credits, 0); + saveCourseData(currentCourse); + switchCourse(currentCourse); +} + +function updateWeight(moduleId, taskId) { + const module = modulesData[currentCourse].modules.find(m => m.id === moduleId); + const task = module.tasks.find(t => t.id === taskId); + const weightInput = document.getElementById('w' + moduleId + taskId); + const newWeightPercent = parseFloat(weightInput.value); + + if (isNaN(newWeightPercent) || newWeightPercent < 0 || newWeightPercent > 100) { + alert('Weight must be between 0 and 100'); + weightInput.value = (task.weight * 100).toFixed(1); + return; + } + + // Calculate total of other weights + const totalOtherWeights = module.tasks + .filter(t => t.id !== taskId) + .reduce((sum, t) => sum + t.weight, 0); + + if (totalOtherWeights + (newWeightPercent / 100) > 1) { + alert('Total weights cannot exceed 100%. Current other weights: ' + + (totalOtherWeights * 100).toFixed(1) + '%'); + weightInput.value = (task.weight * 100).toFixed(1); + return; + } + + task.weight = newWeightPercent / 100; + saveCourseData(currentCourse); + update(); +} + +function saveCourseData(course) { + localStorage['moduleData_' + course] = JSON.stringify(modulesData[course]); +} + +function loadSavedCourseData(course) { + const savedData = localStorage['moduleData_' + course]; + if (savedData) { + modulesData[course] = JSON.parse(savedData); + } +} + window.onload = function() { fixScore(); + loadSavedCourseData('year3'); // Load custom year 3 modules + loadSavedCourseData('year4'); // Load custom year 4 modules switchCourse(currentCourse); } \ No newline at end of file