diff --git a/internal/api/handler.go b/internal/api/handler.go index 8a3ece9..92d5c96 100644 --- a/internal/api/handler.go +++ b/internal/api/handler.go @@ -123,7 +123,7 @@ func (h Handler) EditGame(c echo.Context) error { return slices.Index(form.Players, i.Name) - slices.Index(form.Players, j.Name) }) - updatedGame, err := h.service.Edit(*game) + updatedGame, err := h.service.EditGame(*game) if err != nil { return err } @@ -144,7 +144,7 @@ func (h Handler) DeleteGame(c echo.Context) error { return err } - err = h.service.Delete(int32(parsedId)) + err = h.service.DeleteGame(int32(parsedId)) if err != nil { c.Logger().Error(err) return err @@ -167,12 +167,107 @@ func (h Handler) AddRound(c echo.Context) error { return err } + round, err := parseRound(*game, c) + round.CreatedAt = time.Now() + if err != nil { + return err + } + + round, err = h.service.AddRound(round) + if err != nil { + return err + } + + game.Rounds = append(game.Rounds, round) + gameDetails := template.GameDetails(*game) + return render(c, http.StatusCreated, gameDetails) +} + +func (h Handler) GetEditRoundForm(c echo.Context) error { + game, err := h.findGame(c.Param("gameid")) + if err != nil { + return err + } + + roundId, err := strconv.Atoi(c.Param("roundid")) + if err != nil { + return err + } + + var round skat.Round + var roundIdx int + for i, r := range game.Rounds { + if r.ID == int32(roundId) { + round = r + roundIdx = i + } + } + + form := components.EditRoundForm(*game, round, roundIdx) + return render(c, http.StatusOK, form) +} + +func (h Handler) EditRound(c echo.Context) error { + game, err := h.findGame(c.Param("gameid")) + if err != nil { + c.Logger().Error(err) + return err + } + + parsedRoundId, err := strconv.Atoi(c.Param("roundid")) + if err != nil { + c.Logger().Error(err) + return err + } + + round, err := parseRound(*game, c) + if err != nil { + c.Logger().Error(err) + return err + } + round.ID = int32(parsedRoundId) + + updatedRound, err := h.service.EditRound(round) + if err != nil { + c.Logger().Error(err) + return err + } + + for i, round := range game.Rounds { + if updatedRound.ID == round.ID { + game.Rounds[i] = updatedRound + break + } + } + + gameDetails := template.GameDetails(*game) + return render(c, http.StatusCreated, gameDetails) +} + +func (h Handler) DeleteRound(c echo.Context) error { + parsedRoundId, err := strconv.Atoi(c.Param("roundid")) + if err != nil { + c.Logger().Error(err) + return err + } + + h.service.DeleteRound(int32(parsedRoundId)) + + game, err := h.findGame(c.Param("gameid")) + if err != nil { + return err + } + + gameDetails := template.GameDetails(*game) + return render(c, http.StatusCreated, gameDetails) +} + +func parseRound(game skat.Game, c echo.Context) (skat.Round, error) { var params map[string]string = make(map[string]string) c.Bind(¶ms) round := skat.Round{} round.GameID = game.ID - round.CreatedAt = time.Now() for _, player := range game.Players { role, exists := params[player.Name] if !exists { @@ -185,16 +280,16 @@ func (h Handler) AddRound(c echo.Context) error { case "opponent": round.Opponents = append(round.Opponents, player.ID) case "dealer": - round.Dealer = &player.ID + dealer := player.ID + round.Dealer = &dealer } } - wonStr, exists := params["won"] if exists { won, err := strconv.ParseBool(wonStr) if err != nil { c.Logger().Error(err) - return err + return skat.Round{}, err } round.Won = won } @@ -204,19 +299,12 @@ func (h Handler) AddRound(c echo.Context) error { gameValue, err := strconv.Atoi(gameValueStr) if err != nil { c.Logger().Error(err) - return err + return skat.Round{}, err } round.Value = int32(gameValue) } - round, err = h.service.AddRound(game.ID, round) - if err != nil { - return err - } - - game.Rounds = append(game.Rounds, round) - gameDetails := template.GameDetails(*game) - return render(c, http.StatusCreated, gameDetails) + return round, nil } func render(ctx echo.Context, status int, t templ.Component) error { diff --git a/internal/skat/service.go b/internal/skat/service.go index 3aceb41..89f9288 100644 --- a/internal/skat/service.go +++ b/internal/skat/service.go @@ -145,7 +145,7 @@ func (s Service) Create(g Game) (Game, error) { return g, nil } -func (s Service) Edit(g Game) (Game, error) { +func (s Service) EditGame(g Game) (Game, error) { tx, err := s.db.Begin() if err != nil { return Game{}, err @@ -184,7 +184,7 @@ func (s Service) Edit(g Game) (Game, error) { return g, nil } -func (s Service) AddRound(gameId int32, round Round) (Round, error) { +func (s Service) AddRound(round Round) (Round, error) { opponents := round.Opponents tx, err := s.db.Begin() @@ -228,7 +228,83 @@ func (s Service) AddRound(gameId int32, round Round) (Round, error) { return round, nil } -func (s Service) Delete(gameId int32) error { +func (s Service) EditRound(round Round) (Round, error) { + tx, err := s.db.Begin() + if err != nil { + return Round{}, err + } + defer tx.Rollback() + + // Delete old opponents + deleteOpponents := table.RoundOpponent.DELETE(). + WHERE(table.RoundOpponent.RoundID.EQ(sqlite.Int32(round.ID))) + _, err = deleteOpponents.Exec(tx) + if err != nil { + return Round{}, err + } + + // Update round + updateRound := table.Round.UPDATE( + table.Round.AllColumns.Except(table.Round.ID), + ).WHERE(table.Round.ID.EQ(sqlite.Int32(round.ID))). + MODEL(round) + _, err = updateRound.Exec(tx) + if err != nil { + return Round{}, err + } + + // Insert new round opponents + roundOpponents := make([]model.RoundOpponent, 0) + for _, opponentId := range round.Opponents { + roundOpponents = append(roundOpponents, model.RoundOpponent{ + RoundID: round.ID, + PlayerID: opponentId, + }) + } + insertOpponents := table.RoundOpponent.INSERT( + table.RoundOpponent.AllColumns, + ).MODELS(roundOpponents) + + _, err = insertOpponents.Exec(tx) + if err != nil { + return Round{}, err + } + + err = tx.Commit() + if err != nil { + return Round{}, err + } + + return round, nil +} + +func (s Service) DeleteRound(roundId int32) error { + tx, err := s.db.Begin() + if err != nil { + return err + } + defer tx.Rollback() + + // Delete opponents + deleteOpponents := table.RoundOpponent.DELETE(). + WHERE(table.RoundOpponent.RoundID.EQ(sqlite.Int32(roundId))) + _, err = deleteOpponents.Exec(tx) + if err != nil { + return err + } + + // Delete round + deleteRound := table.Round.DELETE(). + WHERE(table.Round.ID.EQ(sqlite.Int32(roundId))) + _, err = deleteRound.Exec(tx) + if err != nil { + return err + } + + return tx.Commit() +} + +func (s Service) DeleteGame(gameId int32) error { tx, err := s.db.Begin() if err != nil { return err diff --git a/main.go b/main.go index edce60e..2215331 100644 --- a/main.go +++ b/main.go @@ -49,8 +49,11 @@ func registerRoutes(e *echo.Echo, handler api.Handler) { e.PUT("/games/:id/edit", handler.EditGame) e.DELETE("/games/:id", handler.DeleteGame) - e.POST("/games/:id/rounds", handler.AddRound) + e.POST("/games/:id/rounds", handler.AddRound) + e.GET("/games/:gameid/rounds/:roundid", handler.GetEditRoundForm) + e.PUT("/games/:gameid/rounds/:roundid", handler.EditRound) + e.DELETE("/games/:gameid/rounds/:roundid", handler.DeleteRound) } func createTables(db *sql.DB) error { _, err := db.Exec(` diff --git a/templates/components/create_game_form.templ b/templates/components/create_game_form.templ index 1cab628..42b5cbd 100644 --- a/templates/components/create_game_form.templ +++ b/templates/components/create_game_form.templ @@ -1,7 +1,7 @@ package components templ CreateGameForm() { -
+

Create Game

diff --git a/templates/components/create_game_form_templ.go b/templates/components/create_game_form_templ.go index 006fbe7..ca7dc3e 100644 --- a/templates/components/create_game_form_templ.go +++ b/templates/components/create_game_form_templ.go @@ -23,7 +23,7 @@ func CreateGameForm() templ.Component { templ_7745c5c3_Var1 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("

") + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("

") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/templates/components/edit_game_form.templ b/templates/components/edit_game_form.templ index b20dbe6..d8cf4cd 100644 --- a/templates/components/edit_game_form.templ +++ b/templates/components/edit_game_form.templ @@ -4,9 +4,9 @@ import "github.com/tarow/skat-counter/internal/skat" import "fmt" templ EditGameForm(g skat.Game) { - +
-

Create Game

+

Edit Game

@@ -25,7 +25,7 @@ templ EditGameForm(g skat.Game) { 3
-
+
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -194,22 +219,22 @@ func AddRoundForm(game skat.Game) templ.Component { defer templ.ReleaseBuffer(templ_7745c5c3_Buffer) } ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var13 := templ.GetChildren(ctx) - if templ_7745c5c3_Var13 == nil { - templ_7745c5c3_Var13 = templ.NopComponent + templ_7745c5c3_Var14 := templ.GetChildren(ctx) + if templ_7745c5c3_Var14 == nil { + templ_7745c5c3_Var14 = templ.NopComponent } ctx = templ.ClearChildren(ctx) _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("

") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Var14 := `Round ` - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var14) + templ_7745c5c3_Var15 := `Round ` + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var15) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - var templ_7745c5c3_Var15 string = fmt.Sprintf("%v", len(game.Rounds)+1) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var15)) + var templ_7745c5c3_Var16 string = fmt.Sprintf("%v", len(game.Rounds)+1) + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var16)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -222,8 +247,8 @@ func AddRoundForm(game skat.Game) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - var templ_7745c5c3_Var16 string = player.Name - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var16)) + var templ_7745c5c3_Var17 string = player.Name + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var17)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -239,8 +264,8 @@ func AddRoundForm(game skat.Game) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Var17 := `-` - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var17) + templ_7745c5c3_Var18 := `-` + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var18) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -248,8 +273,8 @@ func AddRoundForm(game skat.Game) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Var18 := `Declarer` - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var18) + templ_7745c5c3_Var19 := `Declarer` + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var19) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -257,8 +282,8 @@ func AddRoundForm(game skat.Game) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Var19 := `Opponent` - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var19) + templ_7745c5c3_Var20 := `Opponent` + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var20) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -266,8 +291,8 @@ func AddRoundForm(game skat.Game) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Var20 := `Dealer` - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var20) + templ_7745c5c3_Var21 := `Dealer` + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var21) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -280,17 +305,17 @@ func AddRoundForm(game skat.Game) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Var21 := `Game Value` - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var21) + templ_7745c5c3_Var22 := `Game Value` + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var22) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("