diff --git a/internal/httpapi/handlers.go b/internal/httpapi/handlers.go index f8db054..e27db01 100644 --- a/internal/httpapi/handlers.go +++ b/internal/httpapi/handlers.go @@ -112,7 +112,8 @@ func (h *Handler) Search(w http.ResponseWriter, r *http.Request) { } if req.Format == contracts.FormatHTML { - pd := views.FromResponse(resp, req.Query, req.Pageno) + pd := views.FromResponse(resp, req.Query, req.Pageno, + r.FormValue("category"), r.FormValue("time"), r.FormValue("type")) if err := views.RenderSearchAuto(w, r, pd); err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) } diff --git a/internal/views/templates/results.html b/internal/views/templates/results.html index 7010a3a..39e7c64 100644 --- a/internal/views/templates/results.html +++ b/internal/views/templates/results.html @@ -1,32 +1,75 @@ {{define "title"}}{{if .Query}}{{.Query}} β€” {{end}}{{end}} {{define "content"}}
- -
- -
+ + + + +
+ +
+ +
+ + +
+ All + {{range .Categories}} + {{.}} + {{end}} +
+ + {{template "results_inner" .}}
- -
-{{end}} +{{end}} \ No newline at end of file diff --git a/internal/views/views.go b/internal/views/views.go index 4d7289c..0161d2b 100644 --- a/internal/views/views.go +++ b/internal/views/views.go @@ -50,6 +50,15 @@ type PageData struct { UnresponsiveEngines [][2]string PageNumbers []PageNumber ShowHeader bool + // New fields for three-column layout + Categories []string + CategoryIcons map[string]string + DisabledCategories []string + ActiveCategory string + TimeFilters []FilterOption + TypeFilters []FilterOption + ActiveTime string + ActiveType string } // ResultView is a template-friendly wrapper around a MainResult. @@ -73,6 +82,12 @@ type InfoboxView struct { ImgSrc string } +// FilterOption represents a filter radio option for the sidebar. +type FilterOption struct { + Label string + Value string +} + var ( tmplFull *template.Template tmplIndex *template.Template @@ -116,12 +131,52 @@ func OpenSearchXML(baseURL string) ([]byte, error) { } // FromResponse builds PageData from a search response and request params. -func FromResponse(resp contracts.SearchResponse, query string, pageno int) PageData { +func FromResponse(resp contracts.SearchResponse, query string, pageno int, activeCategory, activeTime, activeType string) PageData { + // Set defaults + if activeCategory == "" { + activeCategory = "all" + } + pd := PageData{ Query: query, Pageno: pageno, NumberOfResults: resp.NumberOfResults, UnresponsiveEngines: resp.UnresponsiveEngines, + + // New: categories with icons + Categories: []string{"all", "news", "images", "videos", "maps"}, + DisabledCategories: []string{"shopping", "music", "weather"}, + CategoryIcons: map[string]string{ + "all": "🌐", + "news": "πŸ“°", + "images": "πŸ–ΌοΈ", + "videos": "🎬", + "maps": "πŸ—ΊοΈ", + "shopping": "πŸ›’", + "music": "🎡", + "weather": "🌀️", + }, + ActiveCategory: activeCategory, + + // Time filters + TimeFilters: []FilterOption{ + {Label: "Any time", Value: ""}, + {Label: "Past hour", Value: "h"}, + {Label: "Past 24 hours", Value: "d"}, + {Label: "Past week", Value: "w"}, + {Label: "Past month", Value: "m"}, + {Label: "Past year", Value: "y"}, + }, + ActiveTime: activeTime, + + // Type filters + TypeFilters: []FilterOption{ + {Label: "All results", Value: ""}, + {Label: "News", Value: "news"}, + {Label: "Videos", Value: "video"}, + {Label: "Images", Value: "image"}, + }, + ActiveType: activeType, } // Convert results.