feat: todo list
This commit is contained in:
parent
583e5d6beb
commit
8dc6d3363b
|
|
@ -42,42 +42,32 @@ func (ctx *Context) WishlistDelete(w http.ResponseWriter, r *http.Request) {
|
|||
http.Redirect(w, r, "/", http.StatusSeeOther)
|
||||
}
|
||||
|
||||
func (ctx *Context) updateClaims(w http.ResponseWriter, r *http.Request) {
|
||||
user := ctx.Auth.ExpectUser(r)
|
||||
userReference := r.PathValue("userReference")
|
||||
claims := r.Form["unclaimed"]
|
||||
unclaims := r.Form["claimed"]
|
||||
err := user.ClaimGifts(claims, unclaims)
|
||||
if err != nil {
|
||||
http.Error(w, "Failed to update claim...", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
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) {
|
||||
user := ctx.Auth.ExpectUser(r)
|
||||
if err := r.ParseForm(); err != nil {
|
||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
userReference := r.PathValue("userReference")
|
||||
switch r.Form.Get("mode") {
|
||||
case "claim":
|
||||
ctx.updateClaims(w, r)
|
||||
claims := r.Form["unclaimed"]
|
||||
unclaims := r.Form["claimed"]
|
||||
err := user.ClaimGifts(claims, unclaims)
|
||||
if err != nil {
|
||||
http.Error(w, "Failed to update claim...", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
case "complete":
|
||||
ctx.completeGifts(w, r)
|
||||
claims := r.Form["claimed"]
|
||||
err := user.CompleteGifts(claims)
|
||||
if err != nil {
|
||||
log.Printf("Failed to complete gifts: %s\n", err)
|
||||
http.Error(w, "Failed to complete gifts...", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
default:
|
||||
http.Error(w, "Invalid mode", http.StatusBadRequest)
|
||||
}
|
||||
http.Redirect(w, r, "/"+userReference, http.StatusSeeOther)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import (
|
|||
type HomeProps struct {
|
||||
Username string
|
||||
Gifts []db.Gift
|
||||
Todo []db.Gift
|
||||
Reference string
|
||||
}
|
||||
|
||||
|
|
@ -20,6 +21,11 @@ func (ctx *Context) Home(w http.ResponseWriter, r *http.Request) {
|
|||
http.Error(w, "An error occurred while fetching your wishlist :(", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
p := HomeProps{Username: user.Name, Gifts: gifts, Reference: user.Reference}
|
||||
todo, err := user.GetTodo()
|
||||
if err != nil {
|
||||
http.Error(w, "An error occurred while fetching your wishlist :(", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
p := HomeProps{Username: user.Name, Gifts: gifts, Todo: todo, Reference: user.Reference}
|
||||
templates.Execute(w, "home.gotmpl", p)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,34 @@
|
|||
package context
|
||||
|
||||
import (
|
||||
"log"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func (ctx *Context) TodoUpdate(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
|
||||
}
|
||||
switch r.Form.Get("mode") {
|
||||
case "unclaim":
|
||||
unclaims := r.Form["gift"]
|
||||
err := user.ClaimGifts([]string{}, unclaims)
|
||||
if err != nil {
|
||||
http.Error(w, "Failed to update claim...", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
case "complete":
|
||||
claims := r.Form["gift"]
|
||||
err := user.CompleteGifts(claims)
|
||||
if err != nil {
|
||||
log.Printf("Failed to complete gifts: %s\n", err)
|
||||
http.Error(w, "Failed to complete gifts...", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
default:
|
||||
http.Error(w, "Invalid mode", http.StatusBadRequest)
|
||||
}
|
||||
http.Redirect(w, r, "/", http.StatusSeeOther)
|
||||
}
|
||||
43
db/user.go
43
db/user.go
|
|
@ -14,11 +14,13 @@ type User struct {
|
|||
}
|
||||
|
||||
type Gift struct {
|
||||
Id string
|
||||
Name string
|
||||
ClaimantId string
|
||||
ClaimantName string
|
||||
Sent bool
|
||||
Id string
|
||||
Name string
|
||||
ClaimantId string
|
||||
ClaimantName string
|
||||
Sent bool
|
||||
RecipientName string
|
||||
RecipientRef string
|
||||
}
|
||||
|
||||
func queryForUser(query string, args ...any) (*User, error) {
|
||||
|
|
@ -111,6 +113,37 @@ func (u *User) GetGifts() ([]Gift, error) {
|
|||
return gifts, nil
|
||||
}
|
||||
|
||||
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, gift.name DESC"
|
||||
rows, err := database.Query(stmt, u.Id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
gifts := []Gift{}
|
||||
for rows.Next() {
|
||||
var id string
|
||||
var name string
|
||||
var sent bool
|
||||
var recipientName string
|
||||
var recipientRef string
|
||||
rows.Scan(&id, &name, &sent, &recipientName, &recipientRef)
|
||||
gift := Gift{
|
||||
Id: id,
|
||||
Name: name,
|
||||
Sent: sent,
|
||||
RecipientName: recipientName,
|
||||
RecipientRef: recipientRef,
|
||||
}
|
||||
gifts = append(gifts, gift)
|
||||
}
|
||||
err = rows.Err()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return gifts, nil
|
||||
}
|
||||
|
||||
func (u *User) AddGift(name string) error {
|
||||
stmt := "INSERT INTO gift (name, recipient_id, creator_id) VALUES (?, ?, ?)"
|
||||
_, err := database.Exec(stmt, name, u.Id, u.Id)
|
||||
|
|
|
|||
1
main.go
1
main.go
|
|
@ -39,6 +39,7 @@ func main() {
|
|||
protectedMux.HandleFunc("POST /{userReference}/update", ctx.UpdateForeignWishlist)
|
||||
protectedMux.HandleFunc("POST /wishlist/add", ctx.WishlistAdd)
|
||||
protectedMux.HandleFunc("POST /wishlist/delete", ctx.WishlistDelete)
|
||||
protectedMux.HandleFunc("POST /todo/update", ctx.TodoUpdate)
|
||||
protectedMux.HandleFunc("POST /logout", authMiddleware.LogoutPost)
|
||||
|
||||
http.Handle("/", authMiddleware)
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
<pre>{{.Reference}}</pre>
|
||||
</dd>
|
||||
</dl>
|
||||
<h2>Your list</h2>
|
||||
<h2>Your wishlist</h2>
|
||||
<form method="post" action="/wishlist/delete" onchange="acceptNames(this, 'deleteSubmit', 'gift')" autocomplete="off">
|
||||
<button id="deleteSubmit" type="submit" name="mode" value="delete" disabled>Delete</button>
|
||||
<ul>
|
||||
|
|
@ -26,6 +26,32 @@
|
|||
</form>
|
||||
<form method="post" action="/wishlist/add">
|
||||
<input name="gift_name" required>
|
||||
<input type="submit">
|
||||
<button type="submit">Add gift idea</button>
|
||||
</form>
|
||||
<h2>Your todo list</h2>
|
||||
<form method="post" action="/todo/update"
|
||||
onchange="acceptNames(this, 'unclaimSubmit', 'gift'); acceptNames(this, 'completeSubmit', 'gift')" autocomplete="off">
|
||||
<button id="unclaimSubmit" type="submit" name="mode" value="unclaim" disabled>Unclaim</button>
|
||||
<button id="completeSubmit" type="submit" name="mode" value="complete" disabled>Complete</button>
|
||||
<ul>
|
||||
{{range .Todo}}
|
||||
<li>
|
||||
<label>
|
||||
{{if .Sent}}
|
||||
<input type="checkbox" disabled>
|
||||
{{else}}
|
||||
<input type="checkbox" name="gift" value="{{.Id}}">
|
||||
{{end}}
|
||||
<em>
|
||||
{{if .Sent}}
|
||||
<s>{{.Name}}</s>
|
||||
{{else}}
|
||||
{{.Name}}
|
||||
{{end}}
|
||||
</em> for <a href="/{{.RecipientRef}}">{{.RecipientName}}</a>
|
||||
</label>
|
||||
</li>
|
||||
{{end}}
|
||||
</ul>
|
||||
</form>
|
||||
{{end}}
|
||||
Loading…
Reference in New Issue