package dashboard import ( "net/http" "net/url" "strings" ) type registryPageData struct { PageData Items []registryItem Query string StatusFilter string Page, PerPage int Total int Pager pagerData PerPageOptions []int } type registryDetailData struct { PageData History registryHistoryResponse } // handleRegistryPage lists every address ever submitted to the check // queue, with a summary of its accumulated check history — the durable // record that survives an address being deleted from /ips and later // re-added. See internal/db/migrations/0007_ip_registry.sql. Optional // ?q=&status= query params narrow the list by address substring and by // LastResult, and ?page=&per_page= select a page — all applied server-side // (control-api's ListRegistryPage), so only the visible rows are transferred. func (s *Server) handleRegistryPage(w http.ResponseWriter, r *http.Request) { q := strings.TrimSpace(r.URL.Query().Get("q")) status := r.URL.Query().Get("status") if !containsStr(ipResults, status) { status = "" } perPage := parsePerPage(r.URL.Query().Get("per_page")) page := parsePage(r.URL.Query().Get("page")) query := registryQuery{Q: q, LastResult: status, Limit: perPage, Offset: (page - 1) * perPage} res, err := s.CA.ListRegistryPage(r.Context(), query) if err == nil { if clamped := clampPage(page, res.Total, perPage); clamped != page { page = clamped query.Offset = (page - 1) * perPage res, err = s.CA.ListRegistryPage(r.Context(), query) } } params := url.Values{} if q != "" { params.Set("q", q) } if status != "" { params.Set("status", status) } data := registryPageData{ Items: res.Items, Query: q, StatusFilter: status, Page: page, PerPage: perPage, Total: res.Total, Pager: newPager("/registry", "registry-table-wrap", params, page, perPage, res.Total), PerPageOptions: perPageOptions, } data.ActiveNav = "registry" data.Banner = bannerFor(err) s.renderPage(w, r, "registry_page", data) } // handleRegistryDetail shows one address's full retained check history // across every cycle it has ever run, not just the current attempt — see // ip_detail_content in ip_detail.html for the attempt-scoped equivalent. func (s *Server) handleRegistryDetail(w http.ResponseWriter, r *http.Request) { ip := r.PathValue("ip") history, err := s.CA.GetRegistryHistory(r.Context(), ip) data := registryDetailData{History: history} data.ActiveNav = "registry" data.Banner = bannerFor(err) s.renderPage(w, r, "registry_detail_page", data) }