diff --git a/internal/handlers/events.go b/internal/handlers/events.go index 0603f21..c53d2fa 100644 --- a/internal/handlers/events.go +++ b/internal/handlers/events.go @@ -10,6 +10,8 @@ import ( "html/template" "log" "net/http" + "os" + "path/filepath" "strconv" "time" @@ -182,11 +184,58 @@ func (h *EventHandler) ReopenEvent(w http.ResponseWriter, r *http.Request) { return } + // Clean up any stale download packages — user must regenerate after reopening. + if oldFiles, err := database.DeleteDownloadTokensByEvent(h.DB, eventID); err == nil { + for _, fn := range oldFiles { + os.Remove(filepath.Join("storage", "postbox", fn)) + } + } + // Redirect to dashboard so the full page renders with updated status. w.Header().Set("HX-Redirect", "/dashboard") w.WriteHeader(http.StatusOK) } +// --------------------------------------------------------------------------- +// POST /events/{id}/close — CloseEvent +// --------------------------------------------------------------------------- + +// CloseEvent sets an event's status to "closed". Only the event owner may +// close it. On success, redirects to the dashboard. +func (h *EventHandler) CloseEvent(w http.ResponseWriter, r *http.Request) { + eventID := chi.URLParam(r, "id") + if eventID == "" { + http.Error(w, "Missing event ID", http.StatusBadRequest) + return + } + + userID := getUserID(r) + if userID == "" { + http.Error(w, "Unauthorized", http.StatusUnauthorized) + return + } + + event, err := database.GetEventByID(h.DB, eventID) + if err != nil || event == nil { + http.Error(w, "Event not found", http.StatusNotFound) + return + } + if event.UserID != userID { + http.Error(w, "Forbidden", http.StatusForbidden) + return + } + + if err := database.UpdateEventStatus(h.DB, eventID, "closed"); err != nil { + log.Printf("ERROR [%s] handlers: CloseEvent: UpdateEventStatus(%s): %v", + time.Now().Format(time.RFC3339), eventID, err) + http.Error(w, "Failed to close event", http.StatusInternalServerError) + return + } + + w.Header().Set("HX-Redirect", "/dashboard") + w.WriteHeader(http.StatusOK) +} + // --------------------------------------------------------------------------- // GET /events/{id}/expenses — ViewEventExpenses // --------------------------------------------------------------------------- diff --git a/main.go b/main.go index 2fec95c..c8f9de0 100644 --- a/main.go +++ b/main.go @@ -218,6 +218,7 @@ func main() { r.Get("/events/{id}/edit", eventHandler.EditEvent) r.Delete("/events/{id}", eventHandler.DeleteEvent) r.Put("/events/{id}/reopen", eventHandler.ReopenEvent) + r.Post("/events/{id}/close", eventHandler.CloseEvent) r.Get("/events/{id}/expenses", eventHandler.ViewEventExpenses) // Expenses. diff --git a/templates/event_expenses.html b/templates/event_expenses.html index 18afb36..47143cb 100644 --- a/templates/event_expenses.html +++ b/templates/event_expenses.html @@ -163,6 +163,19 @@ {{end}} + + {{if eq .Event.Status "open"}} +