From 65c17561ae57feb18b719e87876574ddc7dd5792 Mon Sep 17 00:00:00 2001 From: Arthur Belleville Date: Sat, 16 May 2026 21:08:44 +0200 Subject: [PATCH] docs(15): capture phase context --- .../phases/15-dashboard-tablos/15-CONTEXT.md | 125 ++++++++++++++++++ .../15-dashboard-tablos/15-DISCUSSION-LOG.md | 110 +++++++++++++++ 2 files changed, 235 insertions(+) create mode 100644 .planning/phases/15-dashboard-tablos/15-CONTEXT.md create mode 100644 .planning/phases/15-dashboard-tablos/15-DISCUSSION-LOG.md diff --git a/.planning/phases/15-dashboard-tablos/15-CONTEXT.md b/.planning/phases/15-dashboard-tablos/15-CONTEXT.md new file mode 100644 index 0000000..1dec13a --- /dev/null +++ b/.planning/phases/15-dashboard-tablos/15-CONTEXT.md @@ -0,0 +1,125 @@ +# Phase 15: Dashboard & Tablos - Context + +**Gathered:** 2026-05-16 +**Status:** Ready for planning + + +## Phase Boundary + +Replace the current top-nav shell + simple card list with a sidebar-based app layout (`AppLayout`) and project-card grid that matches the go-backend visual design. Phase 15 delivers: +- New `AppLayout` templ with sidebar (brand, nav items, tablo list section, user footer) +- Tablo dashboard restyled as a 3-column project-card grid +- Tablo empty state uses the `ui.EmptyState` component +- All existing tablo CRUD handler tests pass unchanged + +Does NOT include: tablo detail restyling (Phase 16), chat/planning restyling (Phase 17), sidebar collapse JS interaction, mobile-responsive sidebar breakpoints. + + + + +## Implementation Decisions + +### App Layout Shell +- **D-L01:** Create a new `AppLayout(title string, user *auth.User, csrfToken string, activePath string, tablos []sqlc.Tablo)` templ in `backend/templates/`. All authenticated dashboard pages use `AppLayout`. The old `Layout` templ is preserved but no longer used by dashboard pages (it becomes dead code, can be removed in a future cleanup). +- **D-L02:** `AppLayout` uses the `.dashboard-shell` CSS grid (sidebar + main columns) from `go-backend/internal/web/ui/app.css`. Port `.dashboard-shell`, `.dashboard-sidebar`, `.sidebar-nav-shell`, all `.sidebar-*` CSS, `.sidebar-organization`, and `.dashboard-main` into `backend/internal/web/ui/app.css` (a new CSS file, not auth.css). +- **D-L03:** Active nav item: `AppLayout` receives `activePath string`. A helper function (pure Go, not templ) returns `"is-active"` class when a nav item's href matches `activePath`. Handlers pass the current route path explicitly (e.g., `"/"`, `"/planning"`, `"/tablos"`). +- **D-L04:** Scripts: `AppLayout` loads `htmx.min.js`, `sortable.min.js`, and `discussion-sse.js` — same as the current `Layout`. No change to script loading. + +### Sidebar Nav Items +- **D-N01:** Match go-backend nav item set: Dashboard (`/`), Tablos (`/` or tablo overview — same as Dashboard for now), Tasks, Planning (`/planning`), Chat, Files, Settings. Use go-backend's `dashboard_components.templ` icon SVGs verbatim. +- **D-N02:** Routes that exist in the backend get real `href` values: Dashboard (`/`), Planning (`/planning`). Routes not yet built as standalone pages (Tasks, Files, Settings) render as visual nav items with no `href` attribute (display only, `cursor: default` on the item). +- **D-N03:** Chat is per-tablo (linked from tablo detail, not a top-level nav destination). In the sidebar nav, Chat links to `/` (dashboard) as a placeholder, or is rendered as a visual-only item like Tasks — Claude's discretion. +- **D-N04:** Sidebar-projects section: shows the user's tablos as a list with a colored circle icon (derived from tablo color field) + truncated title. Each item links to `/tablos/{id}`. Section label: "Projects" (English, matching backend convention). + +### Tablo Project Cards +- **D-C01:** Tablo dashboard uses the `.project-grid` 3-column CSS grid layout from go-backend. Port `.project-grid`, `.project-card`, `.project-card-top`, and related CSS into the new `app.css`. +- **D-C02:** Each project card shows (matching go-backend exactly): colored circle avatar (top-left) + title + edit icon button (top-right) + delete icon button (top-right) + creation date (bottom row). +- **D-C03:** Color avatar: use `tablo.Color` field when set. When null/empty, show a default neutral/gray circle (no derived color, no initials). The circle renders via a small `` styled with background-color, matching go-backend's `.sidebar-project-icon` pattern. +- **D-C04:** Edit and delete action icons use `@ui.IconButton(...)` from the design system (Phase 13 component). The HTMX attributes for edit (`hx-get=/tablos/{id}/edit`) and delete (`hx-delete=/tablos/{id}`) are preserved from the current `TabloCard` implementation. +- **D-C05:** The "New tablo" button and inline create form slot (`#create-form-slot`) move to a section header above the grid, matching go-backend's `.overview-section-heading` pattern. + +### Tablo Empty State +- **D-E01:** When no tablos exist, use `@ui.EmptyState(ui.EmptyStateProps{...})` — the Phase 13 component. Replace the current raw HTML empty state in `TablosEmptyState()`. Title: "No tablos yet". Description: "Create your first tablo to get started." Action: "New tablo" button. + +### Sidebar Footer (User/Account) +- **D-F01:** Include a sidebar footer matching go-backend's `.sidebar-organization` section. Shows: avatar circle (first letter of email, colored background) + user email + a small account link. Logout is moved from the old top-nav into this footer area. +- **D-F02:** The account/settings page doesn't exist yet, so the footer button/link only shows the email + logout button. No settings navigation for Phase 15. The `.organization-button` wraps a simple display element, not a dropdown. +- **D-F03:** Port `.sidebar-organization`, `.organization-button`, `.organization-avatar`, `.organization-name`, `.organization-meta` CSS from go-backend into `app.css`. + +### Claude's Discretion +- Exact set of SVG icons for each nav item (copy from go-backend `dashboard_components.templ` — no new icon design needed) +- Whether the sidebar-projects section is a separate templ component or inline in `AppLayout` (prefer separate `SidebarProjectsSection` for testability) +- Exact color for the neutral avatar fallback (use `--color-surface-muted` or similar design token) +- Whether sidebar-footer avatar background color is derived from email hash or a fixed brand color + + + + +## Canonical References + +**Downstream agents MUST read these before planning or implementing.** + +### Product Scope +- `.planning/ROADMAP.md` — Phase 15 goal, success criteria (5 criteria), requirements DASH-01/02/03 +- `.planning/REQUIREMENTS.md` — DASH-01 (sidebar design), DASH-02 (project-card layout), DASH-03 (empty state) +- `.planning/PROJECT.md` — v3.0 scope: visual polish only, go-backend is the visual reference + +### Reference Implementation (source of truth) +- `go-backend/internal/web/views/dashboard_components.templ` — `DashboardPage`, `DashboardSidebar`, `SidebarProjectsSection`, `SidebarNavItem`, `SidebarOrganization` — port structure from here +- `go-backend/internal/web/ui/app.css` — ALL dashboard/sidebar CSS: `.dashboard-shell`, `.dashboard-sidebar`, `.sidebar-nav-shell`, all `.sidebar-*` classes, `.sidebar-organization`, `.dashboard-main`, `.project-grid`, `.project-card`, `.project-card-top` — extract these sections only +- `go-backend/static/logo_dark.png` — brand logo already copied to `backend/static/` in Phase 14 + +### Current Backend (files being changed) +- `backend/templates/layout.templ` — current top-nav Layout; being superseded by AppLayout for dashboard pages +- `backend/templates/tablos.templ` — TablosDashboard, TabloCard, TablosEmptyState — all being restyled +- `backend/internal/web/handlers_tablos.go` (or equivalent) — handlers need to pass tablos list + activePath to AppLayout + +### Design System (Phase 13 — already in backend) +- `backend/internal/web/ui/empty-state.css` + `backend/internal/web/ui/*.templ` — `ui.EmptyState`, `ui.IconButton`, `ui.Button` components already available +- `backend/internal/web/ui/base.css` — design tokens; all new CSS in `app.css` must use `var(--...)` tokens + + + + +## Existing Code Insights + +### Reusable Assets +- `ui.EmptyState` (Phase 13): Ready to use for `TablosEmptyState` — replace raw HTML with `@ui.EmptyState(ui.EmptyStateProps{Title, Description, Icon, Action})` +- `ui.IconButton` (Phase 13): Use for edit + delete icon buttons on project cards — replaces any raw icon buttons +- `ui.Button` (Phase 13): "New tablo" button stays as `@ui.Button(...)` with same HTMX attrs +- `backend/static/logo_dark.png`: Already exists (Phase 14) — use for sidebar brand logo + +### Established Patterns +- `AuthLayout` pattern (Phase 14): New `AppLayout` should follow the same package + templ structure — `package templates`, explicit param list, children via `{ children... }` +- `sqlc.Tablo` type: Has `Color pgtype.Text` (nullable), `Title string`, `ID pgx.UUID`, `CreatedAt pgtype.Timestamptz` — all needed for sidebar-projects and project cards +- Handler pattern: Handlers currently call `Layout(title, user, csrfToken)` — will change to `AppLayout(title, user, csrfToken, activePath, tablos)` requiring handlers to fetch tablos list + +### Integration Points +- `backend/internal/web/handlers_tablos.go`: TablosDashboardHandler fetches tablos for display; needs to also pass tablos to AppLayout for the sidebar-projects section (already has them) +- Other handlers (PlanningHandler, ChatHandler, etc.): Will need to fetch the user's tablos list to populate the sidebar — this is a cross-handler concern worth factoring into a shared helper + + + + +## Specific Ideas + +- Sidebar visual: match go-backend's `DashboardSidebar` structure verbatim — brand logo (logo_dark.png, 4rem×4rem rounded), "XTablo" title, nav list, projects section, footer +- Project card: match go-backend `.project-card` + `.project-card-top` layout — white card, 1rem border-radius, 1rem padding, edit/delete icon buttons in top-right corner +- Sidebar footer: full `.sidebar-organization` treatment — avatar circle with first letter + email + logout button inside `.organization-button` + + + + +## Deferred Ideas + +- Sidebar collapse toggle (JS interaction) — requires client-side JS to persist collapsed state; deferred to a future polish phase +- Mobile-responsive sidebar (hamburger menu, slide-in drawer) — deferred; Phase 15 desktop-first only +- Tablo color picker in the create/edit form — the color field exists in the DB but no UI to set it; deferred to a future enhancement +- Tasks, Files, Settings as standalone pages — nav items shown as visual-only until those pages are built + + + +--- + +*Phase: 15-dashboard-tablos* +*Context gathered: 2026-05-16* diff --git a/.planning/phases/15-dashboard-tablos/15-DISCUSSION-LOG.md b/.planning/phases/15-dashboard-tablos/15-DISCUSSION-LOG.md new file mode 100644 index 0000000..21a990d --- /dev/null +++ b/.planning/phases/15-dashboard-tablos/15-DISCUSSION-LOG.md @@ -0,0 +1,110 @@ +# Phase 15: Dashboard & Tablos - 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-05-16 +**Phase:** 15-dashboard-tablos +**Areas discussed:** Sidebar nav items, Project card format, App layout strategy, Sidebar footer + +--- + +## Sidebar Nav Items + +| Option | Description | Selected | +|--------|-------------|----------| +| All items as links | Show all nav items — Chat, Planning, Tasks, etc. link to existing routes even if not yet visually restyled | ✓ | +| Working routes only | Show only Dashboard/Tablos in Phase 15, add others as restyled in phases 16-17 | | +| All items, non-working ones disabled | Show all but render non-implemented destinations as visual-only | | + +**Follow-up — which items specifically:** + +| Option | Description | Selected | +|--------|-------------|----------| +| Dashboard + Tablos + Planning + Chat | The 4 routes that exist in the backend today | | +| Match go-backend exactly | All 7+ items — Dashboard, Tablos, Tasks, Planning, Chat, Files, Settings | ✓ | +| Just Dashboard + Tablos | Minimal sidebar | | + +**Follow-up — non-implemented routes:** + +| Option | Description | Selected | +|--------|-------------|----------| +| Link to / (home) as placeholder | All items have an href, non-implemented ones go to dashboard | | +| Real hrefs where they exist, visual-only where not | Dashboard, Planning get real links; Tasks, Files, Settings render as non-clickable nav items | ✓ | + +**User's choice:** Match go-backend exactly for nav item set. Items with working routes get real hrefs; Tasks, Files, Settings (no standalone pages yet) render as visual-only. +**Notes:** Chat is per-tablo so it's Claude's discretion whether it appears in top nav or as visual-only. + +--- + +## Project Card Format + +| Option | Description | Selected | +|--------|-------------|----------| +| 3-column grid matching go-backend | Use .project-grid + .project-card CSS | ✓ | +| List layout instead | Vertical list, restyled with project-card visual | | + +**Follow-up — color avatar when null:** + +| Option | Description | Selected | +|--------|-------------|----------| +| Derive from title hash | Deterministic color from palette based on title string | | +| Default gray/neutral color | Fixed gray circle when color is null | ✓ | +| First letter on colored background | Initials-style avatar | | + +**Follow-up — card data:** + +| Option | Description | Selected | +|--------|-------------|----------| +| Match go-backend exactly | Avatar + title + creation date + edit icon + delete icon | ✓ | +| Avatar + title + description + actions | Description snippet instead of date | | +| Avatar + title + task count + actions | Open task count badge | | + +**User's choice:** 3-column grid, default gray avatar when color null, match go-backend card data exactly. + +--- + +## App Layout Strategy + +| Option | Description | Selected | +|--------|-------------|----------| +| Create new AppLayout templ, keep Layout for legacy | New `AppLayout(title, user, csrfToken, activePath, tablos)` for dashboard pages | ✓ | +| Update Layout in-place | Modify existing `Layout` to include sidebar and new params | | + +**Follow-up — active nav:** + +| Option | Description | Selected | +|--------|-------------|----------| +| Pass activePath string param to AppLayout | Handlers pass current route path explicitly | ✓ | +| Derive from request URL in a Go helper | Helper extracts active path from context | | + +**User's choice:** New `AppLayout` templ with explicit `activePath string` parameter. + +--- + +## Sidebar Footer + +| Option | Description | Selected | +|--------|-------------|----------| +| Email + logout button | Show user email with a logout button. Simpler. | | +| Match go-backend .sidebar-organization fully | Avatar circle (initial letter) + email + settings link | ✓ | +| No footer for Phase 15 | Keep footer minimal, defer | | + +**User's choice:** Full `.sidebar-organization` treatment — avatar circle with first initial + email + logout. Settings page doesn't exist yet, so no settings navigation. + +--- + +## Claude's Discretion + +- Exact SVG icons for each nav item (copy from go-backend dashboard_components.templ) +- Whether sidebar-projects section is a separate templ component or inline in AppLayout +- Exact neutral avatar fallback color +- Whether sidebar-footer avatar background derives from email hash or a fixed brand color +- Chat nav item behavior (visual-only vs placeholder href) + +## Deferred Ideas + +- Sidebar collapse toggle (JS interaction) — needs client-side persistence +- Mobile-responsive sidebar (hamburger / slide-in drawer) — Phase 15 desktop-first +- Tablo color picker in create/edit form — color field exists in DB, no UI to set it yet +- Tasks, Files, Settings standalone pages — nav items shown visual-only until built