feat: add gifts to other's wishlists

This commit is contained in:
Teajey 2024-05-23 14:07:37 +12:00
parent ffb27bfd93
commit 7d46722053
Signed by: Teajey
GPG Key ID: 970E790FE834A713
4 changed files with 119 additions and 21 deletions

View File

@ -49,7 +49,7 @@ func (ctx *Context) UpdateForeignWishlist(w http.ResponseWriter, r *http.Request
return return
} }
userReference := r.PathValue("userReference") userReference := r.PathValue("userReference")
switch r.Form.Get("mode") { switch r.Form.Get("intent") {
case "claim": case "claim":
claims := r.Form["unclaimed"] claims := r.Form["unclaimed"]
unclaims := r.Form["claimed"] unclaims := r.Form["claimed"]
@ -66,8 +66,20 @@ func (ctx *Context) UpdateForeignWishlist(w http.ResponseWriter, r *http.Request
http.Error(w, "Failed to complete gifts...", http.StatusInternalServerError) http.Error(w, "Failed to complete gifts...", http.StatusInternalServerError)
return return
} }
case "add":
giftName := r.Form.Get("gift_name")
if giftName == "" {
http.Error(w, "Gift name not provided", http.StatusBadRequest)
return
}
err := user.AddGiftToUser(userReference, giftName)
if err != nil {
log.Printf("Failed to add gift idea to other user: %s\n", err)
http.Error(w, "Failed to add gift idea to other user...", http.StatusInternalServerError)
return
}
default: default:
http.Error(w, "Invalid mode", http.StatusBadRequest) http.Error(w, "Invalid intent", http.StatusBadRequest)
} }
http.Redirect(w, r, "/"+userReference, http.StatusSeeOther) http.Redirect(w, r, "/"+userReference, http.StatusSeeOther)
} }

View File

