feat: gift completion

This commit is contained in:
Teajey 2024-05-07 22:29:23 +12:00
parent 3890c93928
commit 73e64f096d
Signed by: Teajey
GPG Key ID: 970E790FE834A713
4 changed files with 85 additions and 30 deletions

View File

@ -46,20 +46,42 @@ func (ctx *Context) WishlistDelete(w http.ResponseWriter, r *http.Request) {
http.Redirect(w, r, "/", http.StatusSeeOther) http.Redirect(w, r, "/", http.StatusSeeOther)
} }
func (ctx *Context) UpdateClaim(w http.ResponseWriter, r *http.Request) { func (ctx *Context) updateClaims(w http.ResponseWriter, r *http.Request) {
user := ctx.Auth.ExpectUser(r) user := ctx.Auth.ExpectUser(r)
if err := r.ParseForm(); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
userReference := r.PathValue("userReference") userReference := r.PathValue("userReference")
claims := r.Form["claim"] claims := r.Form["unclaimed"]
unclaims := r.Form["unclaim"] unclaims := r.Form["claimed"]
err := user.ClaimGifts(claims, unclaims) err := user.ClaimGifts(claims, unclaims)
println("err?", err)
if err != nil { if err != nil {
http.Error(w, "Failed to update claim...", http.StatusInternalServerError) http.Error(w, "Failed to update claim...", http.StatusInternalServerError)
return return
} }
http.Redirect(w, r, "/"+userReference, http.StatusSeeOther) http.Redirect(w, r, "/"+userReference, http.StatusSeeOther)
} }
func (ctx *Context) completeGifts(w http.ResponseWriter, r *http.Request) {
user := ctx.Auth.ExpectUser(r)
userReference := r.PathValue("userReference")
claims := r.Form["claimed"]
err := user.CompleteGifts(claims)
if err != nil {
http.Error(w, "Failed to complete gifts...", http.StatusInternalServerError)
return
}
http.Redirect(w, r, "/"+userReference, http.StatusSeeOther)
}
func (ctx *Context) UpdateForeignWishlist(w http.ResponseWriter, r *http.Request) {
if err := r.ParseForm(); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
switch r.Form.Get("mode") {
case "claim":
ctx.updateClaims(w, r)
case "complete":
ctx.completeGifts(w, r)
default:
http.Error(w, "Invalid mode", http.StatusBadRequest)
}
}

View File

