diff options
| -rw-r--r-- | backend/admin/handler.go | 64 | ||||
| -rw-r--r-- | backend/admin/templates/game_edit.html | 18 | ||||
| -rw-r--r-- | backend/db/query.sql.go | 25 | ||||
| -rw-r--r-- | backend/query.sql | 8 |
4 files changed, 115 insertions, 0 deletions
diff --git a/backend/admin/handler.go b/backend/admin/handler.go index bce4845..4244788 100644 --- a/backend/admin/handler.go +++ b/backend/admin/handler.go @@ -232,6 +232,35 @@ func (h *Handler) getGameEdit(c echo.Context) error { startedAt = row.StartedAt.Time.In(jst).Format("2006-01-02T15:04") } + mainPlayerRows, err := h.q.ListMainPlayers(c.Request().Context(), []int32{int32(gameID)}) + if err != nil { + if !errors.Is(err, pgx.ErrNoRows) { + return echo.NewHTTPError(http.StatusInternalServerError, err.Error()) + } + } + mainPlayer1 := 0 + if len(mainPlayerRows) > 0 { + mainPlayer1 = int(mainPlayerRows[0].UserID) + } + mainPlayer2 := 0 + if len(mainPlayerRows) > 1 { + mainPlayer2 = int(mainPlayerRows[1].UserID) + } + + userRows, err := h.q.ListUsers(c.Request().Context()) + if err != nil { + if !errors.Is(err, pgx.ErrNoRows) { + return echo.NewHTTPError(http.StatusInternalServerError, err.Error()) + } + } + var users []echo.Map + for _, r := range userRows { + users = append(users, echo.Map{ + "UserID": int(r.UserID), + "Username": r.Username, + }) + } + return c.Render(http.StatusOK, "game_edit", echo.Map{ "BasePath": basePath, "Title": "Game Edit", @@ -243,7 +272,10 @@ func (h *Handler) getGameEdit(c echo.Context) error { "DurationSeconds": row.DurationSeconds, "StartedAt": startedAt, "ProblemID": row.ProblemID, + "MainPlayer1": mainPlayer1, + "MainPlayer2": mainPlayer2, }, + "Users": users, }) } @@ -307,6 +339,38 @@ func (h *Handler) postGameEdit(c echo.Context) error { return echo.NewHTTPError(http.StatusInternalServerError, err.Error()) } + mainPlayers := []int{} + mainPlayer1Raw := c.FormValue("main_player_1") + if mainPlayer1Raw != "" && mainPlayer1Raw != "0" { + mainPlayer1, err := strconv.Atoi(mainPlayer1Raw) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, "Invalid main_player_1") + } + mainPlayers = append(mainPlayers, mainPlayer1) + } + mainPlayer2Raw := c.FormValue("main_player_2") + if mainPlayer2Raw != "" && mainPlayer2Raw != "0" { + mainPlayer2, err := strconv.Atoi(mainPlayer2Raw) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, "Invalid main_player_2") + } + mainPlayers = append(mainPlayers, mainPlayer2) + } + + err = h.q.RemoveAllMainPlayers(c.Request().Context(), int32(gameID)) + if err != nil { + return echo.NewHTTPError(http.StatusInternalServerError, err.Error()) + } + for _, userID := range mainPlayers { + err = h.q.AddMainPlayer(c.Request().Context(), db.AddMainPlayerParams{ + GameID: int32(gameID), + UserID: int32(userID), + }) + if err != nil { + return echo.NewHTTPError(http.StatusInternalServerError, err.Error()) + } + } + return c.Redirect(http.StatusSeeOther, basePath+"/admin/games") } diff --git a/backend/admin/templates/game_edit.html b/backend/admin/templates/game_edit.html index 5ff2ddc..53d647c 100644 --- a/backend/admin/templates/game_edit.html +++ b/backend/admin/templates/game_edit.html @@ -38,6 +38,24 @@ <input type="text" name="problem_id" value="{{ .Game.ProblemID }}"> </div> <div> + <label>Main Player 1</label> + <select name="main_player_1"> + <option value="0"{{ if eq $.Game.MainPlayer1 0 }} selected{{ end }}>none</option> + {{ range .Users }} + <option value="{{ .UserID }}"{{ if eq $.Game.MainPlayer1 .UserID }} selected{{ end }}>{{ .Username }} (uid={{ .UserID }})</option> + {{ end }} + </select> + </div> + <div> + <label>Main Player 2</label> + <select name="main_player_2"> + <option value="0"{{ if eq $.Game.MainPlayer2 0 }} selected{{ end }}>none</option> + {{ range .Users }} + <option value="{{ .UserID }}"{{ if eq $.Game.MainPlayer2 .UserID }} selected{{ end }}>{{ .Username }} (uid={{ .UserID }})</option> + {{ end }} + </select> + </div> + <div> <button type="submit">Save</button> </div> <div> diff --git a/backend/db/query.sql.go b/backend/db/query.sql.go index 75671b6..c7f4fe9 100644 --- a/backend/db/query.sql.go +++ b/backend/db/query.sql.go @@ -11,6 +11,21 @@ import ( "github.com/jackc/pgx/v5/pgtype" ) +const addMainPlayer = `-- name: AddMainPlayer :exec +INSERT INTO game_main_players (game_id, user_id) +VALUES ($1, $2) +` + +type AddMainPlayerParams struct { + GameID int32 + UserID int32 +} + +func (q *Queries) AddMainPlayer(ctx context.Context, arg AddMainPlayerParams) error { + _, err := q.db.Exec(ctx, addMainPlayer, arg.GameID, arg.UserID) + return err +} + const aggregateTestcaseResults = `-- name: AggregateTestcaseResults :one SELECT CASE @@ -604,6 +619,16 @@ func (q *Queries) ListUsers(ctx context.Context) ([]User, error) { return items, nil } +const removeAllMainPlayers = `-- name: RemoveAllMainPlayers :exec +DELETE FROM game_main_players +WHERE game_id = $1 +` + +func (q *Queries) RemoveAllMainPlayers(ctx context.Context, gameID int32) error { + _, err := q.db.Exec(ctx, removeAllMainPlayers, gameID) + return err +} + const syncGameStateBestScoreSubmission = `-- name: SyncGameStateBestScoreSubmission :exec UPDATE game_states SET best_score_submission_id = ( diff --git a/backend/query.sql b/backend/query.sql index e81a11b..61175ab 100644 --- a/backend/query.sql +++ b/backend/query.sql @@ -79,6 +79,14 @@ JOIN users ON game_main_players.user_id = users.user_id WHERE game_main_players.game_id = ANY($1::INT[]) ORDER BY game_main_players.user_id; +-- name: AddMainPlayer :exec +INSERT INTO game_main_players (game_id, user_id) +VALUES ($1, $2); + +-- name: RemoveAllMainPlayers :exec +DELETE FROM game_main_players +WHERE game_id = $1; + -- name: ListTestcasesByGameID :many SELECT * FROM testcases WHERE testcases.problem_id = (SELECT problem_id FROM games WHERE game_id = $1) |
