summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--issues/bug_001_template_rendering.md109
-rw-r--r--issues/bug_002_tab_state.md31
2 files changed, 140 insertions, 0 deletions
diff --git a/issues/bug_001_template_rendering.md b/issues/bug_001_template_rendering.md
new file mode 100644
index 0000000..b5b51e7
--- /dev/null
+++ b/issues/bug_001_template_rendering.md
@@ -0,0 +1,109 @@
+# Bug Report: Template Rendering Error in Notes Tab
+
+## Description
+The application logs an error when rendering the Notes tab:
+`Error rendering notes tab: template: error-banner.html:2:5: executing "error-banner" at <.Errors>: can't evaluate field Errors in type struct { Notes []models.Note }`
+
+This occurs because the `notes-tab` template (which includes `error-banner`) expects a data structure with an `Errors` field, but `HandleNotes` in `internal/handlers/tabs.go` passes an anonymous struct with only `Notes`.
+
+## Reproduction
+1. Run the application.
+2. Navigate to the Notes tab (or trigger a request to `/tabs/notes`).
+3. Observe the error in the server logs.
+
+## Fix Instructions
+
+### 1. Create a Reproduction Test
+Create a new test file `internal/handlers/tabs_test.go` to reproduce the issue.
+
+```go
+package handlers
+
+import (
+ "html/template"
+ "net/http"
+ "net/http/httptest"
+ "testing"
+
+ "task-dashboard/internal/models"
+ "task-dashboard/internal/store"
+)
+
+func TestHandleNotes_RenderError(t *testing.T) {
+ // Setup
+ // Note: You might need to mock the store or use a temporary SQLite DB
+ // For this specific template error, we can test the template execution directly
+ // or mock the store to return empty notes.
+
+ // Since setting up the full store with DB is complex for a unit test,
+ // let's focus on the data structure passed to the template.
+ // However, the handler is coupled to the store.
+
+ // A better approach for this specific bug is to verify the fix by ensuring
+ // the data struct has the Errors field.
+}
+```
+
+**Better Approach:**
+Modify `internal/handlers/tabs.go` to use a consistent data structure that includes `Errors`.
+
+### 2. Modify `internal/handlers/tabs.go`
+
+Update the `HandleNotes` function (and others if necessary) to pass a struct that includes `Errors`.
+
+```go
+// Define a shared data structure or use an anonymous one with Errors
+data := struct {
+ Notes []models.Note
+ Errors []string
+}{
+ Notes: notes,
+ Errors: nil, // Or populate if there are errors
+}
+```
+
+### 3. Verify
+Run the application and check the logs. The error should disappear.
+
+## Automated Test for Verification
+Since we don't have a full test suite set up yet, we can create a simple test that parses the templates and attempts to execute them with the corrected data structure to ensure compatibility.
+
+Create `internal/handlers/template_test.go`:
+
+```go
+package handlers_test
+
+import (
+ "html/template"
+ "testing"
+ "task-dashboard/internal/models"
+)
+
+func TestNotesTemplateRendering(t *testing.T) {
+ // Parse templates
+ tmpl, err := template.ParseGlob("../../web/templates/*.html")
+ if err != nil {
+ t.Fatalf("Failed to parse templates: %v", err)
+ }
+ tmpl, err = tmpl.ParseGlob("../../web/templates/partials/*.html")
+ if err != nil {
+ t.Fatalf("Failed to parse partials: %v", err)
+ }
+
+ // Define the data structure we EXPECT to use
+ data := struct {
+ Notes []models.Note
+ Errors []string
+ }{
+ Notes: []models.Note{},
+ Errors: []string{},
+ }
+
+ // Execute
+ err = tmpl.ExecuteTemplate(io.Discard, "notes-tab", data)
+ if err != nil {
+ t.Errorf("Failed to render notes-tab with corrected data: %v", err)
+ }
+}
+```
+(Note: You'll need to import `io` and adjust paths).
diff --git a/issues/bug_002_tab_state.md b/issues/bug_002_tab_state.md
new file mode 100644
index 0000000..c8c7c09
--- /dev/null
+++ b/issues/bug_002_tab_state.md
@@ -0,0 +1,31 @@
+# Bug 002: Tab State Persistence (RESOLVED)
+
+## Status
+**RESOLVED**
+
+## Description
+When a user switches tabs (e.g., to "Notes") and refreshes the page, the dashboard resets to the default "Tasks" tab. This is a poor user experience. The application should respect the `?tab=` query parameter and update the URL when tabs are switched.
+
+## Root Cause
+1. **Server-Side:** `HandleDashboard` does not read the `tab` query parameter or pass it to the template.
+2. **Client-Side:** `index.html` hardcodes the initial active tab to "Tasks".
+3. **Client-Side:** Tab buttons use `hx-push-url="false"`, so the URL doesn't update on click.
+
+## Resolution
+1. **Model Update:** Added `ActiveTab` field to `DashboardData` struct in `internal/models/types.go`.
+2. **Handler Update:** Updated `HandleDashboard` in `internal/handlers/handlers.go` to:
+ * Read `r.URL.Query().Get("tab")`.
+ * Validate the tab name (defaulting to "tasks").
+ * Set `ActiveTab` in the data passed to the template.
+3. **Template Update:** Updated `web/templates/index.html` to:
+ * Use `{{if eq .ActiveTab "..."}}` to conditionally apply the `tab-button-active` class.
+ * Set the initial `hx-get` for `#tab-content` to `/tabs/{{.ActiveTab}}`.
+ * Set `hx-push-url="?tab=..."` on all tab buttons to ensure the URL updates in the browser history.
+4. **Client-Side Update:** Updated `web/static/js/app.js` to initialize `currentTab` from the URL query parameter.
+
+## Verification
+* **Automated Test:** Created `internal/handlers/tab_state_test.go` which verifies:
+ * Default load (`/`) renders "tasks" as active.
+ * Query param load (`/?tab=notes`) renders "notes" as active.
+ * All valid tab names are supported.
+* **Manual Verification:** Confirmed that clicking tabs updates the URL and refreshing the page preserves the active tab.