@ -32,7 +32,7 @@ func (ctx *Context) ViewForeignWishlist(w http.ResponseWriter, r *http.Request)
http.Error(w, "User not found", http.StatusNotFound) http.Error(w, "User not found", http.StatusNotFound)
return return
} }
gifts, err := otherUser.GetGifts() gifts, err := user.GetOtherUserGifts(userReference)
if err != nil { if err != nil {
log.Printf("An error occurred while fetching %s's wishlist: %s\n", otherUser.Name, err) 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) http.Error(w, "An error occurred while fetching this user's wishlist :(", http.StatusInternalServerError)

View File

@ -19,8 +19,11 @@ type Gift struct {
ClaimantId string ClaimantId string
ClaimantName string ClaimantName string
Sent bool Sent bool
RecipientId string
RecipientName string RecipientName string
RecipientRef string RecipientRef string
CreatorId string
CreatorName string
} }
func queryForUser(query string, args ...any) (*User, error) { func queryForUser(query string, args ...any) (*User, error) {
@ -83,7 +86,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, 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 = ?" 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 gift.creator_id = user.id AND user.id = ?"
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
@ -93,15 +96,18 @@ func (u *User) GetGifts() ([]Gift, error) {
for rows.Next() { for rows.Next() {
var id string var id string
var name string var name string
var claimantId string var claimantId sql.NullString
var claimantName string var claimantName sql.NullString
var sent bool var sent bool
rows.Scan(&id, &name, &claimantId, &claimantName, &sent) err = rows.Scan(&id, &name, &claimantId, &claimantName, &sent)
if err != nil {
return nil, err
}
gift := Gift{ gift := Gift{
Id: id, Id: id,
Name: name, Name: name,
ClaimantId: claimantId, ClaimantId: claimantId.String,
ClaimantName: claimantName, ClaimantName: claimantName.String,
Sent: sent, Sent: sent,
} }
gifts = append(gifts, gift) gifts = append(gifts, gift)
@ -113,6 +119,53 @@ func (u *User) GetGifts() ([]Gift, error) {
return gifts, nil return gifts, nil
} }
func (u *User) GetOtherUserGifts(otherUserReference string) ([]Gift, error) {
otherUser, err := GetUserByReference(otherUserReference)
if err != nil {
return nil, err
}
if otherUser.Id == u.Id {
return nil, fmt.Errorf("Not allowed to view own foreign wishlist")
}
stmt := "SELECT gift.id, gift.name, claimant.id, claimant.name, gift.sent, gift.creator_id, creator.name, gift.recipient_id FROM gift JOIN user ON gift.recipient_id = user.id LEFT JOIN user AS claimant ON gift.claimant_id = claimant.id LEFT JOIN user AS creator ON gift.creator_id = creator.id WHERE user.id = ?"
rows, err := database.Query(stmt, otherUser.Id)
if err != nil {
return nil, err
}
defer rows.Close()
gifts := []Gift{}
for rows.Next() {
var id string
var name string
var claimantId sql.NullString
var claimantName sql.NullString
var sent bool
var creatorId string
var creatorName string
var recipientId string
err = rows.Scan(&id, &name, &claimantId, &claimantName, &sent, &creatorId, &creatorName, &recipientId)
if err != nil {
return nil, err
}
gift := Gift{
Id: id,
Name: name,
ClaimantId: claimantId.String,
ClaimantName: claimantName.String,
Sent: sent,
CreatorId: creatorId,
CreatorName: creatorName,
RecipientId: recipientId,
}
gifts = append(gifts, gift)
}
err = rows.Err()
if err != nil {
return nil, err
}
return gifts, nil
}
func (u *User) GetTodo() ([]Gift, error) { func (u *User) GetTodo() ([]Gift, error) {
stmt := "SELECT gift.id, gift.name, gift.sent, recipient.name, recipient.reference FROM gift JOIN user ON gift.claimant_id = user.id JOIN user AS recipient ON gift.recipient_id = recipient.id WHERE user.id = ? ORDER BY gift.sent ASC, gift.name" stmt := "SELECT gift.id, gift.name, gift.sent, recipient.name, recipient.reference FROM gift JOIN user ON gift.claimant_id = user.id JOIN user AS recipient ON gift.recipient_id = recipient.id WHERE user.id = ? ORDER BY gift.sent ASC, gift.name"
rows, err := database.Query(stmt, u.Id) rows, err := database.Query(stmt, u.Id)
@ -289,3 +342,16 @@ func (u *User) CompleteGifts(claims []string) error {
err = tx.Commit() err = tx.Commit()
return err return err
} }
func (u *User) AddGiftToUser(otherUserReference string, giftName string) error {
otherUser, err := GetUserByReference(otherUserReference)
if err != nil {
return err
}
stmt := "INSERT INTO gift (name, recipient_id, creator_id) VALUES (?, ?, ?)"
_, err = database.Exec(stmt, giftName, otherUser.Id, u.Id)
if err != nil {
return err
}
return nil
}

View File

@ -34,9 +34,9 @@
{{with .Gifts}} {{with .Gifts}}
<form method="post" action="/{{$.UserReference}}/update" autocomplete="off" <form method="post" action="/{{$.UserReference}}/update" autocomplete="off"
onchange="acceptNames(this, 'claimSubmit', 'claimed', 'unclaimed'); acceptNames(this, 'completeSubmit', 'claimed');"> onchange="acceptNames(this, 'claimSubmit', 'claimed', 'unclaimed'); acceptNames(this, 'completeSubmit', 'claimed');">
<button id="claimSubmit" class="btn btn-warning" type="submit" name="mode" value="claim" <button id="claimSubmit" class="btn btn-warning" type="submit" name="intent" value="claim"
disabled>Claim/Unclaim</button> disabled>Claim/Unclaim</button>
<button id="completeSubmit" class="btn btn-success" type="submit" name="mode" value="complete" <button id="completeSubmit" class="btn btn-success" type="submit" name="intent" value="complete"
disabled>Complete</button> disabled>Complete</button>
<ul class="list-group mt-3"> <ul class="list-group mt-3">
{{range .}} {{range .}}
@ -53,29 +53,49 @@
<input id="foreignlist_select_{{.Id}}" class="form-check-input" type="checkbox" <input id="foreignlist_select_{{.Id}}" class="form-check-input" type="checkbox"
aria-describedby="wish_detail_{{.Id}}" name="unclaimed" value="{{.Id}}" {{if .Sent}}disabled{{end}}> aria-describedby="wish_detail_{{.Id}}" name="unclaimed" value="{{.Id}}" {{if .Sent}}disabled{{end}}>
{{end}} {{end}}
<label class="form-check-label" for="foreignlist_select_{{.Id}}"> <label class="form-check-label stretched-link" for="foreignlist_select_{{.Id}}">
{{if .Sent}} {{if .Sent}}
<s>{{.Name}}</s> <s>{{.Name}}</s>
{{else}} {{else}}
{{.Name}} {{.Name}}
{{end}} {{end}}
</label> </label>
{{if .ClaimantId}} {{if or .ClaimantId (ne .RecipientId .CreatorId)}}
{{if eq .ClaimantId $.CurrentUserId}} <div class="d-inline" id="wish_detail_{{.Id}}">
<span id="wish_detail_{{.Id}}" style="color: blue;">{{if .Sent}}Completed{{else}}Claimed{{end}} by {{if .ClaimantId}}
you</span> {{if eq .ClaimantId $.CurrentUserId}}
{{else}} <span style="color: blue;">{{if .Sent}}Completed{{else}}Claimed{{end}} by
<span id="wish_detail_{{.Id}}" style="color: red;">{{if .Sent}}Completed{{else}}Claimed{{end}} by <em>you</em></span>
{{.ClaimantName}}</span> {{else}}
{{end}} <span style="color: red;">{{if .Sent}}Completed{{else}}Claimed{{end}} by
{{.ClaimantName}}</span>
{{end}}
{{end}}
{{if ne .RecipientId .CreatorId}}
{{if eq .CreatorId $.CurrentUserId}}
<span style="color: green;">Added by <em>you</em></span>
{{else}}
<span style="color: green;">Added by {{.CreatorName}}</span>
{{end}}
{{end}}
</div>
{{end}} {{end}}
</li> </li>
{{end}} {{end}}
</ul> </ul>
</form> </form>
{{else}} {{else}}
<p>They haven't wished for anything. Ask them to think of some stuff!</p> <p>They don't have any gift ideas. Ask them to think of something, or add an idea yourself! 👇 (everyone
except them will be able to see it and claim it)</p>
{{end}} {{end}}
<form method="post" action="/{{$.UserReference}}/update">
<div class="input-group mt-3">
<input class="form-control" name="gift_name"
placeholder="This will be invisible to {{.Username}}, but everyone else will be able to see it and possibly claim it."
required>
<button class="btn btn-primary" type="submit" name="intent" value="add">Add gift idea</button>
</div>
</form>
</div> </div>
</section> </section>
</div> </div>