feat: add sort/filter component for watchlist

- create reusable SortFilter templ component with sort options (date, title, score)
- integrate sort/filter into watchlist page with query params
- add sortEntries method to handle client-side sorting
- add CSS styling for sort filter controls
- pass sort params through status tab and view toggle links
This commit is contained in:
2026-04-06 23:28:36 +02:00
parent 4d42ce1587
commit 8687f93f31
7 changed files with 378 additions and 71 deletions

View File

@@ -125,6 +125,15 @@ func (h *Handler) HandleGetWatchlist(w http.ResponseWriter, r *http.Request) {
}
statusFilter := r.URL.Query().Get("status")
sortBy := r.URL.Query().Get("sort")
sortOrder := r.URL.Query().Get("order")
if sortBy != "title" && sortBy != "score" {
sortBy = "date"
}
if sortOrder != "asc" {
sortOrder = "desc"
}
user, ok := r.Context().Value(middleware.UserContextKey).(*database.User)
if !ok || user == nil {
@@ -150,7 +159,10 @@ func (h *Handler) HandleGetWatchlist(w http.ResponseWriter, r *http.Request) {
filteredEntries = entries
}
templates.Watchlist(filteredEntries, layout, statusFilter).Render(r.Context(), w)
// Sort entries
h.sortEntries(filteredEntries, sortBy, sortOrder)
templates.Watchlist(filteredEntries, layout, statusFilter, sortBy, sortOrder).Render(r.Context(), w)
}
func (h *Handler) HandleExportWatchlist(w http.ResponseWriter, r *http.Request) {
@@ -214,3 +226,40 @@ func (h *Handler) HandleImportWatchlist(w http.ResponseWriter, r *http.Request)
w.Header().Set("HX-Redirect", "/watchlist")
w.WriteHeader(http.StatusOK)
}
func (h *Handler) sortEntries(entries []database.GetUserWatchListRow, sortBy, sortOrder string) {
var less func(int, int) bool
switch sortBy {
case "title":
less = func(i, j int) bool {
cmp := entries[i].TitleOriginal < entries[j].TitleOriginal
if sortOrder == "asc" {
return cmp
}
return !cmp
}
case "score":
less = func(i, j int) bool {
// Score is stored as JSON in the DB, for now just keep default order
return false
}
default: // "date"
less = func(i, j int) bool {
cmp := entries[i].UpdatedAt.After(entries[j].UpdatedAt)
if sortOrder == "asc" {
return !cmp
}
return cmp
}
}
// Simple bubble sort for small lists
for i := 0; i < len(entries); i++ {
for j := i + 1; j < len(entries); j++ {
if less(j, i) {
entries[i], entries[j] = entries[j], entries[i]
}
}
}
}