diff --git a/scraper/internal/server/ui.go b/scraper/internal/server/ui.go
index 43fc0d0..cc38530 100644
--- a/scraper/internal/server/ui.go
+++ b/scraper/internal/server/ui.go
@@ -268,7 +268,7 @@ const rankingTmpl = `
Top novels from novelfire.net
{{if .CachedAt}}Cached {{.CachedAt}}
{{end}}
-
@@ -391,6 +388,21 @@ func toRankingViewItems(items []writer.RankingItem, localSlugs map[string]bool)
return out
}
+// refreshPage is one entry in the ranking refresh pagination bar.
+type refreshPage struct {
+ Label string
+ Pages int // 0 means "all pages"
+}
+
+// rankingRefreshPages defines the ordered set of refresh buttons shown on the
+// ranking page. Pages == 0 means "fetch all pages".
+var rankingRefreshPages = []refreshPage{
+ {"Top 100", 1},
+ {"Top 300", 3},
+ {"Top 500", 5},
+ {"All", 0},
+}
+
// handleRanking serves the ranking page from the cached ranking.md file.
// It does NOT trigger a live scrape; use POST /ranking/refresh for that.
func (s *Server) handleRanking(w http.ResponseWriter, r *http.Request) {
@@ -407,9 +419,14 @@ func (s *Server) handleRanking(w http.ResponseWriter, r *http.Request) {
t := template.Must(template.New("ranking").Parse(rankingTmpl))
var buf bytes.Buffer
_ = t.Execute(&buf, struct {
- Books interface{}
- CachedAt string
- }{Books: toRankingViewItems(rankingItems, s.writer.LocalSlugs()), CachedAt: cachedAt})
+ Books interface{}
+ CachedAt string
+ RefreshPages []refreshPage
+ }{
+ Books: toRankingViewItems(rankingItems, s.writer.LocalSlugs()),
+ CachedAt: cachedAt,
+ RefreshPages: rankingRefreshPages,
+ })
s.respond(w, r, "Rankings", buf.String())
}