From 369f4ebcec71bf340b3b4b63837e961621215828 Mon Sep 17 00:00:00 2001 From: Gonne Date: Wed, 31 Aug 2022 22:49:14 +0200 Subject: [PATCH] =?UTF-8?q?Erstelle=20Maske,=20um=20Sprechstunden=20hinzuz?= =?UTF-8?q?uf=C3=BCgen?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- controllers/addOfficeHourHandlers.go | 174 ++++++++++++++++++++ controllers/baseHandler.go | 16 ++ controllers/{handlers.go => getHandlers.go} | 17 +- controllers/timetable.go | 14 +- dummydatasqlite.sql | 2 +- main.go | 2 +- models/date.go | 1 + models/officeHour.go | 7 +- models/tutor.go | 1 + repositories/officeHour.go | 80 +++++++-- repositories/tutor.go | 18 +- templates/addFailure.html | 10 ++ templates/addMask.html | 49 ++++++ templates/index.html | 14 +- templates/officeHourTable.html | 2 +- 15 files changed, 357 insertions(+), 50 deletions(-) create mode 100644 controllers/addOfficeHourHandlers.go create mode 100644 controllers/baseHandler.go rename controllers/{handlers.go => getHandlers.go} (73%) create mode 100644 templates/addFailure.html create mode 100644 templates/addMask.html diff --git a/controllers/addOfficeHourHandlers.go b/controllers/addOfficeHourHandlers.go new file mode 100644 index 0000000..9cc9ac0 --- /dev/null +++ b/controllers/addOfficeHourHandlers.go @@ -0,0 +1,174 @@ +package controllers + +import ( + "fmt" + "html/template" + "net/http" + "net/mail" + "sprechstundentool/models" + "strconv" + "strings" +) + +type maskData struct { + Courses []models.Course + Rooms []models.Room + MinuteGranularity int + SelectedCourse int + SelectedRoom int + Week int + Day int + Hour int + Minute int + Duration int + Roomname string + Name string + Email string + Info string + Errors []string +} + +func (b *BaseHandler) AddOfficeHourHandler(w http.ResponseWriter, req *http.Request) { + var errors []string + courses, err := b.courseRepo.GetAll() + if err != nil { + errors = append(errors, err.Error()) + } + rooms, err := b.roomRepo.GetAll() + if err != nil { + errors = append(errors, err.Error()) + } + //Parse course + courseid, err := strconv.Atoi(req.FormValue("veranstaltung")) + if err != nil { + errors = append(errors, "Die Veranstaltung muss eine ganze Zahl sein.") + } + course, err := b.courseRepo.FindById(courseid) + if err != nil { + errors = append(errors, "Die Veranstaltung muss existieren.") + } + //Parse room + roomid, err := strconv.Atoi(req.FormValue("raum")) + if err != nil { + errors = append(errors, "Der Raum muss eine ganze Zahl sein.") + } + room, err := b.roomRepo.FindById(roomid) + if err != nil { + errors = append(errors, "Der Raum muss existieren.") + } + //Parse date + week, err := strconv.Atoi(req.FormValue("woche")) + if err != nil { + errors = append(errors, "Die Woche muss eine ganze Zahl sein.") + } + if !(week >= 0 && week <= 2) { + errors = append(errors, "Sprechstunden müssen jede, jede gerade oder jede ungerade Woche stattfinden.") + } + day, err := strconv.Atoi(req.FormValue("tag")) + if err != nil { + errors = append(errors, "Der Tag muss eine ganze Zahl sein.") + } + if !(day >= 0 && day <= 4) { + errors = append(errors, "Sprechstunden müssen von Montag bis Freitag stattfinden.") + } + time := strings.SplitN(req.FormValue("startzeit"), ":", 2) + var hour, minute int + if len(time) != 2 { + errors = append(errors, "Die Zeit muss im Format HH:MM sein.") + } else { + hour, err = strconv.Atoi(time[0]) + if err != nil { + errors = append(errors, "Die Stunde muss eine ganze Zahl sein.") + } + if !(hour >= 8 && hour <= 17) { + errors = append(errors, fmt.Sprintf("Sprechstunden müssen zwischen 08:00 Uhr und 17:%d starten.", 60-models.MinuteGranularity)) + } + minute, err = strconv.Atoi(time[1]) + if err != nil { + errors = append(errors, "Die Minute muss eine ganze Zahl sein.") + } + if !(minute >= 0 && minute <= 60-models.MinuteGranularity && minute%models.MinuteGranularity == 0) { + errors = append(errors, fmt.Sprintf("Sprechstunden dürfen nur alle %d Minuten starten.", models.MinuteGranularity)) + } + } + duration, err := strconv.Atoi(req.FormValue("dauer")) + if err != nil { + errors = append(errors, "Die Dauer muss eine ganze Zahl sein.") + } + if !(duration >= models.MinuteGranularity && duration <= 120 && duration%models.MinuteGranularity == 0) { + errors = append(errors, fmt.Sprintf("Sprechstunden müssen zwischen %d und 120 Minuten lang sein.", models.MinuteGranularity)) + } + + roomname := req.FormValue("raumname") + name := req.FormValue("name") + if name == "" { + errors = append(errors, "Der Name darf nicht leer sein.") + } + email, err := mail.ParseAddress(req.FormValue("email")) + if err != nil { + email = &mail.Address{"", req.FormValue("email")} + errors = append(errors, "Mailaddresse konnte nicht geparst werden.") + } else if !strings.HasSuffix(email.Address, "tu-darmstadt.de") { + errors = append(errors, "Mailaddresse muss auf „tu-darmstadt.de“ enden.") + } + info := req.FormValue("info") + + if len(errors) != 0 { + var data maskData = maskData{ + courses, + rooms, + models.MinuteGranularity, + courseid, + roomid, + week, + day, + hour, + minute, + duration, + roomname, + name, + email.Address, + info, + errors, + } + b.writeAddOfficeHourMask(w, req, data) + } else { + officeHour := models.OfficeHour{0, + models.Tutor{0, name, email.Address}, + models.Date{week, day, hour, minute}, + room, + course, + info, + false, + duration, + } + err := b.officeHourRepo.Add(officeHour) + if err != nil { + w.WriteHeader(http.StatusInternalServerError) + failureTemplate, parseErr := template.ParseFiles("templates/addFailure.html") + if parseErr != nil { + w.Write([]byte(fmt.Sprintf("Template konnte nicht geparst werden : %s", string(err.Error())))) + return + } + failureTemplate.Execute(w, err) + } + http.Redirect(w, req, "/", http.StatusTemporaryRedirect) + } +} + +func (b *BaseHandler) writeAddOfficeHourMask(w http.ResponseWriter, req *http.Request, data maskData) { + tmpl, err := template.ParseFiles("templates/addMask.html") + if err != nil { + w.WriteHeader(http.StatusInternalServerError) + w.Write([]byte(fmt.Sprintf("Template konnte nicht geparst werden : %s", string(err.Error())))) + return + } + if len(data.Errors) != 0 { + w.WriteHeader(http.StatusBadRequest) + } + err = tmpl.Execute(w, data) + if err != nil { + w.Write([]byte(fmt.Sprintf("Template konnte nicht geparst werden : %s", string(err.Error())))) + return + } +} diff --git a/controllers/baseHandler.go b/controllers/baseHandler.go new file mode 100644 index 0000000..2e14d95 --- /dev/null +++ b/controllers/baseHandler.go @@ -0,0 +1,16 @@ +package controllers + +import "sprechstundentool/models" + +// BaseHandler will hold everything that controller needs +type BaseHandler struct { + roomRepo models.RoomRepository + officeHourRepo models.OfficeHourRepository + courseRepo models.CourseRepository + tutorRepo models.TutorRepository +} + +// NewBaseHandler returns a new BaseHandler +func NewBaseHandler(roomRepo models.RoomRepository, officeHourRepo models.OfficeHourRepository, courseRepo models.CourseRepository, tutorRepo models.TutorRepository) *BaseHandler { + return &BaseHandler{roomRepo, officeHourRepo, courseRepo, tutorRepo} +} diff --git a/controllers/handlers.go b/controllers/getHandlers.go similarity index 73% rename from controllers/handlers.go rename to controllers/getHandlers.go index 5e613c8..160fdc7 100644 --- a/controllers/handlers.go +++ b/controllers/getHandlers.go @@ -8,19 +8,6 @@ import ( "strconv" ) -// BaseHandler will hold everything that controller needs -type BaseHandler struct { - roomRepo models.RoomRepository - officeHourRepo models.OfficeHourRepository - courseRepo models.CourseRepository - tutorRepo models.TutorRepository -} - -// NewBaseHandler returns a new BaseHandler -func NewBaseHandler(roomRepo models.RoomRepository, officeHourRepo models.OfficeHourRepository, courseRepo models.CourseRepository, tutorRepo models.TutorRepository) *BaseHandler { - return &BaseHandler{roomRepo, officeHourRepo, courseRepo, tutorRepo} -} - func (b *BaseHandler) RootHandler(w http.ResponseWriter, req *http.Request) { b.writeTimetablePage(w, req, template.HTML("")) } @@ -33,7 +20,7 @@ func (b *BaseHandler) GetByRoomHandler(w http.ResponseWriter, req *http.Request) b.RootHandler(w, req) return } - officeHours, _ := b.officeHourRepo.FindByRoom(room) + officeHours, _ := b.officeHourRepo.FindByRoom(room, true) b.writeTimetablePage(w, req, printTimetable(GetTimetable(officeHours))) } @@ -47,7 +34,7 @@ func (b *BaseHandler) GetByCourseHandler(w http.ResponseWriter, req *http.Reques b.RootHandler(w, req) return } - officeHours, _ := b.officeHourRepo.FindByCourse(course) + officeHours, _ := b.officeHourRepo.FindByCourse(course, true) b.writeTimetablePage(w, req, printTimetable(GetTimetable(officeHours))) } diff --git a/controllers/timetable.go b/controllers/timetable.go index 5a8cb9a..bb044e7 100644 --- a/controllers/timetable.go +++ b/controllers/timetable.go @@ -13,20 +13,20 @@ func GetTimetable(officeHours []models.OfficeHour) (timetable map[models.Date]ma for _, officeHour := range officeHours { var slot int = 0 for minute := 0; minute < officeHour.Duration; minute += models.MinuteGranularity { // find slot id - _, exists := fullTimetable[models.Date{officeHour.Day, officeHour.Hour + (officeHour.Minute+minute)/60, (officeHour.Minute + minute) % 60}] + _, exists := fullTimetable[models.Date{0, officeHour.Day, officeHour.Hour + (officeHour.Minute+minute)/60, (officeHour.Minute + minute) % 60}] if exists { - _, exists := fullTimetable[models.Date{officeHour.Day, officeHour.Hour + (officeHour.Minute+minute)/60, (officeHour.Minute + minute) % 60}][slot] + _, exists := fullTimetable[models.Date{0, officeHour.Day, officeHour.Hour + (officeHour.Minute+minute)/60, (officeHour.Minute + minute) % 60}][slot] if exists { slot += 1 minute = 0 continue } } else { - fullTimetable[models.Date{officeHour.Day, officeHour.Hour + (officeHour.Minute+minute)/60, (officeHour.Minute + minute) % 60}] = make(map[int]models.OfficeHour) + fullTimetable[models.Date{0, officeHour.Day, officeHour.Hour + (officeHour.Minute+minute)/60, (officeHour.Minute + minute) % 60}] = make(map[int]models.OfficeHour) } } for minute := 0; minute < officeHour.Duration; minute += models.MinuteGranularity { // write officeHour id to timetable - fullTimetable[models.Date{officeHour.Day, officeHour.Hour + (officeHour.Minute+minute)/60, (officeHour.Minute + minute) % 60}][slot] = officeHour + fullTimetable[models.Date{0, officeHour.Day, officeHour.Hour + (officeHour.Minute+minute)/60, (officeHour.Minute + minute) % 60}][slot] = officeHour } } slots = []int{1, 1, 1, 1, 1} @@ -61,16 +61,16 @@ func printTimetable(timetable map[models.Date]map[int]models.OfficeHour, slots [ } for day := 0; day < 5; day += 1 { for slot := 0; slot < slots[day]; slot += 1 { - current, currentExists := timetable[models.Date{day, hour, minute}][slot] + current, currentExists := timetable[models.Date{0, day, hour, minute}][slot] if currentExists { // This slot is taken by some office hour var continued bool = false // is this slot occupied by the same office hour the previous minute? var predecessorExists bool var predecessor models.OfficeHour if hour > 0 && minute < models.MinuteGranularity { - predecessor, predecessorExists = timetable[models.Date{day, hour - 1, 60 - models.MinuteGranularity}][slot] + predecessor, predecessorExists = timetable[models.Date{0, day, hour - 1, 60 - models.MinuteGranularity}][slot] } else { - predecessor, predecessorExists = timetable[models.Date{day, hour, minute - models.MinuteGranularity}][slot] + predecessor, predecessorExists = timetable[models.Date{0, day, hour, minute - models.MinuteGranularity}][slot] } if predecessorExists { continued = (predecessor == current) diff --git a/dummydatasqlite.sql b/dummydatasqlite.sql index 802af70..56d24fe 100644 --- a/dummydatasqlite.sql +++ b/dummydatasqlite.sql @@ -1,4 +1,4 @@ INSERT INTO `room` (name, max_occupy) VALUES ('S2 15 345',2),('S2 15 415',1),('S2 15 336',2),('S2 15 444',1),('S2 15 333',1),('S2 14 420',1),('Sonstige',1024); -INSERT INTO `officeHour` VALUES (0,1,1,12,0,1,1,0,'',true,60),(1,1,1,12,15,2,1,0,'',true,60),(2,1,1,12,30,1,2,0,'',true,60); +INSERT INTO `officeHour` (tutor, day, hour, minute, room, course, week, info, active, duration) VALUES (1,1,12,0,1,1,0,'',true,60),(1,1,12,15,2,1,0,'',true,60),(1,1,12,30,1,2,0,'',true,60); INSERT INTO `tutor` (name, email) VALUES ('Dummyname','dummy@example.com'); INSERT INTO `course` (name) VALUES ('Integrationstheorie'),('Analysis II (engl.)'),('Analysis II'),('Mathe II für Informatik'),('Mathe II für Bauwesen'),('Diskrete Optimierung'),('Lineare Algebra II'),('Einführung in die Algebra'),('FGdI I&II'),('Algorithmic Discrete Mathematics'),('Einführung in die Stochastik'),('Mathe II für ET'),('Mathe II für Maschinenbau'),('Mathe IV für Maschinenbau'),('Num Mathe für MB (IV)'),('Höhere Mathematik II'),('Elementare PDE'),('LA für Physik und Lehramt'),('Analysis I'),('Mathe III ET'),('Mathe I für Informatik'),('Complex Analysis'),('Mathe & Statistik für Biologen'),('Mathe I für Maschinenbau'),('Mathe I für Bau'),('Nichtlineare Optimierung'),('Einführung in die Numerische Mathematik'),('Differentialgeometrie'),('Mathe I für ET'),('Mathe III (Bau)'),('W. Theorie'),('Gewöhnliche Differentialgleichungen'),('Geometrie für Lehramt'),('Mathe III MB'),('Statistik I für Humanwissenschaftler'),('Einführung in die Optimierung'),('Algebra'),('Lineare Algebra I'),('Höhere Mathematik 1'),('Darstellende Geometrie'),('Statistik 1 für WI'),('Diskrete Mathematik'),('Linear Algebra I (engl.)'),('Introduction to mathematical logic'),('Statistik I für WI'),('Weihnachtsknobelstraße'),('Numerische Lineare Algebra'),('Mathe IV (ET) / Mathe III (Inf) / Praktische Mathe (MEd)'),('Topologie'),('Linear Algebra II (engl.)'),('Einführung in die Finanzmathematik'),('Einführung in die mathematische Software'),('Mathematische Statistik'),('Algebraische Kurven'),('Analysis I (engl.)'),('Funktionalanalysis'),('Lebensversicherungsmathematik'),('Automaten, Formale Sprachen und Entscheidbarkeit (FGdI)'),('Mathematik für Chemiker'),('Numerik gewöhnlicher Differentialgleichungen'),('Darstellungstheorie'),('Aussagen- und Prädikatenlogik'),('Riemannsche Flächen'),('Mathematische Grundlagen der Quantenmechanik'),('Elementare Zahlentheorie'),('Einführung in die mathematische Modellierung'),('Stochastische Prozesse I'),('Mathematik im Kontext'),('Funktionalanalysis II'),('Mathematik IV (für ET) /Mathematik III (für Inf) /PraktischeMathematik (für M.Ed.Math)'),('Differentialgeometrie fuer VI'),('Probability Theory'),('Mathe für MINT'),('Mathematik als gemeinsame Sprache der Naturwissenschaften'),('Lineare Algebra I für Physiker'),('Manifolds'),('Kurvenschätzung'),('Spieltheorie'),('Einführung in die Programmierung'),('Algebraische Topologie'),('Schadenversicherungsmathematik'),('Partial Differential Equations I'); diff --git a/main.go b/main.go index 30c6721..e47336f 100644 --- a/main.go +++ b/main.go @@ -20,7 +20,7 @@ func main() { http.HandleFunc("/getByRoom", h.GetByRoomHandler) http.HandleFunc("/getByCourse", h.GetByCourseHandler) - + http.HandleFunc("/addOfficeHour", h.AddOfficeHourHandler) http.HandleFunc("/", h.RootHandler) http.ListenAndServe(":8080", nil) diff --git a/models/date.go b/models/date.go index 1b71272..f737735 100644 --- a/models/date.go +++ b/models/date.go @@ -2,6 +2,7 @@ package models type Date struct { + Week int Day int Hour int Minute int diff --git a/models/officeHour.go b/models/officeHour.go index aadf0ce..0c81f94 100644 --- a/models/officeHour.go +++ b/models/officeHour.go @@ -4,7 +4,6 @@ package models type OfficeHour struct { Id int Tutor Tutor - Week int Date Room Room Course Course @@ -15,9 +14,9 @@ type OfficeHour struct { type OfficeHourRepository interface { FindById(id int) (OfficeHour, error) - FindByCourse(course Course) ([]OfficeHour, error) - FindByRoom(room Room) ([]OfficeHour, error) - GetAll() ([]OfficeHour, error) + FindByCourse(course Course, activeOnly bool) ([]OfficeHour, error) + FindByRoom(room Room, activatedOnly bool) ([]OfficeHour, error) + GetAll(activatedOnly bool) ([]OfficeHour, error) Delete(officeHour OfficeHour) error Add(officeHour OfficeHour) error } diff --git a/models/tutor.go b/models/tutor.go index 2a317cd..81fa828 100644 --- a/models/tutor.go +++ b/models/tutor.go @@ -9,6 +9,7 @@ type Tutor struct { type TutorRepository interface { FindByEmail(Email string) ([]Tutor, error) + FindByNameAndEmail(name string, email string) (Tutor, error) FindById(Id int) (Tutor, error) GetAll() ([]Tutor, error) Add(tutor Tutor) error diff --git a/repositories/officeHour.go b/repositories/officeHour.go index 5e142d1..05bd3b4 100644 --- a/repositories/officeHour.go +++ b/repositories/officeHour.go @@ -22,8 +22,14 @@ func NewOfficeHourRepo(db *sql.DB, roomRepo *RoomRepo, tutorRepo *TutorRepo, cou } } -func (r *OfficeHourRepo) GetAll() ([]models.OfficeHour, error) { - rows, err := r.db.Query("SELECT * FROM officeHour") +func (r *OfficeHourRepo) GetAll(activeOnly bool) ([]models.OfficeHour, error) { + var rows *sql.Rows + var err error + if activeOnly { + rows, err = r.db.Query("SELECT * FROM officeHour WHERE active") + } else { + rows, err = r.db.Query("SELECT * FROM officeHour") + } if err != nil { return nil, err } @@ -31,8 +37,14 @@ func (r *OfficeHourRepo) GetAll() ([]models.OfficeHour, error) { return r.getFromRows(rows) } -func (r *OfficeHourRepo) FindByCourse(course models.Course) ([]models.OfficeHour, error) { - rows, err := r.db.Query("SELECT * FROM officeHour WHERE course=?", course.Id) +func (r *OfficeHourRepo) FindByCourse(course models.Course, activeOnly bool) ([]models.OfficeHour, error) { + var rows *sql.Rows + var err error + if activeOnly { + rows, err = r.db.Query("SELECT * FROM officeHour WHERE course=? and active", course.Id) + } else { + rows, err = r.db.Query("SELECT * FROM officeHour WHERE course=?", course.Id) + } if err != nil { return nil, err } @@ -40,8 +52,14 @@ func (r *OfficeHourRepo) FindByCourse(course models.Course) ([]models.OfficeHour return r.getFromRows(rows) } -func (r *OfficeHourRepo) FindByRoom(room models.Room) ([]models.OfficeHour, error) { - rows, err := r.db.Query("SELECT * FROM officeHour WHERE room=?", room.Id) +func (r *OfficeHourRepo) FindByRoom(room models.Room, activeOnly bool) ([]models.OfficeHour, error) { + var rows *sql.Rows + var err error + if activeOnly { + rows, err = r.db.Query("SELECT * FROM officeHour WHERE room=? AND active", room.Id) + } else { + rows, err = r.db.Query("SELECT * FROM officeHour WHERE room=?", room.Id) + } if err != nil { return nil, err } @@ -55,7 +73,43 @@ func (r *OfficeHourRepo) FindById(id int) (models.OfficeHour, error) { } func (r *OfficeHourRepo) Add(officeHour models.OfficeHour) error { - return nil + // Find correct tutor or add if not existent + r.tutorRepo.Add(officeHour.Tutor) + var err error + officeHour.Tutor, err = r.tutorRepo.FindByNameAndEmail(officeHour.Tutor.Name, officeHour.Tutor.Email) + if err != nil { + return err + } + + //Don't add identical officeHours + officeHours, err := r.FindByCourse(officeHour.Course, false) + if err != nil { + return err + } + for _, oldOfficeHour := range officeHours { + if officeHour.Tutor == oldOfficeHour.Tutor && + officeHour.Date == oldOfficeHour.Date && + officeHour.Room == oldOfficeHour.Room && + // officeHour.Course == oldOfficeHour.Course && already filtered above + officeHour.Info == oldOfficeHour.Info && + officeHour.Active == oldOfficeHour.Active && + officeHour.Duration == oldOfficeHour.Duration { + return nil + } + } + + _, err = r.db.Exec("INSERT INTO `officeHour` (tutor, day, hour, minute, room, course, week, info, active, duration) VALUES (?,?,?,?,?,?,?,?,?,?)", + officeHour.Tutor.Id, + officeHour.Date.Day, + officeHour.Date.Hour, + officeHour.Date.Minute, + officeHour.Room.Id, + officeHour.Course.Id, + officeHour.Date.Week, + officeHour.Info, + officeHour.Active, + officeHour.Duration) + return err } func (r *OfficeHourRepo) Delete(officeHour models.OfficeHour) error { @@ -64,13 +118,13 @@ func (r *OfficeHourRepo) Delete(officeHour models.OfficeHour) error { func (r *OfficeHourRepo) getFromRow(row *sql.Row) (models.OfficeHour, error) { var officeHour models.OfficeHour - var day, hour, minute, tutorid int + var week, day, hour, minute, tutorid int var roomName, courseName string - err := row.Scan(&officeHour.Id, &tutorid, &day, &hour, &minute, &roomName, &courseName, &officeHour.Week, &officeHour.Info, &officeHour.Active, &officeHour.Duration) + err := row.Scan(&officeHour.Id, &tutorid, &day, &hour, &minute, &roomName, &courseName, &week, &officeHour.Info, &officeHour.Active, &officeHour.Duration) if err != nil { return models.OfficeHour{}, err } - officeHour.Date = models.Date{day, hour, minute} + officeHour.Date = models.Date{week, day, hour, minute} officeHour.Room, _ = r.roomRepo.FindByName(roomName) officeHour.Tutor, _ = r.tutorRepo.FindById(tutorid) officeHour.Course, _ = r.courseRepo.FindByName(courseName) @@ -81,11 +135,11 @@ func (r *OfficeHourRepo) getFromRows(rows *sql.Rows) ([]models.OfficeHour, error var officeHours []models.OfficeHour for rows.Next() { var officeHour models.OfficeHour - var day, hour, minute, tutorId, roomId, courseId int - if err := rows.Scan(&officeHour.Id, &tutorId, &day, &hour, &minute, &roomId, &courseId, &officeHour.Week, &officeHour.Info, &officeHour.Active, &officeHour.Duration); err != nil { + var week, day, hour, minute, tutorId, roomId, courseId int + if err := rows.Scan(&officeHour.Id, &tutorId, &day, &hour, &minute, &roomId, &courseId, &week, &officeHour.Info, &officeHour.Active, &officeHour.Duration); err != nil { return officeHours, err } - officeHour.Date = models.Date{day, hour, minute} + officeHour.Date = models.Date{week, day, hour, minute} officeHour.Room, _ = r.roomRepo.FindById(roomId) officeHour.Tutor, _ = r.tutorRepo.FindById(tutorId) officeHour.Course, _ = r.courseRepo.FindById(courseId) diff --git a/repositories/tutor.go b/repositories/tutor.go index f78b702..a6bc950 100644 --- a/repositories/tutor.go +++ b/repositories/tutor.go @@ -43,6 +43,15 @@ func (r *TutorRepo) FindById(id int) (models.Tutor, error) { return tutor, nil } +func (r *TutorRepo) FindByNameAndEmail(name string, email string) (models.Tutor, error) { + row := r.db.QueryRow("SELECT * FROM tutor WHERE email=? AND name=?", email, name) + var tutor models.Tutor + if err := row.Scan(&tutor.Id, &tutor.Name, &tutor.Email); err != nil { + return models.Tutor{}, err + } + return tutor, nil +} + func (r *TutorRepo) GetAll() ([]models.Tutor, error) { rows, err := r.db.Query("SELECT * FROM tutor") if err != nil { @@ -64,5 +73,12 @@ func (r *TutorRepo) Save(tutor models.Tutor) error { return nil } func (r *TutorRepo) Add(tutor models.Tutor) error { - return nil + //Don't add identical tutors + _, err := r.FindByNameAndEmail(tutor.Name, tutor.Email) + if err == sql.ErrNoRows { + _, err = r.db.Exec("INSERT INTO `tutor` (name, email) VALUES (?,?);", tutor.Name, tutor.Email) + return err + } + return err + } diff --git a/templates/addFailure.html b/templates/addFailure.html new file mode 100644 index 0000000..6ec9f8b --- /dev/null +++ b/templates/addFailure.html @@ -0,0 +1,10 @@ + + + Sprechstunde anlegen + + + Irgendetwas ist schief gegangen. Bitte sende folgende Daten an sprechstundentool@mathebau.de mit einer Beschreibung, was du tun wolltest. +
+ {{.}} + + \ No newline at end of file diff --git a/templates/addMask.html b/templates/addMask.html new file mode 100644 index 0000000..8efab4e --- /dev/null +++ b/templates/addMask.html @@ -0,0 +1,49 @@ + + + Sprechstunde anlegen + + +

+ {{range .Errors}}{{.}}
{{end}} +

+

+

+ : +
+ : +
+ :
+ :
+ :
+ : +
+ :
+ :
+ : +
+ :
+ +
+

+ Du musst hier eine Email-Adresse angeben, die auf „tu-darmstadt.de“ endet.
+ Außerdem dürfen in Räumen nur begrenzt viele Sprechstunden gleichzeitig stattfinden, nämlich +
+ {{range $room := .Rooms}} +
{{$room.Name}}
{{$room.MaxOccupy}} Sprechstunde{{if gt $room.MaxOccupy 1}}n{{end}}

{{end}} +
+ + \ No newline at end of file diff --git a/templates/index.html b/templates/index.html index 48344c7..f2609b4 100644 --- a/templates/index.html +++ b/templates/index.html @@ -10,18 +10,18 @@ {{range $course := .Courses}} {{end}} - +
- -
- {{.Timetable}} - Technische Fragen an sprechstundentool@mathebau.de - + + + {{.Timetable}} + Technische Fragen an sprechstundentool@mathebau.de + \ No newline at end of file diff --git a/templates/officeHourTable.html b/templates/officeHourTable.html index 6dc6057..72e86ed 100644 --- a/templates/officeHourTable.html +++ b/templates/officeHourTable.html @@ -7,5 +7,5 @@ Donnerstag Freitag -{{.TableBody}} + {{.TableBody}} \ No newline at end of file