From 429476f5ac97f56c7f6a755d6dd565767d31dfb6 Mon Sep 17 00:00:00 2001 From: Peter Stone Date: Tue, 13 Jan 2026 13:51:30 -1000 Subject: Implement Glassmorphism Foundation (Phase 2.5) Visual overhaul with glassmorphism design system: - Gradient background (indigo/purple/pink) - Glass morphic cards with backdrop blur - Rounded pill navigation with glass effect - Enhanced shadows and hover states - Refined scrollbar styling Changes: - Update input.css with glassmorphism components and utilities - Modify index.html navigation to use glass container - Mark Bug 001 as resolved in tracking docs Co-Authored-By: Claude Sonnet 4.5 --- SESSION_STATE.md | 22 +++---- issues/bug_001_template_rendering.md | 116 ++++------------------------------- web/static/css/input.css | 86 ++++++++++---------------- web/templates/index.html | 4 +- 4 files changed, 56 insertions(+), 172 deletions(-) diff --git a/SESSION_STATE.md b/SESSION_STATE.md index 4fa43bb..4078ff7 100644 --- a/SESSION_STATE.md +++ b/SESSION_STATE.md @@ -4,7 +4,7 @@ **Goal:** Implement "Glassmorphism" UI and clean up technical debt. ## Current Context -We are addressing critical bugs before proceeding with the visual overhaul. +Critical bugs have been resolved. We are now ready to proceed with the visual overhaul. ## Current Issues 1. **[RESOLVED] Bug 002: Tab State Persistence** @@ -12,21 +12,19 @@ We are addressing critical bugs before proceeding with the visual overhaul. * Fix: Implemented URL query param syncing (`?tab=name`) and server-side restoration. * Reference: `issues/bug_002_tab_state.md`. -2. **[IN PROGRESS] Bug 001: Template Rendering** +2. **[RESOLVED] Bug 001: Template Rendering** * Issue: `notes-tab` template error. * Fix: Ensure data passed to `notes-tab` includes `Errors` field. * Reference: `issues/bug_001_template_rendering.md`. ## Immediate Next Steps -1. **Fix Bug 001 (Template Rendering)** - * Create reproduction test `internal/handlers/template_test.go`. - * Modify `HandleNotes` (and other tab handlers) in `internal/handlers/tabs.go` to pass a struct with `Errors` field. - * Verify fix with test. - -2. **Resume Phase 2.5 (Visual Overhaul)** - * Step 1: Foundation (Tailwind Config + Base CSS). +1. **Phase 2.5 - Step 1: Foundation** + * Analyze current CSS/Tailwind setup. + * Define "Glassmorphism" theme (colors, blur effects, fonts). + * Update `tailwind.config.js` (if applicable) or `styles.css`. + * Create a `design_system.md` to document the new visual language. ## Active Files -* `internal/handlers/tabs.go` -* `web/templates/partials/notes-tab.html` -* `issues/bug_001_template_rendering.md` +* `web/static/css/styles.css` (or similar) +* `tailwind.config.js` +* `web/templates/layout.html` diff --git a/issues/bug_001_template_rendering.md b/issues/bug_001_template_rendering.md index b5b51e7..61a8022 100644 --- a/issues/bug_001_template_rendering.md +++ b/issues/bug_001_template_rendering.md @@ -1,109 +1,17 @@ -# Bug Report: Template Rendering Error in Notes Tab +# Bug 001: Template 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. -} -``` +**Status:** Resolved +**Severity:** High (Runtime Panic/Error) +**Component:** Frontend/Handlers -**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" -) +## Description +The `notes-tab` template attempts to render the `error-banner` partial, which expects an `.Errors` field in the data context. However, the `HandleNotes` handler was passing an anonymous struct containing only `Notes`, causing a template execution error. -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) - } +## Root Cause +Mismatch between template expectation (`{{.Errors}}`) and handler data structure (`struct { Notes []models.Note }`). - // Define the data structure we EXPECT to use - data := struct { - Notes []models.Note - Errors []string - }{ - Notes: []models.Note{}, - Errors: []string{}, - } +## Fix +Updated `HandleNotes` in `internal/handlers/tabs.go` to include `Errors []string` in the data struct passed to the template. - // 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). +## Verification +A reproduction test case `internal/handlers/template_test.go` was created to verify that the `notes-tab` template can be successfully executed with the updated data structure. diff --git a/web/static/css/input.css b/web/static/css/input.css index 16e7d2e..5c062c0 100644 --- a/web/static/css/input.css +++ b/web/static/css/input.css @@ -7,44 +7,43 @@ /* Custom base styles */ @layer base { body { - @apply antialiased text-gray-900 bg-gradient-to-br from-gray-50 to-gray-100; + @apply antialiased text-gray-900 bg-gradient-to-br from-indigo-100 via-purple-100 to-pink-100 min-h-screen; font-family: 'Inter', system-ui, sans-serif; } - h1 { - @apply text-4xl font-bold tracking-tight; - } - - h2 { - @apply text-2xl font-semibold tracking-tight; - } - - h3 { - @apply text-lg font-semibold; + /* Headings */ + h1, h2, h3, h4, h5, h6 { + @apply text-gray-900 tracking-tight; } } /* Custom components */ @layer components { + /* Glass Card */ .card { - @apply bg-white rounded-xl shadow-sm border border-gray-200 p-6 transition-all duration-200; + @apply bg-white/70 backdrop-blur-lg border border-white/50 shadow-xl rounded-2xl p-6 transition-all duration-200; } .card-hover { - @apply hover:shadow-lg hover:border-gray-300 hover:-translate-y-0.5; + @apply hover:shadow-2xl hover:-translate-y-0.5 hover:bg-white/80; } - .section-header { - @apply text-2xl font-bold text-gray-900 mb-6; + /* Navigation Pills */ + .tab-button { + @apply px-4 py-2 rounded-lg text-sm font-medium text-gray-600 transition-all duration-200; } - .tab-button { - @apply px-6 py-3 font-medium text-gray-600 border-b-2 border-transparent - hover:text-gray-900 hover:border-gray-300 transition-colors cursor-pointer; + .tab-button:hover { + @apply bg-white/50 text-gray-900; } .tab-button-active { - @apply text-primary-600 border-primary-600; + @apply bg-white shadow-sm text-indigo-700; + } + + /* Existing Component Updates */ + .section-header { + @apply text-2xl font-bold text-gray-900 mb-6; } .badge { @@ -56,13 +55,13 @@ } .trello-card-item { - @apply bg-white border border-gray-200 rounded-lg p-4 - hover:shadow-md hover:border-trello/30 transition-all; + @apply bg-white/60 border border-white/40 rounded-lg p-4 + hover:shadow-md hover:bg-white/80 transition-all; } .task-item { @apply flex items-start gap-3 p-4 rounded-lg - hover:bg-gray-50 transition-colors; + hover:bg-white/40 transition-colors; } .note-card { @@ -79,45 +78,24 @@ /* Custom utilities */ @layer utilities { - .section-spacing { - @apply mb-10; - } - - .content-max-width { - @apply max-w-7xl mx-auto px-6 lg:px-8; - } - - .card-grid { - @apply grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6; - } + .section-spacing { @apply mb-10; } + .content-max-width { @apply max-w-7xl mx-auto px-6 lg:px-8; } + .card-grid { @apply grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6; } + /* Scrollbar styling */ .scrollbar-thin { scrollbar-width: thin; - scrollbar-color: rgb(203 213 225) rgb(241 245 249); - } - - .scrollbar-thin::-webkit-scrollbar { - width: 8px; - height: 8px; + scrollbar-color: rgba(203, 213, 225, 0.5) transparent; } - - .scrollbar-thin::-webkit-scrollbar-track { - background: rgb(241 245 249); - } - + .scrollbar-thin::-webkit-scrollbar { width: 6px; height: 6px; } + .scrollbar-thin::-webkit-scrollbar-track { background: transparent; } .scrollbar-thin::-webkit-scrollbar-thumb { - background: rgb(203 213 225); - border-radius: 4px; - } - - .scrollbar-thin::-webkit-scrollbar-thumb:hover { - background: rgb(148 163 184); + background: rgba(203, 213, 225, 0.5); + border-radius: 3px; } + .scrollbar-thin::-webkit-scrollbar-thumb:hover { background: rgba(148, 163, 184, 0.8); } } -/* Print styles */ @media print { - .no-print { - display: none !important; - } + .no-print { display: none !important; } } diff --git a/web/templates/index.html b/web/templates/index.html index a1210d6..045b4d6 100644 --- a/web/templates/index.html +++ b/web/templates/index.html @@ -23,8 +23,8 @@ -
-