import { ref, watch, computed } from "vue"; import router from "./router"; import i18n from "./main"; export const lastRoute = ref(); export const loading = ref(false); export const loadingProgress = ref(0); export const classFilter = ref(localStorage.getItem("classFilter") || "none"); export const timetableGroups = ref( JSON.parse(localStorage.getItem("timetableGroups") || "[]") ); export const language = ref(localStorage.getItem("lang") || "en"); export const theme = ref(localStorage.getItem("theme") || "auto"); watch(classFilter, (newValue) => { localStorage.setItem("classFilter", newValue); fetchData(); }); watch(timetableGroups, (newValue) => { localStorage.setItem("timetableGroups", JSON.stringify(newValue)); fetchData(); }); watch(language, (newValue) => { localStorage.setItem("lang", newValue); location.reload(); }); watch(theme, (newValue) => { localStorage.setItem("theme", newValue); }); // Set this to a positive or negative integer // to change selectedDate by this number export const changeDay = ref(0); // Set this to jump to a specific date export const changeDate = ref(new Date()); export const selectedDate = ref(new Date(new Date().setUTCHours(0, 0, 0, 0))); export const selectedDay = computed(() => selectedDate.value.getDay() - 1); // Jump to next Monday if it is weekend if (selectedDay.value == 5) selectedDate.value = new Date(selectedDate.value.getTime() + 86400000 * 2); if (selectedDay.value == -1) selectedDate.value = new Date(selectedDate.value.getTime() + 86400000); // Load new data if date changes watch(selectedDate, async () => { loadingProgress.value = 0.1; loading.value = true; await fetchSubstitutions(); loadingProgress.value = 1 / 2; await fetchHistory(); loadingProgress.value = 1; loading.value = false; }); export const timetable = ref({ trusted: true }); export const substitutions = ref([]); export const history = ref([]); export const classList = ref([]); export const historyOfDate = computed(() => { const dates = {}; for (const entry of history.value) { const date = entry.date; if (!dates[date]) dates[date] = []; dates[entry.date].push(entry); } return dates; }); export const substitutionsForDate = computed(() => { const dates = {}; for (const substitution of substitutions.value) { const date = substitution.date; if (!dates[date]) dates[date] = []; dates[substitution.date].push(substitution); } return dates; }); export const parsedTimetable = computed(() => { if (!timetable.value.data) return []; return timetable.value.data.map((day) => { const newDay = []; for (const lesson of day) { var usedLesson = lesson; // Check for timetable groups if (Array.isArray(lesson)) { var matchingLesson = lesson.find((e) => timetableGroups.value.includes(e.group) ); if (!matchingLesson) { matchingLesson = { subject: lesson.map((e) => e.subject).join(" / "), teacher: i18n.global.t("timetable.configureTimetableGroup"), length: lesson[0].length || 1, }; } usedLesson = matchingLesson; } const lessonLength = usedLesson.length || 1; delete usedLesson.length; for (var i = 0; i < lessonLength; i++) newDay.push(usedLesson); } return newDay; }); }); export const possibleTimetableGroups = computed(() => { const foundTimetableGroups = []; if (!timetable.value.data) return []; for (const day of timetable.value.data) { for (const lesson of day) { if (Array.isArray(lesson)) { for (const group of lesson) { if (!foundTimetableGroups.includes(group.group)) { foundTimetableGroups.push(group.group); } } } } } return foundTimetableGroups; }); const baseUrl = import.meta.env.VITE_API_ENDPOINT || "/api"; export async function fetchData() { loadingProgress.value = 0.1; loading.value = true; const checkResponse = await fetch(`${baseUrl}/check`); if (checkResponse.status != 200) router.push("/login"); loadingProgress.value = 1 / 5; await fetchClassList(); loadingProgress.value = 2 / 5; await fetchTimetable(); loadingProgress.value = 3 / 5; await fetchSubstitutions(); loadingProgress.value = 4 / 5; await fetchHistory(); loadingProgress.value = 1; loading.value = false; } export async function fetchClassList() { const classListResponse = await fetch(`${baseUrl}/classes`); const classListData = await classListResponse.json(); classList.value = classListData; } export async function fetchTimetable() { const timetableResponse = await fetch( `${baseUrl}/timetable?class=${classFilter.value}` ); const timetableData = await timetableResponse.json(); if (timetableData.error) { console.warn("API Error: " + timetableData.error); timetable.value = { trusted: true, source: "", data: [] }; } else timetable.value = timetableData; } export async function fetchSubstitutions() { const requestDate = `?date=${selectedDate.value.getTime()}`; const substitutionResponse = await fetch( classFilter.value == "none" ? `${baseUrl}/substitutions${requestDate}` : `${baseUrl}/substitutions${requestDate}&class=${classFilter.value}` ); const substitutionData = await substitutionResponse.json(); substitutions.value = substitutionData; } export async function fetchHistory() { const requestDate = `?date=${selectedDate.value.getTime()}`; const historyResponse = await fetch( classFilter.value == "none" ? `${baseUrl}/history${requestDate}` : `${baseUrl}/history${requestDate}&class=${classFilter.value}` ); const historyData = await historyResponse.json(); if (historyData.error) console.warn("API Error: " + historyData.error); else history.value = historyData; } fetchData();