chore: add Close Event button + cleanup download tokens on reopen

This commit is contained in:
Claus Lohmar 2026-06-17 12:38:21 +00:00
parent 5aa5523e8b
commit 5e66e849fc
3 changed files with 63 additions and 0 deletions

View file

@ -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
// ---------------------------------------------------------------------------

View file

@ -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.

View file

@ -163,6 +163,19 @@
</div>
{{end}}
<!-- Close (only if open) -->
{{if eq .Event.Status "open"}}
<div style="margin-top: 1.5rem; text-align: center;">
<button class="btn btn-secondary" style="color: #fca5a5; border-color: #7f1d1d;"
hx-post="/events/{{.Event.ID}}/close"
hx-target="body"
hx-push-url="true"
onclick="return confirm('Close this event? You can reopen it later.')">
Close Event
</button>
</div>
{{end}}
<!-- Reopen (only if closed) -->
{{if eq .Event.Status "closed"}}
<div style="margin-top: 2rem; text-align: center;">