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"}}
+
+
+
+
+ {{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}}
+
+ {{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)