From 3890c939289c9b2d4c5f8c784b0496a1c3a78640 Mon Sep 17 00:00:00 2001 From: Teajey <21069848+Teajey@users.noreply.github.com> Date: Tue, 7 May 2024 21:29:07 +1200 Subject: [PATCH] feat: claimable gifts --- context/context.go | 18 +++++++++++ context/foreign_wishlist.go | 9 ++++-- db/user.go | 53 +++++++++++++++++++++++++++---- main.go | 1 + templates/foreign_wishlist.gotmpl | 34 +++++++++++++++++--- 5 files changed, 101 insertions(+), 14 deletions(-) diff --git a/context/context.go b/context/context.go index ff31d78..79a0c56 100644 --- a/context/context.go +++ b/context/context.go @@ -45,3 +45,21 @@ func (ctx *Context) WishlistDelete(w http.ResponseWriter, r *http.Request) { } http.Redirect(w, r, "/", http.StatusSeeOther) } + +func (ctx *Context) UpdateClaim(w http.ResponseWriter, r *http.Request) { + user := ctx.Auth.ExpectUser(r) + if err := r.ParseForm(); err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + userReference := r.PathValue("userReference") + claims := r.Form["claim"] + unclaims := r.Form["unclaim"] + err := user.ClaimGifts(claims, unclaims) + println("err?", err) + if err != nil { + http.Error(w, "Failed to update claim...", http.StatusInternalServerError) + return + } + http.Redirect(w, r, "/"+userReference, http.StatusSeeOther) +} diff --git a/context/foreign_wishlist.go b/context/foreign_wishlist.go index 604911a..fd1e31f 100644 --- a/context/foreign_wishlist.go +++ b/context/foreign_wishlist.go @@ -8,8 +8,10 @@ import ( ) type ForeignWishlistProps struct { - Username string - Gifts []db.Gift + CurrentUserId string + Username string + UserReference string + Gifts []db.Gift } func (ctx *Context) ViewForeignWishlist(w http.ResponseWriter, r *http.Request) { @@ -31,9 +33,10 @@ func (ctx *Context) ViewForeignWishlist(w http.ResponseWriter, r *http.Request) } gifts, err := otherUser.GetGifts() if err != nil { + log.Printf("An error occurred while fetching %s's wishlist: %s\n", otherUser.Name, err) http.Error(w, "An error occurred while fetching this user's wishlist :(", http.StatusInternalServerError) return } - p := ForeignWishlistProps{Username: otherUser.Name, Gifts: gifts} + p := ForeignWishlistProps{CurrentUserId: user.Id, Username: otherUser.Name, UserReference: userReference, Gifts: gifts} templates.Execute(w, "foreign_wishlist.gotmpl", p) } diff --git a/db/user.go b/db/user.go index cd9b0aa..48c27f2 100644 --- a/db/user.go +++ b/db/user.go @@ -14,8 +14,10 @@ type User struct { } type Gift struct { - Id string - Name string + Id string + Name string + ClaimantId string + ClaimantName string } func queryForUser(query string, args ...any) (*User, error) { @@ -78,7 +80,7 @@ func (u *User) GetPassHash() ([]byte, error) { } func (u *User) GetGifts() ([]Gift, error) { - stmt := "SELECT gift.id, gift.name FROM gift JOIN user ON gift.recipient_id = user.id WHERE user.id = ?" + stmt := "SELECT gift.id, gift.name, claimant.id, claimant.name FROM gift JOIN user ON gift.recipient_id = user.id LEFT JOIN user AS claimant ON gift.claimant_id = claimant.id WHERE user.id = ? ORDER BY gift.name DESC" rows, err := database.Query(stmt, u.Id) if err != nil { return nil, err @@ -88,10 +90,14 @@ func (u *User) GetGifts() ([]Gift, error) { for rows.Next() { var id string var name string - rows.Scan(&id, &name) + var claimantId string + var claimantName string + rows.Scan(&id, &name, &claimantId, &claimantName) gift := Gift{ - Id: id, - Name: name, + Id: id, + Name: name, + ClaimantId: claimantId, + ClaimantName: claimantName, } gifts = append(gifts, gift) } @@ -123,3 +129,38 @@ func (u *User) RemoveGift(id string) error { } return nil } + +func (u *User) executeClaims(tx *sql.Tx, claims, unclaims []string) error { + claimStmt := "UPDATE gift SET claimant_id = ? WHERE id = ?" + unclaimStmt := "UPDATE gift SET claimant_id = NULL WHERE id = ?" + for _, id := range claims { + println("exec claim:", claimStmt, u.Id, id) + _, err := tx.Exec(claimStmt, u.Id, id) + if err != nil { + return err + } + } + for _, id := range unclaims { + _, err := tx.Exec(unclaimStmt, id) + if err != nil { + return err + } + } + return nil +} + +func (u *User) ClaimGifts(claims, unclaims []string) error { + tx, err := database.Begin() + if err != nil { + return err + } + + err = u.executeClaims(tx, claims, unclaims) + if err != nil { + err = tx.Rollback() + return err + } + + err = tx.Commit() + return err +} diff --git a/main.go b/main.go index e28f842..18a2e28 100644 --- a/main.go +++ b/main.go @@ -36,6 +36,7 @@ func main() { protectedMux.HandleFunc("GET /", ctx.Home) protectedMux.HandleFunc("GET /{userReference}", ctx.ViewForeignWishlist) + protectedMux.HandleFunc("POST /{userReference}/update_claim", ctx.UpdateClaim) protectedMux.HandleFunc("POST /wishlist/add", ctx.WishlistAdd) protectedMux.HandleFunc("POST /wishlist/delete", ctx.WishlistDelete) protectedMux.HandleFunc("POST /logout", authMiddleware.LogoutPost) diff --git a/templates/foreign_wishlist.gotmpl b/templates/foreign_wishlist.gotmpl index c30ba96..d1ff8e8 100644 --- a/templates/foreign_wishlist.gotmpl +++ b/templates/foreign_wishlist.gotmpl @@ -8,9 +8,33 @@