aboutsummaryrefslogtreecommitdiff
path: root/cockpit/js
diff options
context:
space:
mode:
authorFlorian Fischer <florian.fischer@muhq.space>2026-08-03 14:31:25 +0200
committerFlorian Fischer <florian.fischer@muhq.space>2026-08-03 14:31:25 +0200
commit6839831af54cd9302119bcc3bffafe10475958d4 (patch)
tree12a1c1fbd864e9579cb9c3a09d4bf4686a280b73 /cockpit/js
parentfccb70cbd876785f6833dfe6efc10ec9e445556d (diff)
downloadbycs-sol-6839831af54cd9302119bcc3bffafe10475958d4.tar.gz
bycs-sol-6839831af54cd9302119bcc3bffafe10475958d4.zip
refactor project structure
* merge sites into single project root * fix name of mass-graduation site * enable typescript support
Diffstat (limited to 'cockpit/js')
-rw-r--r--cockpit/js/cockpit.js366
1 files changed, 0 insertions, 366 deletions
diff --git a/cockpit/js/cockpit.js b/cockpit/js/cockpit.js
deleted file mode 100644
index fb3b539..0000000
--- a/cockpit/js/cockpit.js
+++ /dev/null
@@ -1,366 +0,0 @@
-// import {
- // fetchSubjectsMock as fetchSubjects,
- // fetchProgressMock as fetchProgress,
-// } from "../../js/mock.js";
-
-import {
- OBSERVATION_TYPES,
- LEVEL_NAMES,
- GraduationChange,
- fetchGraduation,
- fetchPublicGraduation,
- submitGraduationChange
-} from "../../js/graduation-ENV.js";
-
-import { fetchStudent, fetchStudents, Student } from "../../js/student-ENV.js";
-import {
- isTeacher as getIsTeacher,
- getName,
- getUserId,
- DATE_FMT,
- DATETIME_FMT,
-} from "../../js/utils-ENV.js";
-import { initSelection } from "../../js/selection.js";
-
-let isTeacher;
-let name;
-let student;
-
-async function loadStudent(studentToLoad) {
- student = studentToLoad;
- await fetchAndUpdateStudentInfo();
- // updateStudentCalendar();
- // updateStudentProgress();
- updateStudentGraduation();
-}
-
-function initStudentSelection() {
- initSelection(
- "student-selection",
- fetchStudents,
- (student) => `${student.name} ${student.getGroup()}`,
- loadStudent
- );
-}
-
-function pointClickHandler(color) {
- const textareaDiv = document.getElementById("student-info-point-reason-container");
- const textarea = document.getElementById("student-info-point-reason");
- const submitBtn = document.getElementById("student-info-point-reason-submit");
-
- // TODO(muhq): Prefill the textarea with common reasons
- switch (color) {
- case "green":
- textarea.style.background = "rgb(from green r g b / 20%)"
- textarea.value = "";
- break;
- case "orange":
- textarea.style.background = "rgb(from orange r g b / 20%)"
- textarea.value = "";
- break;
- case "red":
- textarea.style.background = "rgb(from red r g b / 20%)"
- textarea.value = "";
- break;
- }
- textareaDiv.style.display = "block";
- textarea.focus();
-
- const coach = name;
-
- let submit = function() {
- let change;
- switch (color) {
- case "green":
- change = GraduationChange.newGreenPointChange(textarea.value, coach);
- break;
- case "orange":
- change = GraduationChange.newOrangePointChange(textarea.value, coach);
- break;
- case "red":
- change = GraduationChange.newRedPointChange(textarea.value, coach);
- break;
- default:
- alert("Invalid color");
- break;
- }
- submitGraduationChange(student, change);
- textareaDiv.style.display = "none";
- updateStudentInfo();
- student.fetchGraduation().then(() => updateStudentGraduation() );
- }
- // Use onEVENT to override any previous handler
- textarea.onkeydown = function(e) {
- if (e.shiftKey && e.key === "Enter") {
- submit();
- }
- if (e.key === "Escape") {
- textareaDiv.style.display = "none";
- }
- };
- submitBtn.onclick = submit;
-}
-
-async function fetchAndUpdateStudentInfo() {
- if (isTeacher)
- student.graduation = await fetchGraduation(student);
- else
- student.graduation = await fetchPublicGraduation(student);
-
- updateStudentInfo();
-}
-
-let DEFAULT_STUDENT_ICON;
-
-function updateStudentInfo() {
- // Reset the student icon
- document.getElementById("student-info-icon").src = DEFAULT_STUDENT_ICON;
-
- // Try to replace the generic icon with the user's icon
- var img = document.createElement('img');
- img.onload = function() {
- document.getElementById("student-info-icon").src = img.src;
- img = img.onload = null;
- };
- student.getIconUrl().then( (url) => img.src = url );
-
- document.getElementById("student-info-name").innerHTML = `${student.name}`;
-
- if (student.graduation) {
- const tag = document.getElementById("student-info-tag");
- tag.innerHTML = student.graduation.getLevelName();
- tag.style.display = "block";
-
- document.getElementById("student-info-points-green").innerHTML = student.graduation.green;
- document.getElementById("student-info-points-orange").innerHTML = student.graduation.orange;
- document.getElementById("student-info-points-red").innerHTML = student.graduation.red;
-
- if (isTeacher) {
- document.getElementById("student-info-green").addEventListener('click',
- () => pointClickHandler("green"));
- document.getElementById("student-info-orange").addEventListener('click',
- () => pointClickHandler("orange"));
- document.getElementById("student-info-red").addEventListener('click',
- () => pointClickHandler("red"));
- }
-
- renderGraduationLevel(student.graduation);
-
- // renderGraduationStickers(student.graduation, document.getElementById("student-info-stickers"));
- // renderGraduationBonus(student.graduation, document.getElementById("student-info-stickers"));
-
- renderObservationStatus(student.graduation, document.getElementById("student-observation"));
- }
-
- document.getElementById("student-content").style.display = "block";
-}
-
-function renderGraduationLevel(graduation) {
- const label = document.getElementById("student-info-level");
- label.innerHTML = graduation.getLevelName();
- const icon = document.getElementById("student-level-icon");
- icon.src = graduation.getIcon();
-}
-
-// function renderGraduationStickers(graduation, node) {
- // node.innerHTML = "";
-// }
-
-// function renderGraduationBonus(graduation, node) {
- // node.innerHTML = "";
-// }
-
-function renderObservationStatus(graduation, node) {
- node.innerHTML = "";
-
- let status;
- if (isTeacher || graduation.isObserved() || graduation.observationRequested) {
- status = document.createElement("span");
- status.classList.add("student-observation-status");
- if (graduation.isObserved()) {
- status.innerHTML = '<span style="font-size: larger;">&#128065</span> Ich befinde mich in der Beobachtungsphase zum Levelaufstieg.';
- } else if (graduation.observationRequested) {
- status.innerHTML = 'Beobachtungsphase noch nicht begonnen.';
- } else {
- status.innerHTML = "Nicht in Beobachtung.";
- }
- } else {
- status = document.createElement("button");
- status.classList.add("student-request-observation-button");
- // Level is 1-based
- status.innerHTML = `Ich will ${LEVEL_NAMES[graduation.level]} werden`;
- status.addEventListener("click", async function() {
- await graduation.requestObservation();
- // Rerender the observation status
- renderObservationStatus(graduation, node);
- });
- }
- node.appendChild(status);
-}
-
-// function newProgressBar(subject) {
- // let bar = document.createElement("div");
- // fetchProgress(subject).then((progress) => {
- // bar.progress = progress;
- // });
-
- // let s1 = document.createElement("div");
- // s1.onhover
-
- // bar.appendChild(s1);
- // let s2 = document.createElement("div");
- // bar.appendChild(s2);
- // let s3 = document.createElement("div");
- // bar.appendChild(s3);
- // return bar;
-// }
-
-// let selectedSubjects;
-// async function updateStudentProgress() {
- // selectedSubjects = await fetchSubjects(student);
-
- // let prog = document.getElementById("progress");
- // for(const subj of selectedSubjects) {
- // let subjDiv = document.createElement("div");
- // subjDiv.innerHTML = subj;
- // subjDiv.appendChild(newProgressBar(subj))
- // prog.appendChild(subjDiv);
- // }
-// }
-
-// async function updateStudentCalendar() {
- // let cal = document.getElementById("calendar");
-// }
-
-async function updateStudentGraduation() {
- if (!isTeacher) return;
- console.assert(student.graduation, "Student has no graduation");
- const graduation = student.graduation;
-
- const changesTbl = document.getElementById("graduation-changes");
- changesTbl.innerHTML = "";
- for (const change of graduation.changes.filter(
- (ch) => ["Grün", "Rot", "Orange"].includes(ch.change) ))
- {
- const changeTr = document.createElement("tr");
- for (const key in change) {
- if (key == "json" || key == "id" || key == "name") continue;
-
- if (key == "change") {
- switch(change.change) {
- case "Grün":
- changeTr.style.background = "green";
- break;
- case "Rot":
- changeTr.style.background = "red";
- break;
- case "Orange":
- changeTr.style.background = "orange";
- break;
- default:
- alert(`unexpected change: ${change.change}`);
- }
- continue;
- }
-
- const value = change[key];
- const fmt = key == "date" ? DATETIME_FMT.format(value) : value;
-
- const changeTd = document.createElement("td");
- changeTd.innerHTML = fmt;
- changeTd.dataset.key = key;
- changeTr.appendChild(changeTd);
- }
- changesTbl.appendChild(changeTr);
- }
-
- const observtionsTbl = document.getElementById("graduation-current-observation-period");
- observtionsTbl.innerHTML = "";
- if (graduation.observation) {
- const sums = graduation.observation.getObservationsSums();
- for (let i = 0; i < OBSERVATION_TYPES.length; i++) {
- const tr = document.createElement("tr");
- const typeTd = document.createElement("td");
- typeTd.innerHTML = OBSERVATION_TYPES[i];
- tr.appendChild(typeTd);
-
- const yesTd = document.createElement("td");
- yesTd.innerHTML = sums[i].yes;
- tr.appendChild(yesTd);
-
- const noTd = document.createElement("td");
- noTd.innerHTML = sums[i].no;
- tr.appendChild(noTd);
-
- observtionsTbl.appendChild(tr);
- }
-
- const endDiv = document.getElementById("graduation-current-observation-period-end");
- if (!graduation.observation.ready()) {
- endDiv.style.display = "none";
- return;
- }
-
- endDiv.style.display = "block";
-
- const reason = document.getElementById("graduation-current-observation-period-end-reason").value;
- const successBtn = document.getElementById("graduation-current-observation-period-end-success");
- successBtn.addEventListener("click", () => {
- submitGraduationChange(graduation.student, GraduationChange.newObservationEnd(reason, true));
- });
- const failureBtn = document.getElementById("graduation-current-observation-period-end-failure");
- failureBtn.addEventListener("click", () => {
- submitGraduationChange(graduation.student, GraduationChange.newObservationEnd(reason, false));
- });
- }
-
- const pastObservtionsTbl = document.getElementById("graduation-observation-periods");
- pastObservtionsTbl.innerHTML = "";
- if (graduation.pastObservations.length > 0) {
- for (const period of graduation.pastObservations) {
- const tr = document.createElement("tr");
- const periodTd = document.createElement("td");
- const startDate = DATE_FMT.format(period.start);
- const endDate = DATE_FMT.format(period.end);
- periodTd.innerHTML = `${startDate} - ${endDate}`;
- tr.appendChild(periodTd);
-
- const successTd = document.createElement("td");
- if (period.success) {
- successTd.innerHTML = "Graduierung erfolgreich"
- } else {
- successTd.innerHTML = "Graduierung nicht erfolgreich"
- }
- tr.appendChild(successTd);
-
- pastObservtionsTbl.appendChild(tr);
- }
- }
-}
-
-async function initCockpit() {
- if (isTeacher) {
- initStudentSelection();
- const params = new URLSearchParams(location.search);
- const userId = params.get("userToLoad");
- if (userId) {
- student = await fetchStudent(userId);
- await loadStudent(student);
- }
- } else {
- // Remove all elements only suitable for teachers
- for(const elem of document.querySelectorAll("[data-availability=if-lehrer]")) {
- elem.remove();
- }
-
- const student = await Student.fetchById(getUserId());
- await loadStudent(student);
- }
-}
-
-window.onload = function() {
- isTeacher = getIsTeacher();
- DEFAULT_STUDENT_ICON = document.getElementById("student-info-icon").src;
- name = getName();
- initCockpit();
-}