package handler import ( "net/http" "spend-sparrow/handler/middleware" "spend-sparrow/service" t "spend-sparrow/template/transaction" "spend-sparrow/types" "spend-sparrow/utils" "github.com/a-h/templ" ) type Transaction interface { Handle(router *http.ServeMux) } type TransactionImpl struct { s service.Transaction account service.Account treasureChest service.TreasureChest a service.Auth r *Render } func NewTransaction(s service.Transaction, account service.Account, treasureChest service.TreasureChest, a service.Auth, r *Render) Transaction { return TransactionImpl{ s: s, account: account, treasureChest: treasureChest, a: a, r: r, } } func (h TransactionImpl) Handle(r *http.ServeMux) { r.Handle("GET /transaction", h.handleTransactionPage()) r.Handle("GET /transaction/{id}", h.handleTransactionItemComp()) r.Handle("POST /transaction/{id}", h.handleUpdateTransaction()) r.Handle("POST /transaction/recalculate", h.handleRecalculate()) r.Handle("DELETE /transaction/{id}", h.handleDeleteTransaction()) } func (h TransactionImpl) handleRecalculate() http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { user := middleware.GetUser(r) if user == nil { utils.DoRedirect(w, r, "/auth/signin") return } err := h.s.RecalculateBalances(user) if err != nil { handleError(w, r, err) return } } } func (h TransactionImpl) handleTransactionPage() http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { user := middleware.GetUser(r) if user == nil { utils.DoRedirect(w, r, "/auth/signin") return } transactions, err := h.s.GetAll(user) if err != nil { handleError(w, r, err) return } accounts, err := h.account.GetAll(user) if err != nil { handleError(w, r, err) return } treasureChests, err := h.treasureChest.GetAll(user) if err != nil { handleError(w, r, err) return } comp := t.Transaction(transactions, accounts, treasureChests) h.r.RenderLayout(r, w, comp, user) } } func (h TransactionImpl) handleTransactionItemComp() http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { user := middleware.GetUser(r) if user == nil { utils.DoRedirect(w, r, "/auth/signin") return } accounts, err := h.account.GetAll(user) if err != nil { handleError(w, r, err) return } treasureChests, err := h.treasureChest.GetAll(user) if err != nil { handleError(w, r, err) return } id := r.PathValue("id") if id == "new" { comp := t.EditTransaction(nil, accounts, treasureChests) h.r.Render(r, w, comp) return } transaction, err := h.s.Get(user, id) if err != nil { handleError(w, r, err) return } var comp templ.Component if r.URL.Query().Get("edit") == "true" { comp = t.EditTransaction(transaction, accounts, treasureChests) } else { comp = t.TransactionItem(transaction) } h.r.Render(r, w, comp) } } func (h TransactionImpl) handleUpdateTransaction() http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { user := middleware.GetUser(r) if user == nil { utils.DoRedirect(w, r, "/auth/signin") return } var ( transaction *types.Transaction err error ) input := types.TransactionInput{ Id: r.PathValue("id"), AccountId: r.FormValue("account-id"), TreasureChestId: r.FormValue("treasure-chest-id"), Value: r.FormValue("value"), Timestamp: r.FormValue("timestamp"), TimezoneOffsetMinutes: r.FormValue("timezone-offset"), Note: r.FormValue("note"), } if input.Id == "new" { transaction, err = h.s.Add(user, input) if err != nil { handleError(w, r, err) return } } else { transaction, err = h.s.Update(user, input) if err != nil { handleError(w, r, err) return } } comp := t.TransactionItem(transaction) h.r.Render(r, w, comp) } } func (h TransactionImpl) handleDeleteTransaction() http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { user := middleware.GetUser(r) if user == nil { utils.DoRedirect(w, r, "/auth/signin") return } id := r.PathValue("id") err := h.s.Delete(user, id) if err != nil { handleError(w, r, err) return } } }