diff --git a/backend/main.go b/backend/main.go index 5e170be..272cba2 100644 --- a/backend/main.go +++ b/backend/main.go @@ -24,6 +24,8 @@ func main() { service.AddRoutes(app) + service.AddSchedules(app) + if err := app.Start(); err != nil { log.Fatal(err) } diff --git a/backend/model/eventModel.go b/backend/model/eventModel.go index f83e22d..daaf229 100644 --- a/backend/model/eventModel.go +++ b/backend/model/eventModel.go @@ -1,3 +1,18 @@ package model type Events []*Event + +type Event struct { + Day string `db:"Day" json:"day"` + Week string `db:"Week" json:"week"` + Start string `db:"Start" json:"start"` + End string `db:"End" json:"end"` + Name string `db:"Name" json:"name"` + EventType string `db:"EventType" json:"eventType"` + Prof string `db:"Prof" json:"prof"` + Rooms string `db:"Rooms" json:"rooms"` + Notes string `db:"Notes" json:"notes"` + BookedAt string `db:"BookedAt" json:"bookedAt"` + Course string `db:"course" json:"course"` + Semester string `db:"semester" json:"semester"` +} diff --git a/backend/model/moduleModel.go b/backend/model/moduleModel.go new file mode 100644 index 0000000..ab0d17f --- /dev/null +++ b/backend/model/moduleModel.go @@ -0,0 +1,9 @@ +package model + +type Module struct { + Name string `json:"name"` + Prof string `json:"prof"` + Course string `json:"course"` + Semester string `json:"semester"` + Events Events `json:"events"` +} diff --git a/backend/model/seminarGroup.go b/backend/model/seminarGroup.go index d9aedbc..d3d63c9 100644 --- a/backend/model/seminarGroup.go +++ b/backend/model/seminarGroup.go @@ -9,18 +9,3 @@ type SeminarGroup struct { FacultyId string Events []Event } - -type Event struct { - Day string `db:"course"` - Week string `db:"Week"` - Start string `db:"Start"` - End string `db:"End"` - Name string `db:"Name"` - EventType string `db:"EventType"` - Prof string `db:"Prof"` - Rooms string `db:"Rooms"` - Notes string `db:"Notes"` - BookedAt string `db:"BookedAt"` - Course string `db:"course"` - Semester string `db:"semester"` -} diff --git a/backend/service/addRoute.go b/backend/service/addRoute.go index 20b9e24..d5066bf 100644 --- a/backend/service/addRoute.go +++ b/backend/service/addRoute.go @@ -9,7 +9,9 @@ import ( "htwkalender/service/fetch" "htwkalender/service/ical" "htwkalender/service/room" + "io" "net/http" + "net/url" "os" ) @@ -71,6 +73,7 @@ func AddRoutes(app *pocketbase.PocketBase) { return nil }) + // API Endpoint to get all events for a specific room on a specific day app.OnBeforeServe().Add(func(e *core.ServeEvent) error { _, err := e.Router.AddRoute(echo.Route{ Method: http.MethodGet, @@ -90,12 +93,19 @@ func AddRoutes(app *pocketbase.PocketBase) { return nil }) + // API Endpoint to create a new iCal feed app.OnBeforeServe().Add(func(e *core.ServeEvent) error { _, err := e.Router.AddRoute(echo.Route{ Method: http.MethodPost, Path: "/api/createFeed", Handler: func(c echo.Context) error { - return ical.CreateIndividualFeed(c, app) + requestBody, _ := io.ReadAll(c.Request().Body) + result, err := ical.CreateIndividualFeed(requestBody, app) + if err != nil { + return c.JSON(http.StatusInternalServerError, err) + } + return c.JSON(http.StatusOK, result) + }, Middlewares: []echo.MiddlewareFunc{ apis.ActivityLogger(app), @@ -132,7 +142,13 @@ func AddRoutes(app *pocketbase.PocketBase) { Handler: func(c echo.Context) error { course := c.QueryParam("course") semester := c.QueryParam("semester") - return events.GetModulesForCourseDistinct(app, c, course, semester) + modules, err := events.GetModulesForCourseDistinct(app, course, semester) + + if err != nil { + return c.JSON(400, err) + } else { + return c.JSON(200, modules) + } }, Middlewares: []echo.MiddlewareFunc{ apis.ActivityLogger(app), @@ -161,12 +177,62 @@ func AddRoutes(app *pocketbase.PocketBase) { return nil }) + app.OnBeforeServe().Add(func(e *core.ServeEvent) error { + _, err := e.Router.AddRoute(echo.Route{ + Method: http.MethodGet, + Path: "/api/module", + Handler: func(c echo.Context) error { + name := c.Request().Header.Get("Name") + name, err := url.QueryUnescape(name) + module, err := events.GetModuleByName(app, name) + + if err != nil { + return c.JSON(400, err) + } else { + return c.JSON(200, module) + } + }, + Middlewares: []echo.MiddlewareFunc{ + apis.ActivityLogger(app), + }, + }) + if err != nil { + return err + } + return nil + }) + app.OnBeforeServe().Add(func(e *core.ServeEvent) error { _, err := e.Router.AddRoute(echo.Route{ Method: http.MethodGet, Path: "/api/courses", Handler: func(c echo.Context) error { - return events.GetAllCourses(app, c) + courses := events.GetAllCourses(app) + return c.JSON(200, courses) + }, + Middlewares: []echo.MiddlewareFunc{ + apis.ActivityLogger(app), + }, + }) + if err != nil { + return err + } + return nil + }) + + app.OnBeforeServe().Add(func(e *core.ServeEvent) error { + _, err := e.Router.AddRoute(echo.Route{ + Method: http.MethodDelete, + Path: "/api/events", + Handler: func(c echo.Context) error { + course := c.QueryParam("course") + semester := c.QueryParam("semester") + err := events.DeleteAllEventsByCourseAndSemester(app, course, semester) + if err != nil { + return c.JSON(400, err) + } else { + return c.JSON(200, "Events deleted") + } }, Middlewares: []echo.MiddlewareFunc{ apis.ActivityLogger(app), diff --git a/backend/service/addSchedule.go b/backend/service/addSchedule.go new file mode 100644 index 0000000..4cf41bc --- /dev/null +++ b/backend/service/addSchedule.go @@ -0,0 +1,40 @@ +package service + +import ( + "github.com/pocketbase/pocketbase" + "github.com/pocketbase/pocketbase/core" + "github.com/pocketbase/pocketbase/tools/cron" + "htwkalender/service/events" + "log" +) + +func AddSchedules(app *pocketbase.PocketBase) { + + app.OnBeforeServe().Add(func(e *core.ServeEvent) error { + scheduler := cron.New() + + // Every hour update all courses (5 segments - minute, hour, day, month, weekday) "0 * * * *" + // Every three hours update all courses (5 segments - minute, hour, day, month, weekday) "0 */3 * * *" + // Every 10 minutes update all courses (5 segments - minute, hour, day, month, weekday) "*/10 * * * *" + scheduler.MustAdd("updateCourse", "0 */3 * * *", func() { + + courses := events.GetAllCourses(app) + + for _, course := range courses { + err := events.UpdateModulesForCourse(app, course) + if err != nil { + log.Println("Update Course: " + course + " failed") + log.Println(err) + } else { + log.Println("Update Course: " + course + " successful") + } + } + + }) + + scheduler.Start() + + return nil + }) + +} diff --git a/backend/service/db/dbEvents.go b/backend/service/db/dbEvents.go index 20dc862..3079fbd 100644 --- a/backend/service/db/dbEvents.go +++ b/backend/service/db/dbEvents.go @@ -77,6 +77,8 @@ func findEventByDayWeekStartEndNameCourse(event model.Event, course string, app return &event, err } +// GetPlanForModules returns all events for the given modules with the given course +// used for the ical feed func GetPlanForModules(app *pocketbase.PocketBase, modules []model.FeedCollection) model.Events { // build query functions with name equals elements in modules for dbx query @@ -100,51 +102,50 @@ func GetPlanForModules(app *pocketbase.PocketBase, modules []model.FeedCollectio return events } -func GetAllModulesForCourse(app *pocketbase.PocketBase, course string, semester string) ([]string, error) { - var events []struct { - Name string `db:"Name" json:"Name"` - } - - var eventArray []string +func GetAllModulesForCourse(app *pocketbase.PocketBase, course string, semester string) (model.Events, error) { + var events model.Events // get all events from event records in the events collection - err := app.Dao().DB().Select("Name").From("events").Where(dbx.NewExp("course = {:course} AND semester = {:semester}", dbx.Params{"course": course, "semester": semester})).Distinct(true).All(&events) + err := app.Dao().DB().Select("*").From("events").Where(dbx.NewExp("course = {:course} AND semester = {:semester}", dbx.Params{"course": course, "semester": semester})).GroupBy("Name").Distinct(true).All(&events) if err != nil { print("Error while getting events from database: ", err) - return eventArray, err + return nil, err } - for _, event := range events { - eventArray = append(eventArray, event.Name) - } - return eventArray, nil + return events, nil } -func GetAllModulesDistinct(app *pocketbase.PocketBase) ([]struct { - Name string - Course string -}, error) { - var events []struct { - Name string `db:"Name" json:"Name"` - Course string `db:"course" json:"course"` - } +func GetAllModulesDistinctByNameAndCourse(app *pocketbase.PocketBase) (model.Events, error) { + var events model.Events - var eventArray []struct { - Name string - Course string - } - - err := app.Dao().DB().Select("Name", "course").From("events").Distinct(true).All(&events) + err := app.Dao().DB().Select("*").From("events").GroupBy("Name", "course").Distinct(true).All(&events) if err != nil { print("Error while getting events from database: ", err) - return eventArray, err + return nil, err } - for _, event := range events { - eventArray = append(eventArray, struct { - Name string - Course string - }{event.Name, event.Course}) - } - return eventArray, nil + return events, nil +} + +func DeleteAllEventsForCourse(app *pocketbase.PocketBase, course string, semester string) error { + _, err := app.Dao().DB().Delete("events", dbx.NewExp("course = {:course} AND semester = {:semester}", dbx.Params{"course": course, "semester": semester})).Execute() + + if err != nil { + print("Error while deleting events from database: ", err) + return err + } + + return nil +} + +func FindAllEventsByModule(app *pocketbase.PocketBase, moduleName string) (model.Events, error) { + var events model.Events + + err := app.Dao().DB().Select("*").From("events").Where(dbx.NewExp("Name = {:moduleName}", dbx.Params{"moduleName": moduleName})).All(&events) + if err != nil { + print("Error while getting events from database: ", err) + return nil, err + } + + return events, nil } diff --git a/backend/service/events/courseService.go b/backend/service/events/courseService.go index daf9f09..8388925 100644 --- a/backend/service/events/courseService.go +++ b/backend/service/events/courseService.go @@ -1,12 +1,10 @@ package events import ( - "github.com/labstack/echo/v5" "github.com/pocketbase/pocketbase" "htwkalender/service/db" ) -func GetAllCourses(app *pocketbase.PocketBase, c echo.Context) error { - courses := db.GetAllCourses(app) - return c.JSON(200, courses) +func GetAllCourses(app *pocketbase.PocketBase) []string { + return db.GetAllCourses(app) } diff --git a/backend/service/events/eventService.go b/backend/service/events/eventService.go index b5684f0..450ae43 100644 --- a/backend/service/events/eventService.go +++ b/backend/service/events/eventService.go @@ -3,36 +3,24 @@ package events import ( "github.com/labstack/echo/v5" "github.com/pocketbase/pocketbase" + "github.com/pocketbase/pocketbase/apis" + "htwkalender/model" "htwkalender/service/db" + "htwkalender/service/fetch" "htwkalender/service/functions" ) -func GetModulesForCourseDistinct(app *pocketbase.PocketBase, c echo.Context, course string, semester string) error { +func GetModulesForCourseDistinct(app *pocketbase.PocketBase, course string, semester string) (model.Events, error) { modules, err := db.GetAllModulesForCourse(app, course, semester) - replaceEmptyEntryInStringArray(modules, "Sonderveranstaltungen") - - if err != nil { - return c.JSON(400, err) - } else { - return c.JSON(200, modules) - } + replaceEmptyEntry(modules, "Sonderveranstaltungen") + return modules, err } -func replaceEmptyEntryInStringArray(modules []string, replacement string) { - //replace empty functions with "Sonderveranstaltungen" - for i, module := range modules { - if functions.OnlyWhitespace(module) { - modules[i] = replacement - } - } -} +// replaceEmptyEntry replaces an empty entry in a module with a replacement string +// If the module is not empty, nothing happens +func replaceEmptyEntry(modules model.Events, replacement string) { -func replaceEmptyEntry(modules []struct { - Name string - Course string -}, replacement string) { - //replace empty functions with "Sonderveranstaltungen" for i, module := range modules { if functions.OnlyWhitespace(module.Name) { modules[i].Name = replacement @@ -40,8 +28,10 @@ func replaceEmptyEntry(modules []struct { } } +// GetAllModulesDistinct returns all modules distinct by name and course from the database +// That means you get all modules with duplicates if they have different courses func GetAllModulesDistinct(app *pocketbase.PocketBase, c echo.Context) error { - modules, err := db.GetAllModulesDistinct(app) + modules, err := db.GetAllModulesDistinctByNameAndCourse(app) replaceEmptyEntry(modules, "Sonderveranstaltungen") @@ -51,3 +41,134 @@ func GetAllModulesDistinct(app *pocketbase.PocketBase, c echo.Context) error { return c.JSON(200, modules) } } + +// GetModuleByName returns a module by its name +// If the module does not exist, an error is returned +// If the module exists, the module is returned +// Module is a struct that exists in database as events +func GetModuleByName(app *pocketbase.PocketBase, name string) (model.Module, error) { + events, err := db.FindAllEventsByModule(app, name) + + if err != nil || len(events) == 0 { + return model.Module{}, err + } else { + return model.Module{ + Name: name, + Events: events, + Prof: events[0].Prof, + Course: events[0].Course, + Semester: events[0].Semester, + }, nil + } +} + +// DeleteAllEventsByCourseAndSemester deletes all events for a course and a semester +// If the deletion was successful, nil is returned +// If the deletion was not successful, an error is returned +func DeleteAllEventsByCourseAndSemester(app *pocketbase.PocketBase, course string, semester string) error { + err := db.DeleteAllEventsForCourse(app, course, semester) + if err != nil { + return err + } else { + return nil + } +} + +// UpdateModulesForCourse updates all modules for a course +// Does Updates for ws and ss semester sequentially +// Update runs through the following steps: +// 1. Delete all events for the course and the semester +// 2. Fetch all events for the course and the semester +// 3. Save all events for the course and the semester +// If the update was successful, nil is returned +// If the update was not successful, an error is returned +func UpdateModulesForCourse(app *pocketbase.PocketBase, course string) error { + + //new string array with one element (course) + var courses []string + courses = append(courses, course) + + seminarGroups := fetch.GetSeminarGroupsEventsFromHTML(courses) + + collection, dbError := db.FindCollection(app, "events") + if dbError != nil { + return apis.NewNotFoundError("Collection not found", dbError) + } + + seminarGroups = fetch.ClearEmptySeminarGroups(seminarGroups) + + seminarGroups = fetch.ReplaceEmptyEventNames(seminarGroups) + + //check if events in the seminarGroups Events are already in the database + //if yes, keep the database as it is + //if no, delete all events for the course and the semester and save the new events + //if there are no events in the database, save the new events + + //get all events for the course and the semester + events, err := db.GetAllModulesForCourse(app, course, "ws") + if err != nil { + return apis.NewNotFoundError("Events for winter semester could not be found", err) + } + + // append all events for the course and the semester to the events array for ss + summerEvents, err := db.GetAllModulesForCourse(app, course, "ss") + if err != nil { + return apis.NewNotFoundError("Events for summer semester could not be found", err) + } + + events = append(events, summerEvents...) + + //if there are no events in the database, save the new events + if len(events) == 0 { + _, dbError = db.SaveEvents(seminarGroups, collection, app) + if dbError != nil { + return apis.NewNotFoundError("Events could not be saved", dbError) + } + return nil + } + + //check if events in the seminarGroups Events are already in the database + //if yes, keep the database as it is + //if no, delete all events for the course and the semester and save the new events + for _, seminarGroup := range seminarGroups { + for _, event := range seminarGroup.Events { + // if the event is not in the database, delete all events for the course and the semester and save the new events + if !ContainsEvent(events, event) { + + err = DeleteAllEventsByCourseAndSemester(app, course, "ws") + if err != nil { + return err + } + + err = DeleteAllEventsByCourseAndSemester(app, course, "ss") + if err != nil { + return err + } + + //save the new events + _, dbError = db.SaveEvents(seminarGroups, collection, app) + if dbError != nil { + return apis.NewNotFoundError("Events could not be saved", dbError) + } + return nil + } + } + } + + return nil +} + +func ContainsEvent(events model.Events, event model.Event) bool { + for _, e := range events { + if e.Name == event.Name && + e.Prof == event.Prof && + e.Rooms == event.Rooms && + e.Semester == event.Semester && + e.Start == event.Start && + e.End == event.End && + e.Course == event.Course { + return true + } + } + return false +} diff --git a/backend/service/fetch/fetchSeminarEventService.go b/backend/service/fetch/fetchSeminarEventService.go index 17a6125..24e6baa 100644 --- a/backend/service/fetch/fetchSeminarEventService.go +++ b/backend/service/fetch/fetchSeminarEventService.go @@ -28,7 +28,9 @@ func GetSeminarEvents(c echo.Context, app *pocketbase.PocketBase) error { return apis.NewNotFoundError("Collection not found", dbError) } - seminarGroups = clearEmptySeminarGroups(seminarGroups) + seminarGroups = ClearEmptySeminarGroups(seminarGroups) + + seminarGroups = ReplaceEmptyEventNames(seminarGroups) savedRecords, dbError := db.SaveEvents(seminarGroups, collection, app) @@ -39,7 +41,18 @@ func GetSeminarEvents(c echo.Context, app *pocketbase.PocketBase) error { return c.JSON(http.StatusOK, savedRecords) } -func clearEmptySeminarGroups(seminarGroups []model.SeminarGroup) []model.SeminarGroup { +func ReplaceEmptyEventNames(groups []model.SeminarGroup) []model.SeminarGroup { + for i, group := range groups { + for j, event := range group.Events { + if event.Name == "" { + groups[i].Events[j].Name = "Sonderveranstaltungen" + } + } + } + return groups +} + +func ClearEmptySeminarGroups(seminarGroups []model.SeminarGroup) []model.SeminarGroup { var newSeminarGroups []model.SeminarGroup for _, seminarGroup := range seminarGroups { if len(seminarGroup.Events) > 0 && seminarGroup.Course != "" { diff --git a/backend/service/fetch/fetchSeminarEventService_test.go b/backend/service/fetch/fetchSeminarEventService_test.go index ecbe082..b3d95d4 100644 --- a/backend/service/fetch/fetchSeminarEventService_test.go +++ b/backend/service/fetch/fetchSeminarEventService_test.go @@ -1,6 +1,10 @@ package fetch -import "testing" +import ( + "htwkalender/model" + "reflect" + "testing" +) func Test_extractSemesterAndYear(t *testing.T) { type args struct { @@ -50,3 +54,68 @@ func Test_extractSemesterAndYear(t *testing.T) { }) } } + +func Test_replaceEmptyEventNames(t *testing.T) { + type args struct { + groups []model.SeminarGroup + } + tests := []struct { + name string + args args + want []model.SeminarGroup + }{ + { + name: "Test 1", + args: args{ + groups: []model.SeminarGroup{ + { + Events: []model.Event{ + { + Name: "Test", + }, + }, + }, + }, + }, + want: []model.SeminarGroup{ + { + Events: []model.Event{ + { + Name: "Test", + }, + }, + }, + }, + }, + { + name: "Test 1", + args: args{ + groups: []model.SeminarGroup{ + { + Events: []model.Event{ + { + Name: "", + }, + }, + }, + }, + }, + want: []model.SeminarGroup{ + { + Events: []model.Event{ + { + Name: "Sonderveranstaltungen", + }, + }, + }, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := ReplaceEmptyEventNames(tt.args.groups); !reflect.DeepEqual(got, tt.want) { + t.Errorf("ReplaceEmptyEventNames() = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/backend/service/functions/string.go b/backend/service/functions/string.go index 66bd45c..f89ac44 100644 --- a/backend/service/functions/string.go +++ b/backend/service/functions/string.go @@ -20,3 +20,10 @@ func Contains(s []string, e string) bool { } return false } + +func ReplaceEmptyString(word string, replacement string) string { + if OnlyWhitespace(word) { + return replacement + } + return word +} diff --git a/backend/service/ical/ical.go b/backend/service/ical/ical.go index 17f66f5..a0ad8d4 100644 --- a/backend/service/ical/ical.go +++ b/backend/service/ical/ical.go @@ -9,7 +9,6 @@ import ( "github.com/pocketbase/pocketbase/apis" "htwkalender/model" "htwkalender/service/db" - "io" "net/http" "time" ) @@ -63,18 +62,12 @@ func writeSuccess(message string, w http.ResponseWriter) { } } -func CreateIndividualFeed(c echo.Context, app *pocketbase.PocketBase) error { - - // read json from request body +func CreateIndividualFeed(requestBody []byte, app *pocketbase.PocketBase) (string, error) { var modules []model.FeedCollection - requestBodyBytes, err := io.ReadAll(c.Request().Body) - if err != nil { - return apis.NewApiError(400, "Could not bind request body", err) - } - err = json.Unmarshal(requestBodyBytes, &modules) + err := json.Unmarshal(requestBody, &modules) if err != nil { - return apis.NewApiError(400, "Could not bind request body", err) + return "", apis.NewNotFoundError("Could not parse request body", err) } var feed model.Feed @@ -83,13 +76,13 @@ func CreateIndividualFeed(c echo.Context, app *pocketbase.PocketBase) error { collection, dbError := db.FindCollection(app, "feeds") if dbError != nil { - return apis.NewNotFoundError("Collection not found", dbError) + return "", apis.NewNotFoundError("Collection could not be found", dbError) } record, err := db.SaveFeed(feed, collection, app) if err != nil { - return apis.NewNotFoundError("Feed could not be saved", dbError) + return "", apis.NewNotFoundError("Could not save feed", err) } - return c.JSON(http.StatusOK, record.Id) + return record.Id, nil } diff --git a/backend/service/ical/icalFileGeneration.go b/backend/service/ical/icalFileGeneration.go index 0279bf7..14d64ba 100644 --- a/backend/service/ical/icalFileGeneration.go +++ b/backend/service/ical/icalFileGeneration.go @@ -62,6 +62,9 @@ func generateDescription(event *model.Event) string { if !functions.OnlyWhitespace(event.Course) { description += "Gruppe: " + event.Course + "\n" } + if !functions.OnlyWhitespace(event.EventType) { + description += "Typ: " + event.EventType + "\n" + } return description } diff --git a/frontend/src/api/fetchCourse.ts b/frontend/src/api/fetchCourse.ts index 75bc575..b3d13c7 100644 --- a/frontend/src/api/fetchCourse.ts +++ b/frontend/src/api/fetchCourse.ts @@ -24,8 +24,8 @@ export async function fetchModulesByCourseAndSemester( return response.json(); }) .then((modulesResponse) => { - modulesResponse.forEach((module: string) => - modules.push(new Module(module, course, module)), + modulesResponse.forEach((module: Module) => + modules.push(new Module(module.name, course, module.name)), ); }); return modules; @@ -39,7 +39,7 @@ export async function fetchAllModules(): Promise { }) .then((responseModules: Module[]) => { responseModules.forEach((module: Module) => { - modules.push(new Module(module.Name, module.Course, module.Name)); + modules.push(new Module(module.name, module.course, module.name)); }); }); diff --git a/frontend/src/api/fetchModule.ts b/frontend/src/api/fetchModule.ts new file mode 100644 index 0000000..472046b --- /dev/null +++ b/frontend/src/api/fetchModule.ts @@ -0,0 +1,27 @@ +import { Module } from "../model/module.ts"; + +export async function fetchModule( name: string): Promise { + const request = new Request("/api/module", { + method: "GET", + headers: { + "Content-Type": "application/json", + Name: encodeURI(name), + }, + }); + + return await fetch(request) + .then((response) => { + return response.json(); + }) + .then( + (module: Module) => + new Module( + module.name, + module.course, + module.name, + module.prof, + module.semester, + module.events, + ), + ); +} \ No newline at end of file diff --git a/frontend/src/components/AdditionalModules.vue b/frontend/src/components/AdditionalModules.vue index c9ef74b..f1843a7 100644 --- a/frontend/src/components/AdditionalModules.vue +++ b/frontend/src/components/AdditionalModules.vue @@ -1,11 +1,15 @@ + + diff --git a/frontend/src/components/ModuleSelection.vue b/frontend/src/components/ModuleSelection.vue index ab43ec5..446df5d 100644 --- a/frontend/src/components/ModuleSelection.vue +++ b/frontend/src/components/ModuleSelection.vue @@ -105,7 +105,7 @@ function nextStep() { class="flex flex-column align-items-center sm:align-items-start gap-3" >
- {{ slotProps.data.module.Name }} + {{ slotProps.data.module.name }}
{ return { - Course: module.Course, + Course: module.course, Module: module, } }) @@ -36,14 +36,14 @@ async function finalStep() { diff --git a/frontend/src/main.ts b/frontend/src/main.ts index bbcebbf..cb65e1a 100644 --- a/frontend/src/main.ts +++ b/frontend/src/main.ts @@ -23,6 +23,9 @@ import Accordion from 'primevue/accordion'; import AccordionTab from 'primevue/accordiontab'; import DataTable from "primevue/datatable"; import Column from "primevue/column"; +import DynamicDialog from 'primevue/dynamicdialog'; +import DialogService from 'primevue/dialogservice'; +import ProgressSpinner from 'primevue/progressspinner'; const app = createApp(App); const pinia = createPinia(); @@ -31,6 +34,7 @@ app.use(PrimeVue); app.use(router); app.use(ToastService); app.use(pinia); +app.use(DialogService); app.component("Button", Button); app.component("Menubar", Menubar); app.component("Dropdown", Dropdown); @@ -46,4 +50,6 @@ app.component("Accordion", Accordion); app.component("AccordionTab", AccordionTab); app.component("DataTable", DataTable); app.component("Column", Column); +app.component("DynamicDialog", DynamicDialog); +app.component("ProgressSpinner", ProgressSpinner); app.mount("#app"); diff --git a/frontend/src/model/event.ts b/frontend/src/model/event.ts new file mode 100644 index 0000000..db4196a --- /dev/null +++ b/frontend/src/model/event.ts @@ -0,0 +1,14 @@ + +export class Event { + constructor( + public name: string, + public day: string, + public start: string, + public end: string, + public prof: string, + public week: string, + public eventType: string, + public rooms: string, + public notes: string, + ) {} +} \ No newline at end of file diff --git a/frontend/src/model/module.ts b/frontend/src/model/module.ts index eff8f67..1cb0cd5 100644 --- a/frontend/src/model/module.ts +++ b/frontend/src/model/module.ts @@ -1,7 +1,12 @@ +import { Event } from './event'; + export class Module { constructor( - public Name: string, - public Course: string, - public UserDefinedName: string, + public name: string, + public course: string, + public userDefinedName: string, + public prof: string, + public semester: string, + public events: Event[] = [], ) {} } diff --git a/frontend/src/router/index.ts b/frontend/src/router/index.ts index 34a442d..9a88635 100644 --- a/frontend/src/router/index.ts +++ b/frontend/src/router/index.ts @@ -3,7 +3,7 @@ import Faq from "../components/FaqPage.vue"; import CourseSelection from "../components/CourseSelection.vue"; import AdditionalModules from "../components/AdditionalModules.vue"; import CalendarLink from "../components/CalendarLink.vue"; -import Impress from "../components/Imprint.vue"; +import Imprint from "../components/Imprint.vue"; import PrivacyPolicy from "../components/PrivacyPolicy.vue"; import RenameModules from "../components/RenameModules.vue"; @@ -36,9 +36,9 @@ const router = createRouter({ component: PrivacyPolicy, }, { - path: "/impress", - name: "impress", - component: Impress, + path: "/imprint", + name: "imprint", + component: Imprint, }, { path: "/rename-modules",