mirror of
https://github.com/BetterSEQTA/BetterSEQTA-Plus.git
synced 2026-06-06 03:34:40 +00:00
feat: cleanup and comment removal
This commit is contained in:
@@ -30,11 +30,10 @@ export async function getUserInfo() {
|
||||
}),
|
||||
});
|
||||
|
||||
const responseData = await response.json();
|
||||
cachedUserInfo = responseData.payload;
|
||||
cachedUserInfo = (await response.json()).payload;
|
||||
return cachedUserInfo;
|
||||
} catch (error) {
|
||||
console.error("Error fetching user info:", error);
|
||||
console.error("[BetterSEQTA+] Failed to get user info:", error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
@@ -61,7 +60,7 @@ export async function AddBetterSEQTAElements() {
|
||||
handleStudentData(),
|
||||
]);
|
||||
} catch (error) {
|
||||
console.error("Error initializing UI elements:", error);
|
||||
console.error("[BetterSEQTA+] Failed to initialize UI elements:", error);
|
||||
}
|
||||
|
||||
setupEventListeners();
|
||||
@@ -80,20 +79,18 @@ function createHomeButton(fragment: DocumentFragment, _: HTMLElement) {
|
||||
div.classList.add("titlebar");
|
||||
container.append(div);
|
||||
|
||||
const NewButton = stringToHTML(
|
||||
/* html */`<li class="item" data-key="home" id="homebutton" data-path="/home" data-betterseqta="true"><label><svg style="width:24px;height:24px" viewBox="0 0 24 24"><path fill="currentColor" d="M10,20V14H14V20H19V12H22L12,3L2,12H5V20H10Z" /></svg><span>Home</span></label></li>`
|
||||
fragment.appendChild(
|
||||
stringToHTML(
|
||||
/* html */ `<li class="item" data-key="home" id="homebutton" data-path="/home" data-betterseqta="true"><label><svg style="width:24px;height:24px" viewBox="0 0 24 24"><path fill="currentColor" d="M10,20V14H14V20H19V12H22L12,3L2,12H5V20H10Z" /></svg><span>Home</span></label></li>`,
|
||||
).firstChild!,
|
||||
);
|
||||
if (NewButton.firstChild) {
|
||||
fragment.appendChild(NewButton.firstChild);
|
||||
}
|
||||
}
|
||||
|
||||
async function handleUserInfo() {
|
||||
try {
|
||||
const info = await getUserInfo();
|
||||
updateUserInfo(info);
|
||||
updateUserInfo(await getUserInfo());
|
||||
} catch (error) {
|
||||
console.error("Error fetching and processing student data:", error);
|
||||
console.error("[BetterSEQTA+] Failed to handle user info:", error);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -117,30 +114,32 @@ function updateUserInfo(info: {
|
||||
}) {
|
||||
const titlebar = document.getElementsByClassName("titlebar")[0];
|
||||
|
||||
const userInfo = stringToHTML(/* html */ `
|
||||
<div class="userInfosvgdiv tooltip">
|
||||
<svg class="userInfosvg" viewBox="0 0 24 24"><path fill="var(--text-primary)" d="M12,19.2C9.5,19.2 7.29,17.92 6,16C6.03,14 10,12.9 12,12.9C14,12.9 17.97,14 18,16C16.71,17.92 14.5,19.2 12,19.2M12,5A3,3 0 0,1 15,8A3,3 0 0,1 12,11A3,3 0 0,1 9,8A3,3 0 0,1 12,5M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12C22,6.47 17.5,2 12,2Z"></path></svg>
|
||||
<div class="tooltiptext topmenutooltip" id="logouttooltip"></div>
|
||||
</div>
|
||||
`).firstChild;
|
||||
titlebar.append(userInfo!);
|
||||
|
||||
const userinfo = stringToHTML(/* html */ `
|
||||
<div class="userInfo">
|
||||
<div class="userInfoText">
|
||||
<div style="display: flex; align-items: center;">
|
||||
<p class="userInfohouse userInfoCode"></p>
|
||||
<p class="userInfoName">${info.userDesc}</p>
|
||||
</div>
|
||||
<p class="userInfoCode">${info.meta.code} // ${info.meta.governmentID}</p>
|
||||
titlebar.append(
|
||||
stringToHTML(/* html */ `
|
||||
<div class="userInfosvgdiv tooltip">
|
||||
<svg class="userInfosvg" viewBox="0 0 24 24"><path fill="var(--text-primary)" d="M12,19.2C9.5,19.2 7.29,17.92 6,16C6.03,14 10,12.9 12,12.9C14,12.9 17.97,14 18,16C16.71,17.92 14.5,19.2 12,19.2M12,5A3,3 0 0,1 15,8A3,3 0 0,1 12,11A3,3 0 0,1 9,8A3,3 0 0,1 12,5M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12C22,6.47 17.5,2 12,2Z"></path></svg>
|
||||
<div class="tooltiptext topmenutooltip" id="logouttooltip"></div>
|
||||
</div>
|
||||
</div>
|
||||
`).firstChild;
|
||||
titlebar.append(userinfo!);
|
||||
`).firstChild!,
|
||||
);
|
||||
|
||||
var logoutbutton = document.getElementsByClassName("logout")[0];
|
||||
var userInfosvgdiv = document.getElementById("logouttooltip")!;
|
||||
userInfosvgdiv.appendChild(logoutbutton);
|
||||
titlebar.append(
|
||||
stringToHTML(/* html */ `
|
||||
<div class="userInfo">
|
||||
<div class="userInfoText">
|
||||
<div style="display: flex; align-items: center;">
|
||||
<p class="userInfohouse userInfoCode"></p>
|
||||
<p class="userInfoName">${info.userDesc}</p>
|
||||
</div>
|
||||
<p class="userInfoCode">${info.meta.code} // ${info.meta.governmentID}</p>
|
||||
</div>
|
||||
</div>
|
||||
`).firstChild!,
|
||||
);
|
||||
|
||||
document
|
||||
.getElementById("logouttooltip")!
|
||||
.appendChild(document.getElementsByClassName("logout")[0]);
|
||||
}
|
||||
|
||||
async function handleStudentData() {
|
||||
@@ -156,48 +155,40 @@ async function handleStudentData() {
|
||||
},
|
||||
);
|
||||
|
||||
const responseData = await response.json();
|
||||
let students = responseData.payload;
|
||||
await updateStudentInfo(students);
|
||||
await updateStudentInfo((await response.json()).payload);
|
||||
} catch (error) {
|
||||
console.error("Error fetching and processing student data:", error);
|
||||
console.error("[BetterSEQTA+] Failed to handle student data:", error);
|
||||
}
|
||||
}
|
||||
|
||||
async function updateStudentInfo(students: any) {
|
||||
const info = await getUserInfo();
|
||||
var index = students.findIndex(function (person: any) {
|
||||
return (
|
||||
const index = students.findIndex(
|
||||
(person: any) =>
|
||||
person.firstname == info.userDesc.split(" ")[0] &&
|
||||
person.surname == info.userDesc.split(" ")[1]
|
||||
);
|
||||
});
|
||||
person.surname == info.userDesc.split(" ")[1],
|
||||
);
|
||||
|
||||
const houseelement = document.getElementsByClassName("userInfohouse")[0] as HTMLElement;
|
||||
|
||||
// Fallback to N/A
|
||||
let text = 'N/A';
|
||||
const houseelement = document.getElementsByClassName(
|
||||
"userInfohouse",
|
||||
)[0] as HTMLElement;
|
||||
const student = students[index] ?? {};
|
||||
let text = "N/A";
|
||||
|
||||
// If student has a house, prefer to show year + house. If no year, only show house.
|
||||
if (student.house) {
|
||||
text = `${student.year ?? ""}${student.house}`;
|
||||
|
||||
// If house_colour exists, compute colour
|
||||
if (student.house_colour) {
|
||||
houseelement.style.background = student.house_colour;
|
||||
|
||||
try {
|
||||
const colorresult = GetThresholdOfColor(student.house_colour);
|
||||
houseelement.style.color =
|
||||
colorresult && colorresult > 300 ? "black" : "white";
|
||||
|
||||
} catch (err) {
|
||||
// Colour calculation failed, no text colour set
|
||||
} catch {
|
||||
// Invalid color format, leave text color as default
|
||||
}
|
||||
}
|
||||
} else if (student.year) {
|
||||
// No house, only year will be shown
|
||||
text = student.year;
|
||||
}
|
||||
|
||||
@@ -205,15 +196,13 @@ async function updateStudentInfo(students: any) {
|
||||
}
|
||||
|
||||
function createNewsButton(fragment: DocumentFragment, menu: HTMLElement) {
|
||||
const NewsButtonStr =
|
||||
'<li class="item" data-key="news" id="newsbutton" data-path="/news" data-betterseqta="true"><label><svg style="width:24px;height:24px" viewBox="0 0 24 24"><path fill="currentColor" d="M20 3H4C2.89 3 2 3.89 2 5V19C2 20.11 2.89 21 4 21H20C21.11 21 22 20.11 22 19V5C22 3.89 21.11 3 20 3M5 7H10V13H5V7M19 17H5V15H19V17M19 13H12V11H19V13M19 9H12V7H19V9Z" /></svg><span>News</span></label></li>';
|
||||
const NewsButton = stringToHTML(NewsButtonStr);
|
||||
fragment.appendChild(
|
||||
stringToHTML(
|
||||
'<li class="item" data-key="news" id="newsbutton" data-path="/news" data-betterseqta="true"><label><svg style="width:24px;height:24px" viewBox="0 0 24 24"><path fill="currentColor" d="M20 3H4C2.89 3 2 3.89 2 5V19C2 20.11 2.89 21 4 21H20C21.11 21 22 20.11 22 19V5C22 3.89 21.11 3 20 3M5 7H10V13H5V7M19 17H5V15H19V17M19 13H12V11H19V13M19 9H12V7H19V9Z" /></svg><span>News</span></label></li>',
|
||||
).firstChild!,
|
||||
);
|
||||
|
||||
if (NewsButton.firstChild) {
|
||||
fragment.appendChild(NewsButton.firstChild);
|
||||
}
|
||||
|
||||
let iconCover = document.createElement("div");
|
||||
const iconCover = document.createElement("div");
|
||||
iconCover.classList.add("icon-cover");
|
||||
iconCover.id = "icon-cover";
|
||||
menu.appendChild(iconCover);
|
||||
@@ -252,46 +241,42 @@ function setupEventListeners() {
|
||||
}
|
||||
|
||||
async function createSettingsButton() {
|
||||
let SettingsButton = stringToHTML(/* html */ `
|
||||
<button class="addedButton tooltip" id="AddedSettings">
|
||||
<svg width="24" height="24" viewBox="0 0 24 24">
|
||||
<g><g><path d="M23.182,6.923c-.29,0-3.662,2.122-4.142,2.4l-2.8-1.555V4.511l4.257-2.456a.518.518,0,0,0,.233-.408.479.479,0,0,0-.233-.407,6.511,6.511,0,1,0-3.327,12.107,6.582,6.582,0,0,0,6.148-4.374,5.228,5.228,0,0,0,.333-1.542A.461.461,0,0,0,23.182,6.923Z"></path><path d="M9.73,10.418,7.376,12.883c-.01.01-.021.016-.03.025L1.158,19.1a2.682,2.682,0,1,0,3.793,3.793l4.583-4.582,0,0,4.1-4.005-.037-.037A9.094,9.094,0,0,1,9.73,10.418ZM3.053,21.888A.894.894,0,1,1,3.946,21,.893.893,0,0,1,3.053,21.888Z"></path></g></g>
|
||||
</svg>
|
||||
${settingsState.onoff ? '<div class="tooltiptext topmenutooltip">BetterSEQTA+ Settings</div>' : ""}
|
||||
</button>
|
||||
`);
|
||||
let ContentDiv = document.getElementById("content");
|
||||
ContentDiv!.append(SettingsButton.firstChild!);
|
||||
document.getElementById("content")!.append(
|
||||
stringToHTML(/* html */ `
|
||||
<button class="addedButton tooltip" id="AddedSettings">
|
||||
<svg width="24" height="24" viewBox="0 0 24 24">
|
||||
<g><g><path d="M23.182,6.923c-.29,0-3.662,2.122-4.142,2.4l-2.8-1.555V4.511l4.257-2.456a.518.518,0,0,0,.233-.408.479.479,0,0,0-.233-.407,6.511,6.511,0,1,0-3.327,12.107,6.582,6.582,0,0,0,6.148-4.374,5.228,5.228,0,0,0,.333-1.542A.461.461,0,0,0,23.182,6.923Z"></path><path d="M9.73,10.418,7.376,12.883c-.01.01-.021.016-.03.025L1.158,19.1a2.682,2.682,0,1,0,3.793,3.793l4.583-4.582,0,0,4.1-4.005-.037-.037A9.094,9.094,0,0,1,9.73,10.418ZM3.053,21.888A.894.894,0,1,1,3.946,21,.893.893,0,0,1,3.053,21.888Z"></path></g></g>
|
||||
</svg>
|
||||
${settingsState.onoff ? '<div class="tooltiptext topmenutooltip">BetterSEQTA+ Settings</div>' : ""}
|
||||
</button>
|
||||
`).firstChild!,
|
||||
);
|
||||
}
|
||||
|
||||
function GetLightDarkModeString() {
|
||||
if (settingsState.DarkMode) {
|
||||
return "Switch to light theme";
|
||||
} else {
|
||||
return "Switch to dark theme";
|
||||
}
|
||||
return settingsState.DarkMode
|
||||
? "Switch to light theme"
|
||||
: "Switch to dark theme";
|
||||
}
|
||||
|
||||
async function addDarkLightToggle() {
|
||||
const tooltipString = GetLightDarkModeString();
|
||||
const SUN_ICON_SVG = /* html */ `<defs><clipPath id="__lottie_element_80"><rect width="24" height="24" x="0" y="0"></rect></clipPath></defs><g clip-path="url(#__lottie_element_80)"><g style="display: block;" transform="matrix(1,0,0,1,12,12)" opacity="1"><g opacity="1" transform="matrix(1,0,0,1,0,0)"><path fill-opacity="1" d=" M0,-4 C-2.2100000381469727,-4 -4,-2.2100000381469727 -4,0 C-4,2.2100000381469727 -2.2100000381469727,4 0,4 C2.2100000381469727,4 4,2.2100000381469727 4,0 C4,-2.2100000381469727 2.2100000381469727,-4 0,-4z"></path></g></g><g style="display: block;" transform="matrix(1,0,0,1,12,12)" opacity="1"><g opacity="1" transform="matrix(1,0,0,1,0,0)"><path fill-opacity="1" d=" M0,6 C-3.309999942779541,6 -6,3.309999942779541 -6,0 C-6,-3.309999942779541 -3.309999942779541,-6 0,-6 C3.309999942779541,-6 6,-3.309999942779541 6,0 C6,3.309999942779541 3.309999942779541,6 0,6z M8,-3.309999942779541 C8,-3.309999942779541 8,-8 8,-8 C8,-8 3.309999942779541,-8 3.309999942779541,-8 C3.309999942779541,-8 0,-11.3100004196167 0,-11.3100004196167 C0,-11.3100004196167 -3.309999942779541,-8 -3.309999942779541,-8 C-3.309999942779541,-8 -8,-8 -8,-8 C-8,-8 -8,-3.309999942779541 -8,-3.309999942779541 C-8,-3.309999942779541 -11.3100004196167,0 -11.3100004196167,0 C-11.3100004196167,0 -8,3.309999942779541 -8,3.309999942779541 C-8,3.309999942779541 -8,8 -8,8 C-8,8 -3.309999942779541,8 -3.309999942779541,8 C-3.309999942779541,8 0,11.3100004196167 0,11.3100004196167 C0,11.3100004196167 3.309999942779541,8 3.309999942779541,8 C3.309999942779541,8 8,8 8,8 C8,8 8,3.309999942779541 8,3.309999942779541 C8,3.309999942779541 11.3100004196167,0 11.3100004196167,0 C11.3100004196167,0 8,-3.309999942779541 8,-3.309999942779541z"></path></g></g></g>`;
|
||||
const MOON_ICON_SVG = /* html */ `<defs><clipPath id="__lottie_element_263"><rect width="24" height="24" x="0" y="0"></rect></clipPath></defs><g clip-path="url(#__lottie_element_263)"><g style="display: block;" transform="matrix(1.5,0,0,1.5,7,12)" opacity="1"><g opacity="1" transform="matrix(1,0,0,1,0,0)"><path fill-opacity="1" d=" M0,-4 C-2.2100000381469727,-4 -1.2920000553131104,-2.2100000381469727 -1.2920000553131104,0 C-1.2920000553131104,2.2100000381469727 -2.2100000381469727,4 0,4 C2.2100000381469727,4 4,2.2100000381469727 4,0 C4,-2.2100000381469727 2.2100000381469727,-4 0,-4z"></path></g></g><g style="display: block;" transform="matrix(-1,0,0,-1,12,12)" opacity="1"><g opacity="1" transform="matrix(1,0,0,1,0,0)"><path fill-opacity="1" d=" M0,6 C-3.309999942779541,6 -6,3.309999942779541 -6,0 C-6,-3.309999942779541 -3.309999942779541,-6 0,-6 C3.309999942779541,-6 6,-3.309999942779541 6,0 C6,3.309999942779541 3.309999942779541,6 0,6z M8,-3.309999942779541 C8,-3.309999942779541 8,-8 8,-8 C8,-8 3.309999942779541,-8 3.309999942779541,-8 C3.309999942779541,-8 0,-11.3100004196167 0,-11.3100004196167 C0,-11.3100004196167 -3.309999942779541,-8 -3.309999942779541,-8 C-3.309999942779541,-8 -8,-8 -8,-8 C-8,-8 -8,-3.309999942779541 -8,-3.309999942779541 C-8,-3.309999942779541 -11.3100004196167,0 -11.3100004196167,0 C-11.3100004196167,0 -8,3.309999942779541 -8,3.309999942779541 C-8,3.309999942779541 -8,8 -8,8 C-8,8 -3.309999942779541,8 -3.309999942779541,8 C-3.309999942779541,8 0,11.3100004196167 0,11.3100004196167 C0,11.3100004196167 3.309999942779541,8 3.309999942779541,8 C3.309999942779541,8 8,8 8,8 C8,8 8,3.309999942779541 8,3.309999942779541 C8,3.309999942779541 11.3100004196167,0 11.3100004196167,0 C11.3100004196167,0 8,-3.309999942779541 8,-3.309999942779541z"></path></g></g></g>`;
|
||||
|
||||
const initialSvgContent = settingsState.DarkMode ? SUN_ICON_SVG : MOON_ICON_SVG;
|
||||
|
||||
const LightDarkModeButton = stringToHTML(/* html */ `
|
||||
<button class="addedButton DarkLightButton tooltip" id="LightDarkModeButton">
|
||||
<svg xmlns="http://www.w3.org/2000/svg">${initialSvgContent}</svg>
|
||||
<div class="tooltiptext topmenutooltip" id="darklighttooliptext">${tooltipString}</div>
|
||||
</button>
|
||||
`);
|
||||
|
||||
let ContentDiv = document.getElementById("content");
|
||||
ContentDiv!.append(LightDarkModeButton.firstChild!);
|
||||
document.getElementById("content")!.append(
|
||||
stringToHTML(/* html */ `
|
||||
<button class="addedButton DarkLightButton tooltip" id="LightDarkModeButton">
|
||||
<svg xmlns="http://www.w3.org/2000/svg">${settingsState.DarkMode ? SUN_ICON_SVG : MOON_ICON_SVG}</svg>
|
||||
<div class="tooltiptext topmenutooltip" id="darklighttooliptext">${GetLightDarkModeString()}</div>
|
||||
</button>
|
||||
`).firstChild!,
|
||||
);
|
||||
|
||||
updateAllColors();
|
||||
|
||||
const lightDarkModeButtonElement = document.getElementById("LightDarkModeButton")!;
|
||||
const lightDarkModeButtonElement = document.getElementById(
|
||||
"LightDarkModeButton",
|
||||
)!;
|
||||
|
||||
lightDarkModeButtonElement.addEventListener("click", async () => {
|
||||
const darklightText = document.getElementById("darklighttooliptext");
|
||||
@@ -303,7 +288,6 @@ async function addDarkLightToggle() {
|
||||
LightDarkModeSnakeEggButton = 0;
|
||||
}
|
||||
|
||||
|
||||
if (
|
||||
settingsState.originalDarkMode !== undefined &&
|
||||
settingsState.selectedTheme
|
||||
@@ -314,38 +298,24 @@ async function addDarkLightToggle() {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!document.startViewTransition || !settingsState.animations || window.matchMedia("(prefers-reduced-motion: reduce)").matches) {
|
||||
settingsState.DarkMode = !settingsState.DarkMode;
|
||||
updateAllColors();
|
||||
|
||||
const newSvgContent = settingsState.DarkMode ? SUN_ICON_SVG : MOON_ICON_SVG;
|
||||
const svgElement = lightDarkModeButtonElement.querySelector("svg");
|
||||
if (svgElement) svgElement.innerHTML = newSvgContent;
|
||||
darklightText!.innerText = GetLightDarkModeString();
|
||||
return;
|
||||
}
|
||||
|
||||
settingsState.DarkMode = !settingsState.DarkMode;
|
||||
|
||||
updateAllColors();
|
||||
|
||||
const newSvgContent = settingsState.DarkMode ? SUN_ICON_SVG : MOON_ICON_SVG;
|
||||
const svgElement = lightDarkModeButtonElement.querySelector("svg");
|
||||
if (svgElement) svgElement.innerHTML = newSvgContent;
|
||||
|
||||
updateAllColors();
|
||||
|
||||
const svgElement = lightDarkModeButtonElement.querySelector("svg")!;
|
||||
svgElement.innerHTML = settingsState.DarkMode
|
||||
? SUN_ICON_SVG
|
||||
: MOON_ICON_SVG;
|
||||
darklightText!.innerText = GetLightDarkModeString();
|
||||
});
|
||||
}
|
||||
|
||||
function customizeMenuToggle() {
|
||||
const menuToggle = document.getElementById("menuToggle");
|
||||
if (menuToggle) {
|
||||
menuToggle.innerHTML = "";
|
||||
}
|
||||
const menuToggle = document.getElementById("menuToggle")!;
|
||||
menuToggle.innerHTML = "";
|
||||
|
||||
for (let i = 0; i < 3; i++) {
|
||||
const line = document.createElement("div");
|
||||
line.className = "hamburger-line";
|
||||
menuToggle!.appendChild(line);
|
||||
menuToggle.appendChild(line);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,20 +30,17 @@ export async function loadHomePage() {
|
||||
element?.classList.add("active");
|
||||
|
||||
const main = document.getElementById("main");
|
||||
if (!main) {
|
||||
console.error("[BetterSEQTA+] Main element not found.");
|
||||
return;
|
||||
}
|
||||
|
||||
const homeRoot = stringToHTML(`<div id="home-root" class="home-root"></div>`);
|
||||
if (!main) return;
|
||||
|
||||
main.innerHTML = "";
|
||||
main.appendChild(homeRoot?.firstChild!);
|
||||
main.appendChild(
|
||||
stringToHTML(`<div id="home-root" class="home-root"></div>`).firstChild!,
|
||||
);
|
||||
|
||||
const homeContainer = document.getElementById("home-root");
|
||||
if (!homeContainer) return;
|
||||
|
||||
const skeletonStructure = stringToHTML(/* html */`
|
||||
const skeletonStructure = stringToHTML(/* html */ `
|
||||
<div class="home-container" id="home-container">
|
||||
<div class="border shortcut-container">
|
||||
<div class="border shortcuts" id="shortcuts"></div>
|
||||
@@ -101,25 +98,16 @@ export async function loadHomePage() {
|
||||
|
||||
renderShortcuts();
|
||||
|
||||
const date = new Date();
|
||||
const TodayFormatted = formatDate(date);
|
||||
const TodayFormatted = formatDate(new Date());
|
||||
|
||||
const [assessmentsPromise, classesPromise, prefsPromise] = [
|
||||
const [assessments, classes, prefs] = await Promise.all([
|
||||
GetUpcomingAssessments(),
|
||||
|
||||
GetActiveClasses(),
|
||||
|
||||
fetch(`${location.origin}/seqta/student/load/prefs?`, {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({ asArray: true, request: "userPrefs" }),
|
||||
}).then((res) => res.json()),
|
||||
];
|
||||
|
||||
const [assessments, classes, prefs] = await Promise.all([
|
||||
assessmentsPromise,
|
||||
classesPromise,
|
||||
prefsPromise,
|
||||
]);
|
||||
|
||||
callHomeTimetable(TodayFormatted, true);
|
||||
@@ -159,20 +147,20 @@ export async function loadHomePage() {
|
||||
}
|
||||
|
||||
async function GetUpcomingAssessments() {
|
||||
let func = fetch(
|
||||
`${location.origin}/seqta/student/assessment/list/upcoming?`,
|
||||
{
|
||||
try {
|
||||
return fetch(`${location.origin}/seqta/student/assessment/list/upcoming?`, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json; charset=utf-8",
|
||||
},
|
||||
body: JSON.stringify({ student: 69 }),
|
||||
},
|
||||
);
|
||||
|
||||
return func
|
||||
.then((result) => result.json())
|
||||
.then((response) => response.payload);
|
||||
})
|
||||
.then((result) => result.json())
|
||||
.then((response) => response.payload);
|
||||
} catch (error) {
|
||||
console.error("[BetterSEQTA+] Failed to get upcoming assessments:", error);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
function setupTimetableListeners() {
|
||||
@@ -230,15 +218,10 @@ async function GetActiveClasses() {
|
||||
body: JSON.stringify({}),
|
||||
},
|
||||
);
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP error! Status: ${response.status}`);
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
return data.payload;
|
||||
return (await response.json()).payload;
|
||||
} catch (error) {
|
||||
console.error("Oops! There was a problem fetching active classes:", error);
|
||||
console.error("[BetterSEQTA+] Failed to get active classes:", error);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -248,28 +231,25 @@ function setupNotices(labelArray: string[], date: string) {
|
||||
) as HTMLInputElement;
|
||||
|
||||
const fetchNotices = async (date: string) => {
|
||||
let data;
|
||||
try {
|
||||
const data = settingsState.mockNotices
|
||||
? getMockNotices()
|
||||
: await (
|
||||
await fetch(`${location.origin}/seqta/student/load/notices?`, {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json; charset=utf-8" },
|
||||
body: JSON.stringify({ date }),
|
||||
})
|
||||
).json();
|
||||
|
||||
if (settingsState.mockNotices) {
|
||||
data = getMockNotices();
|
||||
} else {
|
||||
const response = await fetch(
|
||||
`${location.origin}/seqta/student/load/notices?`,
|
||||
{
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json; charset=utf-8" },
|
||||
body: JSON.stringify({ date }),
|
||||
},
|
||||
);
|
||||
data = await response.json();
|
||||
processNotices(data, labelArray);
|
||||
} catch (error) {
|
||||
console.error("[BetterSEQTA+] Failed to fetch notices:", error);
|
||||
}
|
||||
|
||||
processNotices(data, labelArray);
|
||||
};
|
||||
|
||||
const debouncedInputChange = debounce((e: Event) => {
|
||||
const target = e.target as HTMLInputElement;
|
||||
fetchNotices(target.value);
|
||||
fetchNotices((e.target as HTMLInputElement).value);
|
||||
}, 250);
|
||||
|
||||
dateControl?.addEventListener("input", debouncedInputChange);
|
||||
@@ -290,16 +270,8 @@ function debounce<T extends (...args: any[]) => any>(
|
||||
}
|
||||
|
||||
function comparedate(obj1: any, obj2: any) {
|
||||
if (obj1.date < obj2.date) {
|
||||
return -1;
|
||||
}
|
||||
if (obj1.date > obj2.date) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
return obj1.date < obj2.date ? -1 : obj1.date > obj2.date ? 1 : 0;
|
||||
}
|
||||
|
||||
|
||||
function processNotices(response: any, labelArray: string[]) {
|
||||
const NoticeContainer = document.getElementById("notice-container");
|
||||
if (!NoticeContainer) return;
|
||||
@@ -343,14 +315,14 @@ function processNoticeColor(colour: string): string | undefined {
|
||||
}
|
||||
|
||||
function createNoticeElement(notice: any, colour: string | undefined): Node {
|
||||
const textPreview = notice.contents
|
||||
.replace(/<[^>]*>/g, "")
|
||||
.replace(/\[\[[\w]+[:][\w]+[\]\]]+/g, "")
|
||||
.replace(/\s+/g, " ")
|
||||
.trim()
|
||||
.substring(0, 150)
|
||||
+ (notice.contents.length > 150 ? "..." : "");
|
||||
|
||||
const textPreview =
|
||||
notice.contents
|
||||
.replace(/<[^>]*>/g, "")
|
||||
.replace(/\[\[[\w]+[:][\w]+[\]\]]+/g, "")
|
||||
.replace(/\s+/g, " ")
|
||||
.trim()
|
||||
.substring(0, 150) + (notice.contents.length > 150 ? "..." : "");
|
||||
|
||||
const noticeId = `notice-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
||||
|
||||
const htmlContent = `
|
||||
@@ -369,12 +341,10 @@ function createNoticeElement(notice: any, colour: string | undefined): Node {
|
||||
</div>`;
|
||||
|
||||
const element = stringToHTML(htmlContent).firstChild as HTMLElement;
|
||||
if (element) {
|
||||
element.addEventListener("click", () =>
|
||||
openNoticeModal(notice, colour, element),
|
||||
);
|
||||
}
|
||||
return element!;
|
||||
element.addEventListener("click", () =>
|
||||
openNoticeModal(notice, colour, element),
|
||||
);
|
||||
return element;
|
||||
}
|
||||
|
||||
function openNoticeModal(
|
||||
@@ -386,15 +356,11 @@ function openNoticeModal(
|
||||
.replace(/\[\[[\w]+[:][\w]+[\]\]]+/g, "")
|
||||
.replace(/ +/, " ");
|
||||
|
||||
const existingModal = document.getElementById("notice-modal");
|
||||
if (existingModal) {
|
||||
existingModal.remove();
|
||||
}
|
||||
document.getElementById("notice-modal")?.remove();
|
||||
|
||||
const sourceRect = sourceElement.getBoundingClientRect();
|
||||
let scrollY = Math.round(window.scrollY);
|
||||
let scrollX = Math.round(window.scrollX);
|
||||
|
||||
let sourceLeft = sourceRect.left;
|
||||
let sourceTop = sourceRect.top;
|
||||
let sourceWidth = sourceRect.width;
|
||||
@@ -476,7 +442,6 @@ function openNoticeModal(
|
||||
let targetHeight = Math.round(
|
||||
Math.min(Math.max(measuredHeight, 200), viewportHeight * 0.85),
|
||||
);
|
||||
|
||||
let targetLeft = Math.round((viewportWidth - targetWidth) / 2);
|
||||
let targetTop = Math.round((viewportHeight - targetHeight) / 2) + scrollY;
|
||||
|
||||
@@ -585,13 +550,10 @@ function openNoticeModal(
|
||||
const newTargetWidth = Math.round(
|
||||
Math.min(Math.max(newSourceWidth, 800), newViewportWidth - 40),
|
||||
);
|
||||
|
||||
// Just measure the existing modal content
|
||||
const currentHeight = unifiedContent.getBoundingClientRect().height;
|
||||
const newTargetHeight = Math.round(
|
||||
Math.min(Math.max(currentHeight, 200), newViewportHeight * 0.85),
|
||||
);
|
||||
|
||||
const newTargetLeft = Math.round((newViewportWidth - newTargetWidth) / 2);
|
||||
const newTargetTop =
|
||||
Math.round((newViewportHeight - newTargetHeight) / 2) + newScrollY;
|
||||
@@ -656,116 +618,92 @@ function callHomeTimetable(date: string, change?: any) {
|
||||
xhr.setRequestHeader("Content-Type", "application/json; charset=utf-8");
|
||||
|
||||
xhr.onreadystatechange = function () {
|
||||
if (xhr.readyState === 4) {
|
||||
if (loadingTimeout) {
|
||||
clearTimeout(loadingTimeout);
|
||||
loadingTimeout = null;
|
||||
}
|
||||
if (xhr.readyState !== 4) return;
|
||||
|
||||
const DayContainer = document.getElementById("day-container")!;
|
||||
if (loadingTimeout) {
|
||||
clearTimeout(loadingTimeout);
|
||||
loadingTimeout = null;
|
||||
}
|
||||
|
||||
try {
|
||||
var serverResponse = JSON.parse(xhr.response);
|
||||
let lessonArray: Array<any> = [];
|
||||
const DayContainer = document.getElementById("day-container")!;
|
||||
|
||||
if (serverResponse.payload.items.length > 0) {
|
||||
if (DayContainer.innerText || change) {
|
||||
for (let i = 0; i < serverResponse.payload.items.length; i++) {
|
||||
lessonArray.push(serverResponse.payload.items[i]);
|
||||
var serverResponse = JSON.parse(xhr.response);
|
||||
let lessonArray: Array<any> = [];
|
||||
|
||||
if (serverResponse.payload.items.length > 0) {
|
||||
if (DayContainer.innerText || change) {
|
||||
for (let i = 0; i < serverResponse.payload.items.length; i++) {
|
||||
lessonArray.push(serverResponse.payload.items[i]);
|
||||
}
|
||||
lessonArray.sort(function (a, b) {
|
||||
return a.from.localeCompare(b.from);
|
||||
});
|
||||
|
||||
GetLessonColours().then((colours) => {
|
||||
for (let i = 0; i < lessonArray.length; i++) {
|
||||
let subjectname =
|
||||
lessonArray[i].type == "tutorial"
|
||||
? `timetable.tutor.${lessonArray[i].tutorID}`
|
||||
: `timetable.subject.colour.${lessonArray[i].code}`;
|
||||
let subject = colours.find(
|
||||
(element: any) => element.name === subjectname,
|
||||
);
|
||||
|
||||
if (!subject) {
|
||||
lessonArray[i].colour = "--item-colour: #8e8e8e;";
|
||||
} else {
|
||||
lessonArray[i].colour = `--item-colour: ${subject.value};`;
|
||||
if (GetThresholdOfColor(subject.value) > 300) {
|
||||
lessonArray[i].invert = true;
|
||||
}
|
||||
}
|
||||
lessonArray.sort(function (a, b) {
|
||||
return a.from.localeCompare(b.from);
|
||||
});
|
||||
|
||||
GetLessonColours().then((colours) => {
|
||||
let subjects = colours;
|
||||
for (let i = 0; i < lessonArray.length; i++) {
|
||||
|
||||
let subjectname = ((lessonArray[i].type == "tutorial") ? `timetable.tutor.${lessonArray[i].tutorID}` : `timetable.subject.colour.${lessonArray[i].code}`);
|
||||
lessonArray[i].from = lessonArray[i].from.substring(0, 5);
|
||||
lessonArray[i].until = lessonArray[i].until.substring(0, 5);
|
||||
|
||||
let subject = subjects.find(
|
||||
(element: any) => element.name === subjectname,
|
||||
);
|
||||
if (!subject) {
|
||||
lessonArray[i].colour = "--item-colour: #8e8e8e;";
|
||||
} else {
|
||||
lessonArray[i].colour = `--item-colour: ${subject.value};`;
|
||||
let result = GetThresholdOfColor(subject.value);
|
||||
if (settingsState.timeFormat === "12") {
|
||||
lessonArray[i].from = convertTo12HourFormat(lessonArray[i].from);
|
||||
lessonArray[i].until = convertTo12HourFormat(
|
||||
lessonArray[i].until,
|
||||
);
|
||||
}
|
||||
|
||||
if (result > 300) {
|
||||
lessonArray[i].invert = true;
|
||||
}
|
||||
}
|
||||
|
||||
lessonArray[i].from = lessonArray[i].from.substring(0, 5);
|
||||
lessonArray[i].until = lessonArray[i].until.substring(0, 5);
|
||||
|
||||
if (settingsState.timeFormat === "12") {
|
||||
lessonArray[i].from = convertTo12HourFormat(
|
||||
lessonArray[i].from,
|
||||
);
|
||||
lessonArray[i].until = convertTo12HourFormat(
|
||||
lessonArray[i].until,
|
||||
);
|
||||
}
|
||||
|
||||
lessonArray[i].attendanceTitle = CheckUnmarkedAttendance(
|
||||
lessonArray[i].attendance,
|
||||
);
|
||||
}
|
||||
|
||||
DayContainer.innerText = "";
|
||||
for (let i = 0; i < lessonArray.length; i++) {
|
||||
var div = makeLessonDiv(lessonArray[i], i + 1);
|
||||
|
||||
if (lessonArray[i].invert) {
|
||||
const div1 = div.firstChild! as HTMLElement;
|
||||
div1.classList.add("day-inverted");
|
||||
}
|
||||
|
||||
DayContainer.append(div.firstChild as HTMLElement);
|
||||
}
|
||||
|
||||
DayContainer.classList.remove("loading");
|
||||
|
||||
const today = new Date();
|
||||
if (currentSelectedDate.getDate() == today.getDate()) {
|
||||
for (let i = 0; i < lessonArray.length; i++) {
|
||||
CheckCurrentLesson(lessonArray[i], i + 1);
|
||||
}
|
||||
|
||||
CheckCurrentLessonAll(lessonArray);
|
||||
}
|
||||
});
|
||||
lessonArray[i].attendanceTitle = CheckUnmarkedAttendance(
|
||||
lessonArray[i].attendance,
|
||||
);
|
||||
}
|
||||
|
||||
DayContainer.innerText = "";
|
||||
for (let i = 0; i < lessonArray.length; i++) {
|
||||
const div = makeLessonDiv(lessonArray[i], i + 1);
|
||||
if (lessonArray[i].invert) {
|
||||
(div.firstChild! as HTMLElement).classList.add("day-inverted");
|
||||
}
|
||||
DayContainer.append(div.firstChild as HTMLElement);
|
||||
}
|
||||
} else {
|
||||
DayContainer.innerHTML = "";
|
||||
var dummyDay = document.createElement("div");
|
||||
dummyDay.classList.add("day-empty");
|
||||
let img = document.createElement("img");
|
||||
img.src = browser.runtime.getURL(LogoLight);
|
||||
let text = document.createElement("p");
|
||||
text.innerText = "No lessons available.";
|
||||
dummyDay.append(img);
|
||||
dummyDay.append(text);
|
||||
DayContainer.append(dummyDay);
|
||||
|
||||
DayContainer.classList.remove("loading");
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error loading timetable data:", error);
|
||||
|
||||
DayContainer.classList.remove("loading");
|
||||
|
||||
DayContainer.innerHTML = "";
|
||||
const errorDiv = document.createElement("div");
|
||||
errorDiv.classList.add("day-empty");
|
||||
errorDiv.innerHTML = `
|
||||
<img src="${browser.runtime.getURL(LogoLight)}" />
|
||||
<p>Error loading lessons. Please try again.</p>
|
||||
`;
|
||||
DayContainer.append(errorDiv);
|
||||
const today = new Date();
|
||||
if (currentSelectedDate.getDate() == today.getDate()) {
|
||||
for (let i = 0; i < lessonArray.length; i++) {
|
||||
CheckCurrentLesson(lessonArray[i], i + 1);
|
||||
}
|
||||
CheckCurrentLessonAll(lessonArray);
|
||||
}
|
||||
});
|
||||
}
|
||||
} else {
|
||||
DayContainer.innerHTML = "";
|
||||
const dummyDay = document.createElement("div");
|
||||
dummyDay.classList.add("day-empty");
|
||||
const img = document.createElement("img");
|
||||
img.src = browser.runtime.getURL(LogoLight);
|
||||
const text = document.createElement("p");
|
||||
text.innerText = "No lessons available.";
|
||||
dummyDay.append(img, text);
|
||||
DayContainer.append(dummyDay);
|
||||
DayContainer.classList.remove("loading");
|
||||
}
|
||||
};
|
||||
xhr.send(
|
||||
@@ -855,8 +793,6 @@ async function CheckCurrentLesson(lesson: any, num: number) {
|
||||
}
|
||||
|
||||
function makeLessonDiv(lesson: any, num: number) {
|
||||
if (!lesson) throw new Error("No lesson provided.");
|
||||
|
||||
const {
|
||||
code,
|
||||
colour,
|
||||
@@ -869,14 +805,14 @@ function makeLessonDiv(lesson: any, num: number) {
|
||||
programmeID,
|
||||
metaID,
|
||||
assessments,
|
||||
type
|
||||
type,
|
||||
} = lesson;
|
||||
|
||||
let lessonString = `
|
||||
<div class="day" id="${code + num}" style="${colour}">
|
||||
<h2>${(type == "class") ? description : (type == "tutorial") ? "Tutorial" : "Unknown"}</h2>
|
||||
<h2>${type == "class" ? description : type == "tutorial" ? "Tutorial" : "Unknown"}</h2>
|
||||
<h3>${staff || "Unknown"}</h3>
|
||||
<h3>${(type == "class") ? room : (type == "tutorial") ? "N/A" : "Unknown"}</h3>
|
||||
<h3>${type == "class" ? room : type == "tutorial" ? "N/A" : "Unknown"}</h3>
|
||||
<h4>${from || "Unknown"} - ${until || "Unknown"}</h4>
|
||||
<h5>${attendanceTitle || "Unknown"}</h5>
|
||||
`;
|
||||
@@ -922,64 +858,48 @@ function buildAssessmentURL(programmeID: any, metaID: any, itemID = "") {
|
||||
}
|
||||
|
||||
function CheckUnmarkedAttendance(lessonattendance: any) {
|
||||
if (lessonattendance) {
|
||||
var lesson = lessonattendance.label;
|
||||
} else {
|
||||
lesson = " ";
|
||||
}
|
||||
return lesson;
|
||||
return lessonattendance ? lessonattendance.label : " ";
|
||||
}
|
||||
|
||||
async function CreateUpcomingSection(assessments: any, activeSubjects: any) {
|
||||
let upcomingitemcontainer = document.querySelector("#upcoming-items");
|
||||
let overdueDates = [];
|
||||
let upcomingDates = {};
|
||||
|
||||
var Today = new Date();
|
||||
const upcomingitemcontainer = document.querySelector("#upcoming-items");
|
||||
const overdueDates = [];
|
||||
const upcomingDates = {};
|
||||
const Today = new Date();
|
||||
|
||||
for (let i = 0; i < assessments.length; i++) {
|
||||
const assessment = assessments[i];
|
||||
let assessmentdue = new Date(assessment.due);
|
||||
|
||||
CheckSpecialDay(Today, assessmentdue);
|
||||
if (assessmentdue < Today) {
|
||||
if (!CheckSpecialDay(Today, assessmentdue)) {
|
||||
overdueDates.push(assessment);
|
||||
assessments.splice(i, 1);
|
||||
i--;
|
||||
}
|
||||
const assessmentdue = new Date(assessments[i].due);
|
||||
if (assessmentdue < Today && !CheckSpecialDay(Today, assessmentdue)) {
|
||||
overdueDates.push(assessments[i]);
|
||||
assessments.splice(i, 1);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
|
||||
var TomorrowDate = new Date();
|
||||
TomorrowDate.setDate(TomorrowDate.getDate() + 1);
|
||||
|
||||
const colours = await GetLessonColours();
|
||||
|
||||
let subjects = colours;
|
||||
for (let i = 0; i < assessments.length; i++) {
|
||||
let subjectname = `timetable.subject.colour.${assessments[i].code}`;
|
||||
|
||||
let subject = subjects.find((element: any) => element.name === subjectname);
|
||||
|
||||
const subject = colours.find(
|
||||
(element: any) =>
|
||||
element.name === `timetable.subject.colour.${assessments[i].code}`,
|
||||
);
|
||||
if (!subject) {
|
||||
assessments[i].colour = "--item-colour: #8e8e8e;";
|
||||
} else {
|
||||
assessments[i].colour = `--item-colour: ${subject.value};`;
|
||||
GetThresholdOfColor(subject.value);
|
||||
}
|
||||
}
|
||||
|
||||
for (let i = 0; i < activeSubjects.length; i++) {
|
||||
const element = activeSubjects[i];
|
||||
let subjectname = `timetable.subject.colour.${element.code}`;
|
||||
let colour = colours.find((element: any) => element.name === subjectname);
|
||||
const colour = colours.find(
|
||||
(c: any) => c.name === `timetable.subject.colour.${element.code}`,
|
||||
);
|
||||
if (!colour) {
|
||||
element.colour = "--item-colour: #8e8e8e;";
|
||||
} else {
|
||||
element.colour = `--item-colour: ${colour.value};`;
|
||||
let result = GetThresholdOfColor(colour.value);
|
||||
if (result > 300) {
|
||||
if (GetThresholdOfColor(colour.value) > 300) {
|
||||
element.invert = true;
|
||||
}
|
||||
}
|
||||
@@ -987,52 +907,35 @@ async function CreateUpcomingSection(assessments: any, activeSubjects: any) {
|
||||
|
||||
CreateFilters(activeSubjects);
|
||||
|
||||
let type;
|
||||
let class_;
|
||||
|
||||
for (let i = 0; i < assessments.length; i++) {
|
||||
const element: any = assessments[i];
|
||||
if (!upcomingDates[element.due as keyof typeof upcomingDates]) {
|
||||
let dateObj: any = new Object();
|
||||
dateObj.div = CreateElement(
|
||||
(type = "div"),
|
||||
(class_ = "upcoming-date-container"),
|
||||
);
|
||||
dateObj.assessments = [];
|
||||
const dateObj: any = {
|
||||
div: CreateElement("div", "upcoming-date-container"),
|
||||
assessments: [],
|
||||
};
|
||||
(upcomingDates[element.due as keyof typeof upcomingDates] as any) =
|
||||
dateObj;
|
||||
}
|
||||
let assessmentDateDiv =
|
||||
const assessmentDateDiv =
|
||||
upcomingDates[element.due as keyof typeof upcomingDates];
|
||||
|
||||
if (assessmentDateDiv) {
|
||||
(assessmentDateDiv as any).assessments.push(element);
|
||||
}
|
||||
}
|
||||
|
||||
for (var date in upcomingDates) {
|
||||
let assessmentdue = new Date(
|
||||
const assessmentdue = new Date(
|
||||
(
|
||||
upcomingDates[date as keyof typeof upcomingDates] as any
|
||||
).assessments[0].due,
|
||||
);
|
||||
let specialcase = CheckSpecialDay(Today, assessmentdue);
|
||||
let assessmentDate;
|
||||
|
||||
if (specialcase) {
|
||||
let datecase: string = specialcase!;
|
||||
assessmentDate = createAssessmentDateDiv(
|
||||
date,
|
||||
upcomingDates[date as keyof typeof upcomingDates],
|
||||
|
||||
datecase,
|
||||
);
|
||||
} else {
|
||||
assessmentDate = createAssessmentDateDiv(
|
||||
date,
|
||||
upcomingDates[date as keyof typeof upcomingDates],
|
||||
);
|
||||
}
|
||||
const specialcase = CheckSpecialDay(Today, assessmentdue);
|
||||
const assessmentDate = createAssessmentDateDiv(
|
||||
date,
|
||||
upcomingDates[date as keyof typeof upcomingDates],
|
||||
specialcase,
|
||||
);
|
||||
|
||||
if (specialcase === "Yesterday") {
|
||||
upcomingitemcontainer!.insertBefore(
|
||||
@@ -1044,7 +947,7 @@ async function CreateUpcomingSection(assessments: any, activeSubjects: any) {
|
||||
}
|
||||
}
|
||||
FilterUpcomingAssessments(settingsState.subjectfilters);
|
||||
|
||||
|
||||
if (assessments.length === 0) {
|
||||
upcomingitemcontainer!.innerHTML = `
|
||||
<div class="day-empty">
|
||||
@@ -1055,77 +958,68 @@ async function CreateUpcomingSection(assessments: any, activeSubjects: any) {
|
||||
}
|
||||
|
||||
function createAssessmentDateDiv(date: string, value: any, datecase?: any) {
|
||||
var options = {
|
||||
const options = {
|
||||
weekday: "long" as "long",
|
||||
month: "long" as "long",
|
||||
day: "numeric" as "numeric",
|
||||
};
|
||||
const FormattedDate = new Date(date);
|
||||
|
||||
const assessments = value.assessments;
|
||||
const container = value.div;
|
||||
|
||||
let DateTitleDiv = document.createElement("div");
|
||||
const DateTitleDiv = document.createElement("div");
|
||||
DateTitleDiv.classList.add("upcoming-date-title");
|
||||
|
||||
if (datecase) {
|
||||
let datetitle = document.createElement("h5");
|
||||
const datetitle = document.createElement("h5");
|
||||
datetitle.classList.add("upcoming-special-day");
|
||||
datetitle.innerText = datecase;
|
||||
DateTitleDiv.append(datetitle);
|
||||
container.setAttribute("data-day", datecase);
|
||||
}
|
||||
|
||||
let DateTitle = document.createElement("h5");
|
||||
const DateTitle = document.createElement("h5");
|
||||
DateTitle.innerText = FormattedDate.toLocaleDateString("en-AU", options);
|
||||
DateTitleDiv.append(DateTitle);
|
||||
|
||||
container.append(DateTitleDiv);
|
||||
|
||||
let assessmentContainer = document.createElement("div");
|
||||
const assessmentContainer = document.createElement("div");
|
||||
assessmentContainer.classList.add("upcoming-date-assessments");
|
||||
|
||||
for (let i = 0; i < assessments.length; i++) {
|
||||
const element = assessments[i];
|
||||
let item = document.createElement("div");
|
||||
const item = document.createElement("div");
|
||||
item.classList.add("upcoming-assessment");
|
||||
item.setAttribute("data-subject", element.code);
|
||||
item.id = `assessment${element.id}`;
|
||||
|
||||
item.style.cssText = element.colour;
|
||||
|
||||
let titlediv = document.createElement("div");
|
||||
const titlediv = document.createElement("div");
|
||||
titlediv.classList.add("upcoming-subject-title");
|
||||
|
||||
let titlesvg =
|
||||
titlediv.append(
|
||||
stringToHTML(`<svg viewBox="0 0 24 24" style="width:35px;height:35px;fill:white;">
|
||||
<path d="M6 20H13V22H6C4.89 22 4 21.11 4 20V4C4 2.9 4.89 2 6 2H18C19.11 2 20 2.9 20 4V12.54L18.5 11.72L18 12V4H13V12L10.5 9.75L8 12V4H6V20M24 17L18.5 14L13 17L18.5 20L24 17M15 19.09V21.09L18.5 23L22 21.09V19.09L18.5 21L15 19.09Z"></path>
|
||||
</svg>`).firstChild;
|
||||
titlediv.append(titlesvg!);
|
||||
</svg>`).firstChild!,
|
||||
);
|
||||
|
||||
let detailsdiv = document.createElement("div");
|
||||
const detailsdiv = document.createElement("div");
|
||||
detailsdiv.classList.add("upcoming-details");
|
||||
let detailstitle = document.createElement("h5");
|
||||
const detailstitle = document.createElement("h5");
|
||||
detailstitle.innerText = `${element.subject} assessment`;
|
||||
let subject = document.createElement("p");
|
||||
const subject = document.createElement("p");
|
||||
subject.innerText = element.title;
|
||||
subject.classList.add("upcoming-assessment-title");
|
||||
subject.onclick = function () {
|
||||
document.querySelector("#menu ul")!.classList.add("noscroll");
|
||||
location.href = `../#?page=/assessments/${element.programmeID}:${element.metaclassID}&item=${element.id}`;
|
||||
};
|
||||
detailsdiv.append(detailstitle);
|
||||
detailsdiv.append(subject);
|
||||
|
||||
item.append(titlediv);
|
||||
item.append(detailsdiv);
|
||||
detailsdiv.append(detailstitle, subject);
|
||||
item.append(titlediv, detailsdiv);
|
||||
assessmentContainer.append(item);
|
||||
|
||||
fetch(`${location.origin}/seqta/student/assessment/submissions/get`, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json; charset=utf-8",
|
||||
},
|
||||
headers: { "Content-Type": "application/json; charset=utf-8" },
|
||||
body: JSON.stringify({
|
||||
assessment: element.id,
|
||||
metaclass: element.metaclassID,
|
||||
@@ -1136,8 +1030,7 @@ function createAssessmentDateDiv(date: string, value: any, datecase?: any) {
|
||||
.then((response) => {
|
||||
if (response.payload.length > 0) {
|
||||
const assessment = document.querySelector(`#assessment${element.id}`);
|
||||
|
||||
let submittedtext = document.createElement("div");
|
||||
const submittedtext = document.createElement("div");
|
||||
submittedtext.classList.add("upcoming-submittedtext");
|
||||
submittedtext.innerText = "Submitted";
|
||||
assessment!.append(submittedtext);
|
||||
@@ -1175,36 +1068,37 @@ function CheckSpecialDay(date1: Date, date2: Date) {
|
||||
}
|
||||
|
||||
async function GetLessonColours() {
|
||||
let func = fetch(`${location.origin}/seqta/student/load/prefs?`, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json; charset=utf-8",
|
||||
},
|
||||
body: JSON.stringify({ request: "userPrefs", asArray: true, user: 69 }),
|
||||
});
|
||||
return func
|
||||
.then((result) => result.json())
|
||||
.then((response) => response.payload);
|
||||
try {
|
||||
return fetch(`${location.origin}/seqta/student/load/prefs?`, {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json; charset=utf-8" },
|
||||
body: JSON.stringify({ request: "userPrefs", asArray: true, user: 69 }),
|
||||
})
|
||||
.then((result) => result.json())
|
||||
.then((response) => response.payload);
|
||||
} catch (error) {
|
||||
console.error("[BetterSEQTA+] Failed to get lesson colours:", error);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
function CreateFilters(subjects: any) {
|
||||
let filteroptions = settingsState.subjectfilters;
|
||||
const filteroptions = settingsState.subjectfilters;
|
||||
const filterdiv = document.querySelector("#upcoming-filters");
|
||||
|
||||
let filterdiv = document.querySelector("#upcoming-filters");
|
||||
for (let i = 0; i < subjects.length; i++) {
|
||||
const element = subjects[i];
|
||||
|
||||
if (!Object.prototype.hasOwnProperty.call(filteroptions, element.code)) {
|
||||
filteroptions[element.code] = true;
|
||||
settingsState.subjectfilters = filteroptions;
|
||||
}
|
||||
let elementdiv = CreateSubjectFilter(
|
||||
element.code,
|
||||
element.colour,
|
||||
filteroptions[element.code],
|
||||
filterdiv!.append(
|
||||
CreateSubjectFilter(
|
||||
element.code,
|
||||
element.colour,
|
||||
filteroptions[element.code],
|
||||
),
|
||||
);
|
||||
|
||||
filterdiv!.append(elementdiv);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1213,23 +1107,20 @@ function CreateSubjectFilter(
|
||||
itemcolour: string,
|
||||
checked: any,
|
||||
) {
|
||||
let label = CreateElement("label", "upcoming-checkbox-container");
|
||||
const label = CreateElement("label", "upcoming-checkbox-container");
|
||||
label.innerText = subjectcode;
|
||||
let input1 = CreateElement("input");
|
||||
const input = input1 as HTMLInputElement;
|
||||
const input = CreateElement("input") as HTMLInputElement;
|
||||
input.type = "checkbox";
|
||||
input.checked = checked;
|
||||
input.id = `filter-${subjectcode}`;
|
||||
label.style.cssText = itemcolour;
|
||||
let span = CreateElement("span", "upcoming-checkmark");
|
||||
label.append(input);
|
||||
label.append(span);
|
||||
const span = CreateElement("span", "upcoming-checkmark");
|
||||
label.append(input, span);
|
||||
|
||||
input.addEventListener("change", function (change) {
|
||||
let filters = settingsState.subjectfilters;
|
||||
let id = (change.target as HTMLInputElement)!.id.split("-")[1];
|
||||
filters[id] = (change.target as HTMLInputElement)!.checked;
|
||||
|
||||
const filters = settingsState.subjectfilters;
|
||||
const id = (change.target as HTMLInputElement).id.split("-")[1];
|
||||
filters[id] = (change.target as HTMLInputElement).checked;
|
||||
settingsState.subjectfilters = filters;
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user