diff --git a/backend/Dockerfile b/backend/Dockerfile index 67a9d42..655af93 100644 --- a/backend/Dockerfile +++ b/backend/Dockerfile @@ -1,4 +1,4 @@ -FROM golang:1.21.3-alpine +FROM golang:1.21-alpine # Set the Current Working Directory inside the container WORKDIR /app diff --git a/backend/go.mod b/backend/go.mod index 660cc3d..3a2ca8b 100644 --- a/backend/go.mod +++ b/backend/go.mod @@ -1,6 +1,6 @@ module htwkalender -go 1.21.3 +go 1.21 require ( github.com/google/uuid v1.3.1 diff --git a/backend/service/fetch/v1/fetchSeminarEventService.go b/backend/service/fetch/v1/fetchSeminarEventService.go index bc1af4c..6238c44 100644 --- a/backend/service/fetch/v1/fetchSeminarEventService.go +++ b/backend/service/fetch/v1/fetchSeminarEventService.go @@ -64,18 +64,22 @@ func GetSeminarGroupsEventsFromHTML(seminarGroupsLabel []string) []model.Seminar var seminarGroups []model.SeminarGroup for _, seminarGroupLabel := range seminarGroupsLabel { - ssUrl := "https://stundenplan.htwk-leipzig.de/" + string("ss") + "/Berichte/Text-Listen;Studenten-Sets;name;" + seminarGroupLabel + "?template=sws_semgrp&weeks=1-65" - result, getError := fetch.GetHTML(ssUrl) - if getError == nil { - seminarGroup := parseSeminarGroup(result) - seminarGroups = append(seminarGroups, seminarGroup) + if (time.Now().Month() >= 3) && (time.Now().Month() <= 10) { + ssUrl := "https://stundenplan.htwk-leipzig.de/" + string("ss") + "/Berichte/Text-Listen;Studenten-Sets;name;" + seminarGroupLabel + "?template=sws_semgrp&weeks=1-65" + result, getError := fetch.GetHTML(ssUrl) + if getError == nil { + seminarGroup := parseSeminarGroup(result) + seminarGroups = append(seminarGroups, seminarGroup) + } } - wsUrl := "https://stundenplan.htwk-leipzig.de/" + string("ws") + "/Berichte/Text-Listen;Studenten-Sets;name;" + seminarGroupLabel + "?template=sws_semgrp&weeks=1-65" - result, getError = fetch.GetHTML(wsUrl) - if getError == nil { - seminarGroup := parseSeminarGroup(result) - seminarGroups = append(seminarGroups, seminarGroup) + if (time.Now().Month() >= 9) || (time.Now().Month() <= 4) { + wsUrl := "https://stundenplan.htwk-leipzig.de/" + string("ws") + "/Berichte/Text-Listen;Studenten-Sets;name;" + seminarGroupLabel + "?template=sws_semgrp&weeks=1-65" + result, getError := fetch.GetHTML(wsUrl) + if getError == nil { + seminarGroup := parseSeminarGroup(result) + seminarGroups = append(seminarGroups, seminarGroup) + } } } return seminarGroups diff --git a/frontend/src/App.vue b/frontend/src/App.vue index 153089b..6d84655 100644 --- a/frontend/src/App.vue +++ b/frontend/src/App.vue @@ -1,11 +1,24 @@ diff --git a/frontend/src/components/CalendarPreview.vue b/frontend/src/components/CalendarPreview.vue new file mode 100644 index 0000000..c9da149 --- /dev/null +++ b/frontend/src/components/CalendarPreview.vue @@ -0,0 +1,84 @@ + + + + + diff --git a/frontend/src/components/ModuleSelection.vue b/frontend/src/components/ModuleSelection.vue index 9500ca8..7c6f1f8 100644 --- a/frontend/src/components/ModuleSelection.vue +++ b/frontend/src/components/ModuleSelection.vue @@ -1,9 +1,10 @@ @@ -61,31 +45,29 @@ function nextStep() {
- + - + diff --git a/frontend/src/components/RenameModules.vue b/frontend/src/components/RenameModules.vue index 0e90c17..21220fd 100644 --- a/frontend/src/components/RenameModules.vue +++ b/frontend/src/components/RenameModules.vue @@ -9,8 +9,9 @@ import { onlyWhitespace } from "../helpers/strings.ts"; import { useI18n } from "vue-i18n"; const { t } = useI18n({ useScope: "global" }); +const store = moduleStore(); const tableData = ref( - moduleStore().modules.map((module) => { + store.getAllModules().map((module) => { return { Course: module.course, Module: module, @@ -25,7 +26,7 @@ const columns = computed(() => [ ]); async function finalStep() { - const token: string = await createIndividualFeed(moduleStore().modules); + const token: string = await createIndividualFeed(store.getAllModules()); tokenStore().setToken(token); await router.push("/calendar-link"); } @@ -124,10 +125,4 @@ async function finalStep() {
- + diff --git a/frontend/src/components/editCalendar/EditModules.vue b/frontend/src/components/editCalendar/EditModules.vue index bb5c3f6..8f13bbf 100644 --- a/frontend/src/components/editCalendar/EditModules.vue +++ b/frontend/src/components/editCalendar/EditModules.vue @@ -11,8 +11,9 @@ import { onlyWhitespace } from "../../helpers/strings.ts"; import { useI18n } from "vue-i18n"; const { t } = useI18n({ useScope: "global" }); +const store = moduleStore(); const tableData = computed(() => - moduleStore().modules.map((module: Module) => { + store.getAllModules().map((module: Module) => { return { Course: module.course, Module: module, @@ -45,7 +46,7 @@ fetchedModules().then( ); async function finalStep() { - await saveIndividualFeed(tokenStore().token, moduleStore().modules); + await saveIndividualFeed(tokenStore().token, store.getAllModules()); await router.push("/calendar-link"); } @@ -159,10 +160,4 @@ async function finalStep() {
- + diff --git a/frontend/src/i18n/translations/de.json b/frontend/src/i18n/translations/de.json index d059bce..bd84f6e 100644 --- a/frontend/src/i18n/translations/de.json +++ b/frontend/src/i18n/translations/de.json @@ -38,7 +38,7 @@ "semester": "Semester", "module": "Modul", "day": "Tag", - "start": "Begin", + "start": "Anfang", "end": "Ende", "room": "Raum", "type": "Art", @@ -57,8 +57,17 @@ "dropDown": "Wähle weitere Module aus", "module": "Modul", "modules": "Module", - "dropDownFooterSelected": "ausgewählt", - "nextStep": "Weiter" + "footerModulesSelected": "{count} Modul ausgewählt | {count} Module ausgewählt", + "nextStep": "Weiter", + "professor": "Dozent", + "course": "Seminargruppe", + "info": "Info", + "info-long": "Information", + "paginator": { + "from": "", + "to": " bis ", + "of": " von insgesamt " + } }, "renameModules": { "reminder": "Erinnerung", @@ -90,6 +99,12 @@ "toGoogleCalendar": "Google Kalender", "toMicrosoftCalendar": "Microsoft Kalender" }, + "calendarPreview": { + "preview": "Vorschau", + "preview-long": "Kalendervorschau", + "module": "Modul", + "course": "Seminargruppe" + }, "faqView": { "headline": "Fragen und Antworten", "firstQuestion": "Wie funktioniert das Kalender erstellen mit dem HTWKalender?", diff --git a/frontend/src/i18n/translations/en.json b/frontend/src/i18n/translations/en.json index cf7d08a..2e76316 100644 --- a/frontend/src/i18n/translations/en.json +++ b/frontend/src/i18n/translations/en.json @@ -53,12 +53,21 @@ "noCalendarFound": "no calendar found" }, "additionalModules": { - "subTitle": "Select additional Modules that are not listed in the regular semester for your Course", + "subTitle": "Select additional modules that are not listed in the regular semester for your course", "dropDown": "Select additional modules", "module": "module", "modules": "modules", - "dropDownFooterSelected": "selected", - "nextStep": "next step" + "footerModulesSelected": "{count} module selected | {count} modules selected", + "nextStep": "next step", + "professor": "professor", + "course": "course", + "info": "info", + "info-long": "information", + "paginator": { + "from": "", + "to": " to ", + "of": " of " + } }, "renameModules": { "reminder": "reminder", @@ -90,6 +99,12 @@ "toGoogleCalendar": "to Google Calendar", "toMicrosoftCalendar": "to Microsoft Calendar" }, + "calendarPreview": { + "preview": "preview", + "preview-long": "calendar preview", + "module": "module", + "course": "course" + }, "faqView": { "headline": "faq", "firstQuestion": "How does calendar creation work with HTWKalender?", diff --git a/frontend/src/main.ts b/frontend/src/main.ts index 3c4bc9b..c2b5e96 100644 --- a/frontend/src/main.ts +++ b/frontend/src/main.ts @@ -16,6 +16,7 @@ import "primevue/resources/themes/viva-dark/theme.css"; import "primeicons/primeicons.css"; import "primeflex/primeflex.css"; import router from "./router"; +import SpeedDial from "primevue/speeddial"; import TabView from "primevue/tabview"; import TabPanel from "primevue/tabpanel"; import Tag from "primevue/tag"; @@ -30,6 +31,7 @@ import Column from "primevue/column"; import DynamicDialog from "primevue/dynamicdialog"; import DialogService from "primevue/dialogservice"; import ProgressSpinner from "primevue/progressspinner"; +import Checkbox from "primevue/checkbox"; import i18n from "./i18n"; const app = createApp(App); @@ -52,6 +54,7 @@ app.component("InputSwitch", InputSwitch); app.component("Card", Card); app.component("DataView", DataView); app.component("ToggleButton", ToggleButton); +app.component("SpeedDial", SpeedDial); app.component("TabView", TabView); app.component("TabPanel", TabPanel); app.component("MultiSelect", MultiSelect); @@ -63,4 +66,5 @@ app.component("DataTable", DataTable); app.component("Column", Column); app.component("DynamicDialog", DynamicDialog); app.component("ProgressSpinner", ProgressSpinner); +app.component("Checkbox", Checkbox); app.mount("#app"); diff --git a/frontend/src/model/module.ts b/frontend/src/model/module.ts index 01f277d..e08c18b 100644 --- a/frontend/src/model/module.ts +++ b/frontend/src/model/module.ts @@ -12,7 +12,7 @@ export class Module { public events: Event[] = [], ) {} - isEqual(module: Module): Boolean { + isEqual(module: Module): boolean { return this.name === module.name && this.course === module.course; } } diff --git a/frontend/src/store/moduleStore.ts b/frontend/src/store/moduleStore.ts index 27f6a2b..281135c 100644 --- a/frontend/src/store/moduleStore.ts +++ b/frontend/src/store/moduleStore.ts @@ -3,18 +3,42 @@ import { defineStore } from "pinia"; const moduleStore = defineStore("moduleStore", { state: () => ({ - modules: [] as Module[], + modules: new Map(), }), actions: { addModule(module: Module) { - this.modules.push(module); + this.modules.set(module.uuid, module); }, removeModule(module: Module) { - this.modules.splice(this.modules.indexOf(module), 1); + this.modules.delete(module.uuid); + }, + hasModule(module: Module): boolean { + return ( + this.modules.has(module.uuid) && + (this.modules.get(module.uuid)?.isEqual(module) ?? false) + ); }, removeAllModules() { - this.modules = []; + this.modules.clear(); }, + overwriteModules(modules: Module[]) { + this.modules.clear(); + modules.forEach((module) => { + this.modules.set(module.uuid, module); + }); + }, + isEmpty(): boolean { + return this.modules.size === 0; + }, + countModules(): number { + return this.modules.size; + }, + getAllModules(): Module[] { + return Array.from(this.modules.values()); + }, + containsModule(module: Module): boolean { + return this.modules.has(module.uuid); + } }, }); diff --git a/frontend/src/style.css b/frontend/src/style.css index 4d2c94a..99b676e 100644 --- a/frontend/src/style.css +++ b/frontend/src/style.css @@ -1,3 +1,10 @@ body { font-family: var(--font-family); } + +.small-button.p-button.p-button-icon-only, +.small-button.p-button.p-button-icon-only.p-button-rounded { + width: 2rem; + height: 2rem; + padding: 0; +} diff --git a/frontend/src/view/AdditionalModules.vue b/frontend/src/view/AdditionalModules.vue index bbb647e..f4f4ed1 100644 --- a/frontend/src/view/AdditionalModules.vue +++ b/frontend/src/view/AdditionalModules.vue @@ -1,12 +1,13 @@