# Phase 4: UX Improvements - Discussion Log > **Audit trail only.** Do not use as input to planning, research, or execution agents. > Decisions are captured in CONTEXT.md -- this log preserves the alternatives considered. **Date:** 2026-03-24 **Phase:** 04-ux-improvements **Areas discussed:** Bulk dismiss scope, Search/filter architecture, New-update detection, Theme toggle behavior **Mode:** auto (all decisions auto-selected) --- ## Bulk Dismiss Scope | Option | Description | Selected | |--------|-------------|----------| | New Store methods + dedicated endpoints | Add AcknowledgeAll and AcknowledgeByTag to Store interface with new HTTP endpoints | ✓ | | Batch image list from frontend | Frontend sends list of image names to a generic bulk-dismiss endpoint | | | Reuse existing single-dismiss in loop | Frontend calls existing PATCH /api/updates/{image} for each item | | **User's choice:** [auto] New Store methods + dedicated endpoints (recommended default) **Notes:** Consistent with existing per-image dismiss pattern. Server-side bulk is more efficient and keeps frontend simple. --- | Option | Description | Selected | |--------|-------------|----------| | Tag ID parameter for per-group dismiss | Server looks up which images belong to the tag | ✓ | | Send list of images from frontend | Frontend determines which images are in the group | | **User's choice:** [auto] Tag ID parameter (recommended default) **Notes:** Server already knows tag-image relationships, fewer bytes over the wire. --- | Option | Description | Selected | |--------|-------------|----------| | Dismiss-all in header, dismiss-group in TagSection header | Natural placement near existing controls | ✓ | | All bulk actions in a separate toolbar | Dedicated action bar for bulk operations | | **User's choice:** [auto] Dismiss-all in header area, dismiss-by-group in each TagSection header (recommended default) --- | Option | Description | Selected | |--------|-------------|----------| | Confirmation dialog for all, inline for per-group | Dismiss-all gets modal; per-group matches existing tag-delete pattern | ✓ | | No confirmation for either | Fast but risky | | | Confirmation for both | Consistent but slower workflow | | **User's choice:** [auto] Yes, confirmation dialog for dismiss-all; inline confirm for per-group (recommended default) --- ## Search/Filter Architecture | Option | Description | Selected | |--------|-------------|----------| | Client-side filtering | All data already in memory from polling; filter in React state | ✓ | | Server-side with query params | Add filter params to GET /api/updates endpoint | | | Hybrid (client with server fallback) | Client-side now, server-side when data grows | | **User's choice:** [auto] Client-side filtering (recommended default) **Notes:** All data is fetched via 5s polling. No need for server-side filtering at this scale. --- | Option | Description | Selected | |--------|-------------|----------| | Filter bar above sections, below stats | Standard placement, visible without scrolling | ✓ | | Collapsible sidebar filters | More space but hidden by default | | | Inline per-section filters | Distributed, harder to use across groups | | **User's choice:** [auto] Filter bar above the sections list (recommended default) --- | Option | Description | Selected | |--------|-------------|----------| | Text search + status + tag + sort dropdowns | Covers all SRCH requirements | ✓ | | Text search only | Minimal, doesn't cover SRCH-02/03/04 | | **User's choice:** [auto] Search text input + status dropdown + tag dropdown + sort dropdown (recommended default) --- | Option | Description | Selected | |--------|-------------|----------| | No persistence (reset on reload) | Simpler, dashboard is quick-glance tool | ✓ | | Persist in URL params | Shareable/bookmarkable filters | | | Persist in localStorage | Remembers across visits | | **User's choice:** [auto] No persistence -- reset on reload (recommended default) --- ## New-Update Detection | Option | Description | Selected | |--------|-------------|----------| | localStorage timestamp | Store last visit time client-side, compare with received_at | ✓ | | Server-side last-seen tracking | Track per-user last-seen on server | | | Session-only (no persistence) | Only detect new items arriving during current session | | **User's choice:** [auto] localStorage timestamp (recommended default) **Notes:** Single-user tool, no server changes needed. Simple and effective. --- | Option | Description | Selected | |--------|-------------|----------| | Auto-dismiss after 5s with dismiss button | Non-intrusive, doesn't pile up | ✓ | | Sticky until manually dismissed | Persistent but can pile up | | | No toast, badge only | Minimal notification | | **User's choice:** [auto] Auto-dismiss after 5 seconds with dismiss button (recommended default) --- | Option | Description | Selected | |--------|-------------|----------| | Header badge + tab title | Always visible, covers INDIC-01 and INDIC-02 | ✓ | | Stats card only | Already partially exists | | **User's choice:** [auto] In the header next to title + browser tab title (recommended default) --- | Option | Description | Selected | |--------|-------------|----------| | Subtle left border accent | Visible but not overwhelming | ✓ | | Background color change | More prominent | | | Pulsing dot indicator | Animated, attention-grabbing | | **User's choice:** [auto] Subtle left border accent on ServiceCard (recommended default) --- ## Theme Toggle Behavior | Option | Description | Selected | |--------|-------------|----------| | Header bar, next to refresh button | Compact, always accessible | ✓ | | Footer | Less prominent | | | Settings page | Requires new page | | **User's choice:** [auto] Header bar, next to refresh button (recommended default) --- | Option | Description | Selected | |--------|-------------|----------| | localStorage with prefers-color-scheme fallback | Standard pattern, no server involvement | ✓ | | Cookie-based | SSR-friendly but not needed here | | | No persistence | Resets every visit | | **User's choice:** [auto] localStorage with prefers-color-scheme fallback (recommended default) --- | Option | Description | Selected | |--------|-------------|----------| | Always visible at reduced opacity | Accessible without cluttering UI | ✓ | | Always fully visible | More prominent but noisier | | | Keep hover-only | Current behavior, accessibility issue | | **User's choice:** [auto] Always visible at reduced opacity, full opacity on hover (recommended default) --- ## Claude's Discretion - Toast component implementation (custom or shadcn/ui Sonner) - Exact filter bar layout and responsive breakpoints - Animation/transition details for theme switching - Whether to show a count in the per-group dismiss button - Sort order default ## Deferred Ideas None -- discussion stayed within phase scope.