docs: fix implementation plan issues from review
- Move template registration from Phase 2 to Phase 4 (was causing build failure) - Add filter params (activeCategory, activeTime, activeType) to FromResponse - Add DisabledCategories to PageData for backend-unsupported categories - Add disabled class to sidebar for future categories - Clarify POST handler is a no-op for localStorage-only preferences - Note CSS must be tested manually in browser Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
b005e2140e
commit
8909654c8f
1 changed files with 44 additions and 55 deletions
|
|
@ -354,11 +354,13 @@ Append to end of `kafka.css`, before the `@media print` block:
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
- [ ] **Step 6: Verify CSS changes compile**
|
- [ ] **Step 6: Verify Go compilation**
|
||||||
|
|
||||||
Run: `go build ./...`
|
Run: `go build ./...`
|
||||||
Expected: No errors
|
Expected: No errors
|
||||||
|
|
||||||
|
Note: CSS is embedded as static files and not processed by the Go compiler. CSS changes must be tested manually in a browser.
|
||||||
|
|
||||||
- [ ] **Step 7: Commit**
|
- [ ] **Step 7: Commit**
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
|
@ -501,17 +503,28 @@ type FilterOption struct {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
- [ ] **Step 4: Update FromResponse to populate new fields**
|
- [ ] **Step 4: Update FromResponse to accept filter params**
|
||||||
|
|
||||||
In `views.go`, update `FromResponse` to populate the new fields:
|
Update `FromResponse` signature to accept `activeCategory`, `activeTime`, and `activeType` from the request. First update the `Search` handler in `handlers.go` to pass these params:
|
||||||
|
|
||||||
```go
|
```go
|
||||||
func FromResponse(resp contracts.SearchResponse, query string, pageno int) PageData {
|
// In handlers.go, update Search handler:
|
||||||
|
pd := views.FromResponse(resp, req.Query, req.Pageno)
|
||||||
|
pd.ActiveCategory = r.FormValue("category")
|
||||||
|
pd.ActiveTime = r.FormValue("time")
|
||||||
|
pd.ActiveType = r.FormValue("type")
|
||||||
|
```
|
||||||
|
|
||||||
|
Then update `FromResponse` in `views.go` to accept these params:
|
||||||
|
|
||||||
|
```go
|
||||||
|
func FromResponse(resp contracts.SearchResponse, query string, pageno int, activeCategory, activeTime, activeType string) PageData {
|
||||||
pd := PageData{
|
pd := PageData{
|
||||||
// ... existing initialization ...
|
// ... existing initialization ...
|
||||||
|
|
||||||
// New: categories with icons
|
// New: categories with icons
|
||||||
Categories: []string{"all", "news", "images", "videos", "maps", "shopping", "music", "weather"},
|
Categories: []string{"all", "news", "images", "videos", "maps"},
|
||||||
|
DisabledCategories: []string{"shopping", "music", "weather"},
|
||||||
CategoryIcons: map[string]string{
|
CategoryIcons: map[string]string{
|
||||||
"all": "🌐",
|
"all": "🌐",
|
||||||
"news": "📰",
|
"news": "📰",
|
||||||
|
|
@ -522,7 +535,8 @@ func FromResponse(resp contracts.SearchResponse, query string, pageno int) PageD
|
||||||
"music": "🎵",
|
"music": "🎵",
|
||||||
"weather": "🌤️",
|
"weather": "🌤️",
|
||||||
},
|
},
|
||||||
ActiveCategory: "all",
|
ActiveCategory: activeCategory,
|
||||||
|
if activeCategory == "" { activeCategory = "all" }
|
||||||
|
|
||||||
// Time filters
|
// Time filters
|
||||||
TimeFilters: []FilterOption{
|
TimeFilters: []FilterOption{
|
||||||
|
|
@ -533,7 +547,7 @@ func FromResponse(resp contracts.SearchResponse, query string, pageno int) PageD
|
||||||
{Label: "Past month", Value: "m"},
|
{Label: "Past month", Value: "m"},
|
||||||
{Label: "Past year", Value: "y"},
|
{Label: "Past year", Value: "y"},
|
||||||
},
|
},
|
||||||
ActiveTime: "",
|
ActiveTime: activeTime,
|
||||||
|
|
||||||
// Type filters
|
// Type filters
|
||||||
TypeFilters: []FilterOption{
|
TypeFilters: []FilterOption{
|
||||||
|
|
@ -542,64 +556,40 @@ func FromResponse(resp contracts.SearchResponse, query string, pageno int) PageD
|
||||||
{Label: "Videos", Value: "video"},
|
{Label: "Videos", Value: "video"},
|
||||||
{Label: "Images", Value: "image"},
|
{Label: "Images", Value: "image"},
|
||||||
},
|
},
|
||||||
ActiveType: "",
|
ActiveType: activeType,
|
||||||
}
|
}
|
||||||
// ... rest of function ...
|
// ... rest of function ...
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
- [ ] **Step 5: Register new preferences template**
|
Add `DisabledCategories []string` field to `PageData`.
|
||||||
|
|
||||||
In `views.go`, add to the `init()` function and add `tmplPreferences`:
|
- [ ] **Step 5: Update results.html sidebar to show disabled state**
|
||||||
|
|
||||||
```go
|
Update the sidebar category loop to conditionally apply `disabled` class:
|
||||||
var (
|
|
||||||
tmplFull *template.Template
|
|
||||||
tmplIndex *template.Template
|
|
||||||
tmplFragment *template.Template
|
|
||||||
tmplPreferences *template.Template
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
```html
|
||||||
tmplFS, _ := fs.Sub(templatesFS, "templates")
|
{{range .Categories}}
|
||||||
|
<a href="/search?q={{$.Query | urlquery}}&category={{.}}" class="sidebar-nav-item {{if eq $.ActiveCategory .}}active{{end}}">
|
||||||
funcMap := template.FuncMap{
|
<span class="sidebar-nav-item-icon">{{index $.CategoryIcons .}}</span>
|
||||||
"urlquery": template.URLQueryEscaper,
|
<span>{{.}}</span>
|
||||||
}
|
</a>
|
||||||
|
{{end}}
|
||||||
tmplFull = template.Must(template.New("").Funcs(funcMap).ParseFS(tmplFS,
|
<!-- Disabled categories with no links -->
|
||||||
"base.html", "results.html", "results_inner.html", "result_item.html", "video_item.html",
|
{{range .DisabledCategories}}
|
||||||
))
|
<span class="sidebar-nav-item disabled">
|
||||||
tmplIndex = template.Must(template.New("").Funcs(funcMap).ParseFS(tmplFS,
|
<span class="sidebar-nav-item-icon">{{index $.CategoryIcons .}}</span>
|
||||||
"base.html", "index.html",
|
<span>{{.}}</span>
|
||||||
))
|
</span>
|
||||||
tmplFragment = template.Must(template.New("").Funcs(funcMap).ParseFS(tmplFS,
|
{{end}}
|
||||||
"results_inner.html", "result_item.html", "video_item.html",
|
|
||||||
))
|
|
||||||
tmplPreferences = template.Must(template.New("").Funcs(funcMap).ParseFS(tmplFS,
|
|
||||||
"base.html", "preferences.html",
|
|
||||||
))
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
- [ ] **Step 6: Add RenderPreferences function**
|
- [ ] **Step 6: Test compilation**
|
||||||
|
|
||||||
Add to `views.go`:
|
|
||||||
|
|
||||||
```go
|
|
||||||
// RenderPreferences renders the full preferences page.
|
|
||||||
func RenderPreferences(w http.ResponseWriter, sourceURL string) error {
|
|
||||||
w.Header().Set("Content-Type", "text/html; charset=utf-8")
|
|
||||||
return tmplPreferences.ExecuteTemplate(w, "base", PageData{ShowHeader: true, SourceURL: sourceURL})
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
- [ ] **Step 7: Test compilation**
|
|
||||||
|
|
||||||
Run: `go build ./...`
|
Run: `go build ./...`
|
||||||
Expected: No errors
|
Expected: No errors
|
||||||
|
|
||||||
- [ ] **Step 8: Commit**
|
- [ ] **Step 7: Commit**
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git add internal/views/views.go internal/views/templates/results.html
|
git add internal/views/views.go internal/views/templates/results.html
|
||||||
|
|
@ -1020,15 +1010,14 @@ func (h *Handler) Preferences(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// PreferencesPOST handles form submission from the preferences page.
|
// PreferencesPOST handles form submission from the preferences page.
|
||||||
|
// NOTE: This is a no-op. All preferences are stored in localStorage on the client
|
||||||
|
// via JavaScript. This handler exists only for form submission completeness (e.g.,
|
||||||
|
// if a form POSTs without JS). The JavaScript in settings.js handles all saves.
|
||||||
func (h *Handler) PreferencesPOST(w http.ResponseWriter, r *http.Request) {
|
func (h *Handler) PreferencesPOST(w http.ResponseWriter, r *http.Request) {
|
||||||
if r.URL.Path != "/preferences" {
|
if r.URL.Path != "/preferences" {
|
||||||
http.NotFound(w, r)
|
http.NotFound(w, r)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// Preferences are stored in localStorage on the client.
|
|
||||||
// This handler exists for form submission completeness but
|
|
||||||
// the actual save happens via JavaScript.
|
|
||||||
// Redirect back to preferences page.
|
|
||||||
http.Redirect(w, r, "/preferences", http.StatusFound)
|
http.Redirect(w, r, "/preferences", http.StatusFound)
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue