Compare commits

..

No commits in common. "b38e707ae2ff23b5da1911864d29239cc28f418b" and "ffb27bfd932566d342862385f207d05f55961400" have entirely different histories.

6 changed files with 44 additions and 152 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("intent") { switch r.Form.Get("mode") {
case "claim": case "claim":
claims := r.Form["unclaimed"] claims := r.Form["unclaimed"]
unclaims := r.Form["claimed"] unclaims := r.Form["claimed"]
@ -66,30 +66,8 @@ 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
}
case "delete":
claims := r.Form["unclaimed"]
unclaims := r.Form["claimed"]
gifts := append(claims, unclaims...)
err := user.RemoveGifts(gifts...)
if err != nil {
log.Printf("Failed to remove gift idea for other user: %s\n", err)
http.Error(w, "Failed to remove gift idea for other user...", http.StatusInternalServerError)
return
}
default: default:
http.Error(w, "Invalid intent", http.StatusBadRequest) http.Error(w, "Invalid mode", 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 := user.GetOtherUserGifts(userReference) gifts, err := otherUser.GetGifts()
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,11 +19,8 @@ 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) {
@ -86,7 +83,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 gift.creator_id = user.id AND 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 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
@ -96,18 +93,15 @@ 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 sql.NullString var claimantId string
var claimantName sql.NullString var claimantName string
var sent bool var sent bool
err = rows.Scan(&id, &name, &claimantId, &claimantName, &sent) 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.String, ClaimantId: claimantId,
ClaimantName: claimantName.String, ClaimantName: claimantName,
Sent: sent, Sent: sent,
} }
gifts = append(gifts, gift) gifts = append(gifts, gift)
@ -119,53 +113,6 @@ 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)
@ -342,16 +289,3 @@ 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

@ -28,12 +28,6 @@
const accepted = submissionNames.length > 0 && submissionNames.every((name) => acceptedNames.includes(name)); const accepted = submissionNames.length > 0 && submissionNames.every((name) => acceptedNames.includes(name));
submitter.disabled = !accepted; submitter.disabled = !accepted;
} }
function acceptAttribute(form, submitId, acceptedAttribute) {
const checkedInputs = Array.from(form.querySelectorAll("input")).filter((i) => i.checked);
const submitter = document.getElementById(submitId);
const accepted = checkedInputs.length > 0 && checkedInputs.every((i) => i.hasAttribute(acceptedAttribute));
submitter.disabled = !accepted;
}
</script> </script>
</head> </head>

View File

@ -33,63 +33,49 @@
<h2>{{.Username}}'s list</h2> <h2>{{.Username}}'s list</h2>
{{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'); acceptAttribute(this, 'deleteSubmit', 'data-deletable')"> onchange="acceptNames(this, 'claimSubmit', 'claimed', 'unclaimed'); acceptNames(this, 'completeSubmit', 'claimed');">
<ul class="list-group mb-3"> <button id="claimSubmit" class="btn btn-warning" type="submit" name="mode" value="claim"
disabled>Claim/Unclaim</button>
<button id="completeSubmit" class="btn btn-success" type="submit" name="mode" value="complete"
disabled>Complete</button>
<ul class="list-group mt-3">
{{range .}} {{range .}}
{{$isMine := eq .ClaimantId $.CurrentUserId}}
{{$createdByMe := eq .CreatorId $.CurrentUserId}}
{{$outsideIdea := ne .RecipientId .CreatorId}}
<li class="list-group-item{{if .Sent}} list-group-item-light{{end}}"> <li class="list-group-item{{if .Sent}} list-group-item-light{{end}}">
{{if .ClaimantId}}
{{if eq .ClaimantId $.CurrentUserId}}
<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}}" {{if $isMine}} name="claimed" value="{{.Id}}" {{else if aria-describedby="wish_detail_{{.Id}}" name="claimed" value="{{.Id}}" {{if .Sent}}disabled{{end}}>
.ClaimantId}} disabled {{else}} name="unclaimed" value="{{.Id}}" {{end}} {{if .Sent}} disabled {{end}} {{else}}
{{if $createdByMe}}data-deletable{{end}}> <input id="foreignlist_select_{{.Id}}" class="form-check-input" type="checkbox"
aria-describedby="wish_detail_{{.Id}}" disabled>
<label class="form-check-label stretched-link" for="foreignlist_select_{{.Id}}"> {{end}}
{{else}}
<input id="foreignlist_select_{{.Id}}" class="form-check-input" type="checkbox"
aria-describedby="wish_detail_{{.Id}}" name="unclaimed" value="{{.Id}}" {{if .Sent}}disabled{{end}}>
{{end}}
<label class="form-check-label" for="foreignlist_select_{{.Id}}">
{{if .Sent}} {{if .Sent}}
<s>{{.Name}}</s> <s>{{.Name}}</s>
{{else}} {{else}}
{{.Name}} {{.Name}}
{{end}} {{end}}
</label> </label>
{{if or .ClaimantId $outsideIdea}}
<div class="d-inline" id="wish_detail_{{.Id}}">
{{if .ClaimantId}} {{if .ClaimantId}}
<span style="color: {{if $isMine}}blue{{else}}red{{end}};">{{if .Sent}}Completed{{else}}Claimed{{end}} {{if eq .ClaimantId $.CurrentUserId}}
by <span id="wish_detail_{{.Id}}" style="color: blue;">{{if .Sent}}Completed{{else}}Claimed{{end}} by
{{if $isMine}}<em>you</em>{{else}}{{.ClaimantName}}{{end}}</span> you</span>
{{else}}
<span id="wish_detail_{{.Id}}" style="color: red;">{{if .Sent}}Completed{{else}}Claimed{{end}} by
{{.ClaimantName}}</span>
{{end}} {{end}}
{{if $outsideIdea}}
<span style="color: green;">Added by {{if
$createdByMe}}<em>you</em>{{else}}{{.CreatorName}}{{end}}</span>
{{end}}
</div>
{{end}} {{end}}
</li> </li>
{{end}} {{end}}
</ul> </ul>
<button id="claimSubmit" class="btn btn-warning" type="submit" name="intent" value="claim"
disabled>Claim/Unclaim</button>
<button id="completeSubmit" class="btn btn-success" type="submit" name="intent" value="complete"
disabled>Complete</button>
<button id="deleteSubmit" class="btn btn-danger" type="submit" name="intent" value="delete"
disabled>Delete</button>
</form> </form>
{{else}} {{else}}
<p>They don't have any gift ideas. Ask them to think of something, or add an idea yourself! 👇 (everyone <p>They haven't wished for anything. Ask them to think of some stuff!</p>
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>