@ -18,6 +18,7 @@ type Gift struct {
Name string Name string
ClaimantId string ClaimantId string
ClaimantName string ClaimantName string
Sent bool
} }
func queryForUser(query string, args ...any) (*User, error) { func queryForUser(query string, args ...any) (*User, error) {
@ -80,7 +81,7 @@ func (u *User) GetPassHash() ([]byte, error) {
} }
func (u *User) GetGifts() ([]Gift, error) { func (u *User) GetGifts() ([]Gift, error) {
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" stmt := "SELECT gift.id, gift.name, claimant.id, claimant.name, gift.sent 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) rows, err := database.Query(stmt, u.Id)
if err != nil { if err != nil {
return nil, err return nil, err
@ -92,12 +93,14 @@ func (u *User) GetGifts() ([]Gift, error) {
var name string var name string
var claimantId string var claimantId string
var claimantName string var claimantName string
rows.Scan(&id, &name, &claimantId, &claimantName) var sent bool
rows.Scan(&id, &name, &claimantId, &claimantName, &sent)
gift := Gift{ gift := Gift{
Id: id, Id: id,
Name: name, Name: name,
ClaimantId: claimantId, ClaimantId: claimantId,
ClaimantName: claimantName, ClaimantName: claimantName,
Sent: sent,
} }
gifts = append(gifts, gift) gifts = append(gifts, gift)
} }
@ -134,7 +137,6 @@ func (u *User) executeClaims(tx *sql.Tx, claims, unclaims []string) error {
claimStmt := "UPDATE gift SET claimant_id = ? WHERE id = ?" claimStmt := "UPDATE gift SET claimant_id = ? WHERE id = ?"
unclaimStmt := "UPDATE gift SET claimant_id = NULL WHERE id = ?" unclaimStmt := "UPDATE gift SET claimant_id = NULL WHERE id = ?"
for _, id := range claims { for _, id := range claims {
println("exec claim:", claimStmt, u.Id, id)
_, err := tx.Exec(claimStmt, u.Id, id) _, err := tx.Exec(claimStmt, u.Id, id)
if err != nil { if err != nil {
return err return err
@ -164,3 +166,30 @@ func (u *User) ClaimGifts(claims, unclaims []string) error {
err = tx.Commit() err = tx.Commit()
return err return err
} }
func (u *User) executeCompletions(tx *sql.Tx, claims []string) error {
claimStmt := "UPDATE gift SET sent = 1 WHERE id = ?"
for _, id := range claims {
_, err := tx.Exec(claimStmt, id)
if err != nil {
return err
}
}
return nil
}
func (u *User) CompleteGifts(claims []string) error {
tx, err := database.Begin()
if err != nil {
return err
}
err = u.executeCompletions(tx, claims)
if err != nil {
err = tx.Rollback()
return err
}
err = tx.Commit()
return err
}

View File

@ -36,7 +36,7 @@ func main() {
protectedMux.HandleFunc("GET /", ctx.Home) protectedMux.HandleFunc("GET /", ctx.Home)
protectedMux.HandleFunc("GET /{userReference}", ctx.ViewForeignWishlist) protectedMux.HandleFunc("GET /{userReference}", ctx.ViewForeignWishlist)
protectedMux.HandleFunc("POST /{userReference}/update_claim", ctx.UpdateClaim) protectedMux.HandleFunc("POST /{userReference}/update", ctx.UpdateForeignWishlist)
protectedMux.HandleFunc("POST /wishlist/add", ctx.WishlistAdd) protectedMux.HandleFunc("POST /wishlist/add", ctx.WishlistAdd)
protectedMux.HandleFunc("POST /wishlist/delete", ctx.WishlistDelete) protectedMux.HandleFunc("POST /wishlist/delete", ctx.WishlistDelete)
protectedMux.HandleFunc("POST /logout", authMiddleware.LogoutPost) protectedMux.HandleFunc("POST /logout", authMiddleware.LogoutPost)

View File

@ -8,31 +8,35 @@
</ul> </ul>
</nav> </nav>
<h2>{{.Username}}'s list</h2> <h2>{{.Username}}'s list</h2>
<form method="post" action="/{{.UserReference}}/update_claim" autocomplete="off"> <form method="post" action="/{{.UserReference}}/update" autocomplete="off">
<input type="submit" value="Update"> <button type="submit" name="mode" value="claim">Claim/Unclaim</button>
<button type="submit" name="mode" value="complete">Complete</button>
<ul> <ul>
{{range .Gifts}} {{range .Gifts}}
<li> <li>
{{if eq .ClaimantId $.CurrentUserId}}
<label> <label>
<input type="checkbox" name="unclaim" value="{{.Id}}"> {{if .ClaimantId}}
{{.Name}} {{if eq .ClaimantId $.CurrentUserId}}
</label> <input type="checkbox" name="claimed" value="{{.Id}}" {{if .Sent}}disabled{{end}}>
<span style="color: blue;">Claimed by you</span>
{{else}}
{{if .ClaimantId}}
<label>
<input type="checkbox" disabled>
{{.Name}}
</label>
<span style="color: red;">Claimed by {{.ClaimantName}}</span>
{{else}} {{else}}
<label> <input type="checkbox" disabled>
<input type="checkbox" name="claim" value="{{.Id}}"> {{end}}
{{.Name}} {{else}}
</label> <input type="checkbox" name="unclaimed" value="{{.Id}}" {{if .Sent}}disabled{{end}}>
{{end}}
{{if .Sent}}
<s>{{.Name}}</s>
{{else}}
{{.Name}}
{{end}}
{{if .ClaimantId}}
{{if eq .ClaimantId $.CurrentUserId}}
<span style="color: blue;">{{if .Sent}}Completed{{else}}Claimed{{end}} by you</span>
{{else}}
<span style="color: red;">{{if .Sent}}Completed{{else}}Claimed{{end}} by {{.ClaimantName}}</span>
{{end}} {{end}}
{{end}} {{end}}
</label>
</li> </li>
{{end}} {{end}}
</ul> </ul>