diff --git a/model/scheduled_break.go b/model/scheduled_break.go index 917c91e7..1344fb16 100644 --- a/model/scheduled_break.go +++ b/model/scheduled_break.go @@ -23,6 +23,14 @@ func (database *Database) CreateScheduledBreak(scheduledBreak *ScheduledBreak) e return database.scheduledBreakTable.create(scheduledBreak) } +func (database *Database) GetScheduledBreakById(id int) (*ScheduledBreak, error) { + return database.scheduledBreakTable.getById(id) +} + +func (database *Database) UpdateScheduledBreak(scheduledBreak *ScheduledBreak) error { + return database.scheduledBreakTable.update(scheduledBreak) +} + func (database *Database) GetScheduledBreaksByMatchType(matchType MatchType) ([]ScheduledBreak, error) { scheduledBreaks, err := database.scheduledBreakTable.getAll() if err != nil { diff --git a/model/scheduled_break_test.go b/model/scheduled_break_test.go index 4094923e..14753991 100644 --- a/model/scheduled_break_test.go +++ b/model/scheduled_break_test.go @@ -20,6 +20,21 @@ func TestScheduledBreakCrud(t *testing.T) { scheduledBreak3 := ScheduledBreak{0, Playoff, 4, time.Unix(500, 0).UTC(), 900, "Awards"} assert.Nil(t, db.CreateScheduledBreak(&scheduledBreak3)) + // Test retrieval by ID. + scheduledBreak, err := db.GetScheduledBreakById(1) + assert.Nil(t, err) + assert.Equal(t, scheduledBreak1, *scheduledBreak) + scheduledBreak, err = db.GetScheduledBreakById(2) + assert.Nil(t, err) + assert.Equal(t, scheduledBreak2, *scheduledBreak) + + // Test update. + scheduledBreak2.Description = "Brunch" + assert.Nil(t, db.UpdateScheduledBreak(&scheduledBreak2)) + scheduledBreak, err = db.GetScheduledBreakById(2) + assert.Nil(t, err) + assert.Equal(t, scheduledBreak2, *scheduledBreak) + // Test retrieval of all blocks by match type. scheduledBreaks, err := db.GetScheduledBreaksByMatchType(Practice) assert.Nil(t, err) @@ -37,7 +52,7 @@ func TestScheduledBreakCrud(t *testing.T) { } // Test individual retrieval by match type and order. - scheduledBreak, err := db.GetScheduledBreakByMatchTypeOrder(Qualification, 25) + scheduledBreak, err = db.GetScheduledBreakByMatchTypeOrder(Qualification, 25) assert.Nil(t, err) assert.Equal(t, scheduledBreak2, *scheduledBreak) scheduledBreak, err = db.GetScheduledBreakByMatchTypeOrder(Playoff, 4) diff --git a/templates/base.html b/templates/base.html index 5a033468..46d867cb 100644 --- a/templates/base.html +++ b/templates/base.html @@ -24,6 +24,7 @@ Awards Lower Thirds Sponsor Slides + Scheduled Breaks Display Configuration Field Testing diff --git a/templates/setup_breaks.html b/templates/setup_breaks.html new file mode 100644 index 00000000..ffc95f99 --- /dev/null +++ b/templates/setup_breaks.html @@ -0,0 +1,42 @@ +{{/* + Copyright 2024 Team 254. All Rights Reserved. + Author: pat@patfairbank.com (Patrick Fairbank) + + UI for configuring scheduled breaks. +*/}} +{{define "title"}}Breaks Configuration{{end}} +{{define "body"}} +
+
+
+ Scheduled Break Configuration + {{if not .ScheduledBreaks}} +

+ Playoff breaks won't appear here until alliance selection is complete and the playoff tournament is created. +

+ {{end}} + {{range $i, $scheduledBreak := .ScheduledBreaks}} +
+
Break #{{add $i 1}}
+ +
+
+ +
+
+ +
+
+ +
+
+
+ {{end}} +
+
+
+{{end}} +{{define "script"}} +{{end}} diff --git a/web/setup_breaks.go b/web/setup_breaks.go new file mode 100644 index 00000000..dac3fa75 --- /dev/null +++ b/web/setup_breaks.go @@ -0,0 +1,60 @@ +// Copyright 2024 Team 254. All Rights Reserved. +// Author: pat@patfairbank.com (Patrick Fairbank) +// +// Web routes for managing scheduled breaks. + +package web + +import ( + "github.com/Team254/cheesy-arena/model" + "net/http" + "strconv" +) + +// Shows the breaks configuration page. +func (web *Web) breaksGetHandler(w http.ResponseWriter, r *http.Request) { + if !web.userIsAdmin(w, r) { + return + } + + template, err := web.parseFiles("templates/setup_breaks.html", "templates/base.html") + if err != nil { + handleWebErr(w, err) + return + } + breaks, err := web.arena.Database.GetScheduledBreaksByMatchType(model.Playoff) + if err != nil { + handleWebErr(w, err) + return + } + data := struct { + *model.EventSettings + ScheduledBreaks []model.ScheduledBreak + }{web.arena.EventSettings, breaks} + err = template.ExecuteTemplate(w, "base", data) + if err != nil { + handleWebErr(w, err) + return + } +} + +// Saves the modified breaks to the database. +func (web *Web) breaksPostHandler(w http.ResponseWriter, r *http.Request) { + if !web.userIsAdmin(w, r) { + return + } + + scheduledBreakId, _ := strconv.Atoi(r.PostFormValue("id")) + scheduledBreak, err := web.arena.Database.GetScheduledBreakById(scheduledBreakId) + if err != nil { + handleWebErr(w, err) + return + } + scheduledBreak.Description = r.PostFormValue("description") + if err = web.arena.Database.UpdateScheduledBreak(scheduledBreak); err != nil { + handleWebErr(w, err) + return + } + + http.Redirect(w, r, "/setup/breaks", 303) +} diff --git a/web/setup_breaks_test.go b/web/setup_breaks_test.go new file mode 100644 index 00000000..0eec7951 --- /dev/null +++ b/web/setup_breaks_test.go @@ -0,0 +1,35 @@ +// Copyright 2024 Team 254. All Rights Reserved. +// Author: pat@patfairbank.com (Patrick Fairbank) + +package web + +import ( + "github.com/Team254/cheesy-arena/model" + "github.com/stretchr/testify/assert" + "testing" + "time" +) + +func TestSetupBreaks(t *testing.T) { + web := setupTestWeb(t) + + web.arena.Database.CreateScheduledBreak( + &model.ScheduledBreak{0, model.Playoff, 4, time.Unix(500, 0).UTC(), 900, "Field Break 1"}, + ) + web.arena.Database.CreateScheduledBreak( + &model.ScheduledBreak{0, model.Playoff, 4, time.Unix(500, 0).UTC(), 900, "Field Break 2"}, + ) + + recorder := web.getHttpResponse("/setup/breaks") + assert.Equal(t, 200, recorder.Code) + assert.Contains(t, recorder.Body.String(), "Field Break 1") + assert.Contains(t, recorder.Body.String(), "Field Break 2") + + recorder = web.postHttpResponse("/setup/breaks", "id=2&description=Award Break 3") + assert.Equal(t, 303, recorder.Code) + recorder = web.getHttpResponse("/setup/breaks") + assert.Equal(t, 200, recorder.Code) + assert.Contains(t, recorder.Body.String(), "Field Break 1") + assert.NotContains(t, recorder.Body.String(), "Field Break 2") + assert.Contains(t, recorder.Body.String(), "Award Break 3") +} diff --git a/web/web.go b/web/web.go index 38212d7c..a6187ba6 100644 --- a/web/web.go +++ b/web/web.go @@ -194,6 +194,8 @@ func (web *Web) newHandler() http.Handler { mux.HandleFunc("GET /reports/pdf/teams", web.teamsPdfReportHandler) mux.HandleFunc("GET /setup/awards", web.awardsGetHandler) mux.HandleFunc("POST /setup/awards", web.awardsPostHandler) + mux.HandleFunc("GET /setup/breaks", web.breaksGetHandler) + mux.HandleFunc("POST /setup/breaks", web.breaksPostHandler) mux.HandleFunc("POST /setup/db/clear", web.clearDbHandler) mux.HandleFunc("POST /setup/db/restore", web.restoreDbHandler) mux.HandleFunc("GET /setup/db/save", web.saveDbHandler)