View File

@ -30,6 +30,8 @@
{{with .Gifts}} {{with .Gifts}}
<form method="post" action="/wishlist/delete" onchange="acceptNames(this, 'deleteSubmit', 'gift')" <form method="post" action="/wishlist/delete" onchange="acceptNames(this, 'deleteSubmit', 'gift')"
autocomplete="off"> autocomplete="off">
<button id="deleteSubmit" class="btn btn-danger mb-3" type="submit" name="mode" value="delete"
disabled>Delete</button>
<ul class="list-group mb-3"> <ul class="list-group mb-3">
{{range .}} {{range .}}
<li class="list-group-item"> <li class="list-group-item">
@ -40,8 +42,6 @@
</li> </li>
{{end}} {{end}}
</ul> </ul>
<button id="deleteSubmit" class="btn btn-danger mb-3" type="submit" name="mode" value="delete"
disabled>Delete</button>
</form> </form>
{{else}} {{else}}
<p>Your list is empty. Think of some things to add!</p> <p>Your list is empty. Think of some things to add!</p>
@ -62,7 +62,11 @@
<form method="post" action="/todo/update" <form method="post" action="/todo/update"
onchange="acceptNames(this, 'unclaimSubmit', 'gift'); acceptNames(this, 'completeSubmit', 'gift')" onchange="acceptNames(this, 'unclaimSubmit', 'gift'); acceptNames(this, 'completeSubmit', 'gift')"
autocomplete="off"> autocomplete="off">
<ul class="list-group mb-3"> <button id="unclaimSubmit" class="btn btn-warning" type="submit" name="mode" value="unclaim"
disabled>Unclaim</button>
<button id="completeSubmit" class="btn btn-success" type="submit" name="mode" value="complete"
disabled>Complete</button>
<ul class="list-group mt-3">
{{range .}} {{range .}}
<li class="list-group-item{{if .Sent}} list-group-item-light{{end}}"> <li class="list-group-item{{if .Sent}} list-group-item-light{{end}}">
<input id="todo_select_{{.Id}}" class="form-check-input" type="checkbox" {{if .Sent}} <input id="todo_select_{{.Id}}" class="form-check-input" type="checkbox" {{if .Sent}}
@ -82,10 +86,6 @@
</li> </li>
{{end}} {{end}}
</ul> </ul>
<button id="unclaimSubmit" class="btn btn-warning" type="submit" name="mode" value="unclaim"
disabled>Unclaim</button>
<button id="completeSubmit" class="btn btn-success" type="submit" name="mode" value="complete"
disabled>Complete</button>
</form> </form>
</div> </div>
</section> </section>