Commit graph

156 commits

Author SHA1 Message Date
Arthur Belleville
5d0c201e86
Some work
Some checks failed
backend-ci / Backend tests (pull_request) Failing after 53s
backend-ci / Backend tests (push) Failing after 1s
2026-05-23 17:26:01 +02:00
Arthur Belleville
eaaec7a89d
style(planning): implement Month/Week/Day calendar views from sketch 005
Some checks are pending
xtablo-ci / Checks (pull_request) Waiting to run
go-backend-ci / Check go-backend (pull_request) Waiting to run
- Replace 14-day agenda list with three-view calendar (month/week/day)
- Add PlanningCalendar, CalendarDay, CalendarTimeEvent, MiniCalDay data structs
- Add BuildMonthCalendar, BuildWeekCalendar, BuildDayCalendar builder helpers
- Add MondayOf, PlanningMonthURL, PlanningWeekURL, PlanningDayURL URL helpers
- Handler now parses ?view=month|week|day with matching date params
- Month view: 7-col grid with event chips using tablo color via color-mix()
- Week/Day view: split layout with mini-month panel and hour timeline (07-20)
- Timeline events positioned via TopPx/HeightPx from start_time microseconds
- Append all calendar CSS to app.css (view-toggle, cal-grid, tl-* classes)
2026-05-18 16:56:44 +02:00
Arthur Belleville
63e7d65290
feat(phase-20): port tablo detail restyle to backend/
Phase 20 work was executed against go-backend/ (prototype) instead of
backend/ (production). This commit ports the Figma-aligned restyle to
the correct codebase.

Changes:
- tablos.templ: replace project-card-top header with tablo-detail-header,
  tablo-detail-avatar, tablo-detail-title; update tab bar to tablo-tab-bar;
  localise tab labels to French (Vue d'ensemble, Tâches, Fichiers,
  Discussion, Événements)
- tasks.templ: update KanbanBoard to tablo-kanban-board; KanbanColumn to
  tablo-kanban-column with new header/count/empty classes; TaskCard to
  card-style layout (task-card-top-row, task-card-title, task-card-delete)
- app.css: add sections 25–27 — tablo detail page, kanban board/columns,
  and task card (card appearance, hover states)

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-18 16:31:05 +02:00
Arthur Belleville
6b73c78d9d
fix(19): update stale dashboard tests — new view/filter/status class names
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-17 22:29:06 +02:00
Arthur Belleville
a575ab93c6
feat(19): list view as proper table — Projet/Statut/Créé le/Progression/Actions
- Two separate containers: #tablos-grid (card grid) and #tablos-table (table), toggled via .hidden
- TabloListRow: new templ for <tr> with icon+title, Actif/Archivé badge, date, progress bar, trash
- JS: setTablosView toggles hidden on both containers; filterTablos targets both article and tr elements
- Remove old .tablo-list-row / #tablos-list[data-view] CSS (no longer needed)

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-17 22:24:45 +02:00
Arthur Belleville
3a864aa84e
feat(19): revamp tablos page — filter tabs, view toggle, card click nav
- Dashboard: French header "Mes Projets", underline-tab view toggle (grid/list), filter tabs (Tous/Pas commencé/En cours/Terminé) with JS client-side filtering
- Cards: display status derived from progress (À faire/En cours/Terminé), rounded-xl p-6, w-8 h-8 avatar, green-500 progress bar, dashed "Créé le" footer
- Click on card/row navigates to /tablos/{uuid} via event delegation (delete zone stops propagation)
- List view: single-column grid, rows show status + title + date + task count
- CSS: .view-tab and .filter-tab with .is-active state

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-17 22:11:31 +02:00
Arthur Belleville
7388418aed
feat(19): restyle tablo cards to production design with X/Y task count
- TabloCardView gains DoneTasks/TotalTasks int fields; handler stores raw counts alongside Progress %
- TabloProjectCard: rounded-2xl card, border-[#EAECF0], purple-50 status badge, colored avatar initial (12x12 rounded-xl), calendar date row, Progression label + X/Y task count + purple-500 progress bar
- List row: matching pill badge + X/Y count
- All 7 TestTablosDashboard_* tests pass

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-17 17:00:51 +02:00
Arthur Belleville
161437828e
test(19-03): add LIST-01/02/03 test coverage for dashboard
- TestTablosDashboard_ProgressBar: asserts "Progression:" label and project-card-progress-row class
- TestTablosDashboard_ViewToggle: asserts view-toggle-btn class and data-view="grid" attribute
- TestTablosDashboard_StatusBadge: asserts "Active" badge and tablo-list-row dual-element structure
- All tests use unique email addresses; go build ./... exits 0
2026-05-17 16:33:36 +02:00
Arthur Belleville
3deb4f9595
feat(19-03): add view toggle button to TablosDashboard
- Add plain <button class="view-toggle-btn"> with inline SVG list icon and onclick JS
- data-view="grid" static attribute added to #tablos-list container
- .view-toggle-btn CSS block added to app.css (Section 20c)
- Tailwind CSS rebuilt to include view-toggle-btn class
- templ generate + go build exit 0
2026-05-17 16:33:02 +02:00
Arthur Belleville
2b786e2014
feat(19-02): add progress-row and list-row CSS, rebuild Tailwind
- Added Section 20b to app.css: .project-card-progress-row, .project-card-progress-label
- Added .project-card-progress-bar (uses var(--color-accent) instead of --project-color)
- Added .tablo-card-wrapper (display:contents) for transparent grid wrapper
- Added .tablo-list-row (hidden by default), .tablo-list-row-title, .tablo-list-row-meta
- Added [data-view="list"] toggle rules for #tablos-list container
- Rebuilt static/tailwind.css with tailwindcss CLI
2026-05-17 16:30:56 +02:00
Arthur Belleville
47ba2f1797
feat(19-01): enrich TabloCardView with Progress field and wire batch progress query
- Add Progress int field to TabloCardView (D-05)
- Map row.Status into Tablo struct in TabloCardsFromUnreadRows
- Wire ListTabloProgressByIDs batch query in TablosListHandler (no N+1)
- Non-fatal error handling: progress defaults to 0 on query failure
2026-05-17 16:28:15 +02:00
Arthur Belleville
c1928e312f
feat(19-01): add tablo status column, batch progress query, and sqlc regen
- Add migration 0010_tablo_status.sql with reversible goose Up/Down
- Update all tablo SQL queries to include status column in SELECT/RETURNING/GROUP BY
- Add ListTabloProgressByIDs batch aggregation query (D-06)
- sqlc regenerated locally (files gitignored — regen via sqlc generate)
2026-05-17 16:27:30 +02:00
Arthur Belleville
9ba650b345
feat(18): restyle sidebar and header to match production design
- Sidebar: Tailwind utilities, French labels (Aperçu/Tâches/Projets/Planning/Discussions/Fichiers), hr separators, collapse button on group hover, tablo list with circle icons, org footer with avatar + "1 membre"
- Header: 75px height, border-b #EAECF0, search input left, bell + avatar-dropdown right (no breadcrumb visible — retained sr-only for a11y + tests)
- Layout: flex instead of grid, dashboard-main no padding, dashboard-main-content wrapper at 2rem
- Tests updated for new search-input assertion

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-17 16:00:26 +02:00
Arthur Belleville
9a70553cb0
feat(18-03): add page-header CSS, /settings stub route, and header tests
- Add page-header, breadcrumb, header-search-placeholder, header-icon-button, header-avatar-menu, header-avatar-dropdown CSS rules to app.css
- Regenerate tailwind.css with new page-header and avatar dropdown classes
- Add GET /settings stub route returning 200 with "Coming soon" content (D-06)
- Add page-header and breadcrumb assertions to TestTablosDashboard_Sidebar
- Add new TestTablosDashboard_Header test asserting page-header, header-avatar-menu, Dashboard breadcrumb, header-search-placeholder
2026-05-17 15:34:58 +02:00
Arthur Belleville
8a91183639
feat(18-02): add sidebar collapsed-state CSS rules and regenerate tailwind.css
- Add .dashboard-shell.sidebar-is-collapsed grid-template-columns: 4rem 1fr
- Hide sidebar-brand-title, section labels, nav labels, project labels when collapsed
- Center icons in collapsed state via justify-content: center on sidebar-nav-link-inner
- Hide sidebar-project-list in collapsed state (no icons for project entries)
- Flip collapse button chevron with rotate(180deg) when collapsed
- Regenerate static/tailwind.css via bin/tailwindcss --minify
2026-05-17 15:30:42 +02:00
Arthur Belleville
59f143aecb
feat(18-01): update all handler call sites with per-page breadcrumbs
- handlers_tablos.go: TablosListHandler, renderTabloCreateError, TabloDetailHandler, TabloUpdateHandler
- handlers_planning.go: PlanningPageHandler
- handlers_account.go: AccountProvidersHandler
- handlers_discussion.go: TabloDiscussionTabHandler
- handlers_files.go: TabloFilesTabHandler, TabloTasksTabHandler
- handlers_events.go: TabloEventsTabHandler
- go build ./... succeeds, go test ./... passes
2026-05-17 15:27:38 +02:00
Arthur Belleville
3d5d9a05ea
feat(17): cap discussion height at 32rem with auto-scroll to latest message
- #discussion-messages: max-height 32rem, overflow-y auto, smooth scroll
- Auto-scroll to bottom on initial load, on own message sent (htmx:afterRequest),
  and on SSE message received from other users

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-17 12:58:26 +02:00
Arthur Belleville
681c094b0c
fix(17): skip own-user SSE messages in JS to eliminate left-then-right flash
The server-side flush didn't eliminate the race because browser HTMX and SSE
event processing are inherently async.

Real fix: embed data-current-user-id on #discussion-tab (from DiscussionTabData.
CurrentUserID). The SSE handler now skips any event whose authorUserId matches
the current user — those messages are always delivered via HTMX (IsOwn=true,
right-aligned). SSE only appends messages from other users.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-17 12:47:21 +02:00
Arthur Belleville
96a58ef0ea
fix(17): flush HTTP response before SSE publish to fix own-message alignment race
The server was publishing to the SSE broker before writing the HTMX response,
causing a race: if the SSE event (IsOwn=false, left-aligned) arrived at the
browser before HTMX appended the response (IsOwn=true, right-aligned), the
SSE path won and messageExists() then blocked the correct HTMX append.

Fix: write and flush the HTMX response first, then publish to SSE. This ensures
the sender's own message lands in the DOM right-aligned before the SSE event fires.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-17 12:26:13 +02:00
Arthur Belleville
30256895b2
fix(17): address all code review findings
- CR-01: add id="discussion-message-list" to .divide-y; change hx-target
  to #discussion-message-list so HTMX appends inside the list, not after it.
  Always render the list div so the target exists even when messages is empty.
- WR-01: SSE broadcast now renders IsOwn=false for all recipients so other
  users don't receive the sender's right-aligned bubble
- WR-02: add HX-Retarget/HX-Reswap headers on 422 and 500 error responses
  so validation errors reach the composer form in the DOM
- WR-03: replace hardcoded rgba(128,78,236,0.10) with color-mix() using
  the --color-brand-primary token
- WR-04: remove hardcoded "1 participant" subtitle (no participant count in data)
- IN-02: DiscussionMessageFromRow now accepts currentUserID uuid.UUID (matching
  DiscussionMessagesFromRows) instead of a pre-computed bool

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-17 12:23:21 +02:00
Arthur Belleville
bc3d8e6355
fix(17): return TabloOverviewTabFragment on HX-Request for overview tab
TabloDetailHandler was always rendering the full page regardless of
HX-Request, causing HTMX to swap the entire layout (sidebar, header)
into #tab-content instead of just the overview fragment.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-17 10:24:39 +02:00
Arthur Belleville
d8e52f695b
fix(17): own messages right-aligned; restore .divide-y for SSE compatibility
- Add IsOwn bool to DiscussionMessageView; set via user.ID comparison in
  DiscussionMessagesFromRows and DiscussionMessageFromRow
- Thread currentUserID through loadDiscussionTabData and all call sites
- discussion.templ: branch message-own vs message-other on message.IsOwn
- Restore .divide-y wrapper inside #discussion-messages (discussion-sse.js
  depends on it to locate the message list before appending SSE events)

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-17 10:22:23 +02:00
Arthur Belleville
56194cfdb5
feat(17): restyle discussion view and planning page in backend/
- discussion.templ: #discussion-messages uses .ui-card; DiscussionMessageRow
  uses .message-row/.message-other/.message-bubble/.message-meta classes;
  day separator gets data-day-separator attribute
- planning.templ: wraps content in .overview-section; heading uses
  .overview-section-heading with h1; empty state uses .ui-card
- app.css: add Section 26 .message-* bubble classes; extend
  .overview-section-heading selector to include h1

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-17 10:01:24 +02:00
Arthur Belleville
18a705c812
fix(16): restore task-drag-handle for Sortable.js drag-and-drop
Phase 16 executor removed the .task-drag-handle div from TaskCard
during restyling. Sortable.js handle: '.task-drag-handle' had no
matching element → dragging completely non-functional.

Restores the grip element with CSS-token styling (no Tailwind).
2026-05-16 23:58:51 +02:00
Arthur Belleville
e2ee4349f8
feat(16-03): update all three KanbanBoard call sites to pass etapes
- tablos.templ TasksTabFragment: add etapes as 5th argument to @KanbanBoard
- handlers_tasks.go reorder (single): capture etapes from loadTasksTabData; pass to KanbanBoard
- handlers_tasks.go reorder (batch): capture etapes from loadTasksTabData; pass to KanbanBoard
- go build ./backend/... exits 0; go test ./backend/internal/web/... -count=1 passes
2026-05-16 23:42:46 +02:00
Arthur Belleville
44209b9db2
feat(16-01): append CSS Sections 19-25 to app.css
- Section 19: tasks-section block (task-row, task-check, task-body, task-meta, tasks-add-button)
- Section 20: project-progress-track and project-progress-bar
- Section 21: tab-nav, tab-nav-item, tab-nav-item.is-active, tab-nav-item:hover
- Section 22: tablo-metadata-row, tablo-metadata-date
- Section 23: kanban-column wrapper (width: 18rem) + scoped h3 override (1rem)
- Section 24: etape-group-header, etape-group-color-dot, etape-group-label
- Section 25: task-list-empty placeholder
- all values use var(--...) tokens; zero hardcoded hex values
2026-05-16 23:32:57 +02:00
Arthur Belleville
a1a3ea8239
feat(16-01): add download and chat icon cases to UIIcon switch
- insert case "download" with arrow-down SVG (path + polyline + line) before default case
- insert case "chat" with speech-bubble SVG (path) before default case
- icon_button_templ.go regenerated via templ generate (gitignored, regenerated at build time)
2026-05-16 23:31:58 +02:00
Arthur Belleville
c7a16dbcae
feat(15-03): wire AppLayout into all authenticated handlers and templates
- TablosListHandler: derives sidebarTablos from cardViews, calls TablosDashboard with activePath="/"
- TabloDetailHandler: fetches ListTablosByUser for sidebar, calls TabloDetailPage with activePath=""
- TabloUpdateHandler: fetches ListTablosByUser for non-HTMX error path
- renderTabloCreateError: derives errorSidebarTablos from errorCardViews
- TabloDiscussionTabHandler, TabloEventsTabHandler, TabloFilesTabHandler, TabloTasksTabHandler: fetch ListTablosByUser for non-HTMX full-page renders
- PlanningPageHandler: fetches ListTablosByUser, calls PlanningPage with activePath="/planning"
- AccountProvidersHandler: fetches ListTablosByUser, calls AccountProvidersPage with activePath="/"
- planning.templ: updated signature + switched to @AppLayout
- account_providers.templ: updated signature + switched to @AppLayout
2026-05-16 21:49:23 +02:00
Arthur Belleville
f533d53c74
feat(15-02): port sidebar + project-card CSS into app.css and register in tailwind
- Create backend/internal/web/ui/app.css with dashboard shell, sidebar, and project-card CSS ported verbatim from go-backend
- All color values use var(--...) design tokens — no hex colors
- Add @import "./internal/web/ui/app.css" to backend/tailwind.input.css
2026-05-16 21:41:58 +02:00
Arthur Belleville
7bea525c1b
test(15-01): add Wave 0 RED test stubs for DASH-01, DASH-02, DASH-03
- TestTablosDashboard_Sidebar: asserts dashboard-sidebar + sidebar-nav-shell in GET / body
- TestTablosDashboard_ProjectCards: asserts project-card in GET / body with a pre-inserted tablo
- TestTablosDashboard_EmptyState: asserts ui-empty-state in GET / body with zero tablos
- All three skip without TEST_DATABASE_URL; compile cleanly; existing TestTablos* tests unaffected
2026-05-16 21:38:50 +02:00
Arthur Belleville
dcbc05b642
test(14): add Nyquist validation tests for AUTH-UI-01/02/03
auth_login_test.go: LoginPage renders AuthLayout structure (login-screen,
auth-card-shell, brand-logo, h1, auth-body, divider-pill), HTMX form
attributes, password not echoed.

auth_components_test.go: AnimatedBackground exactly 35 elements,
GoogleButton configured/unconfigured variants, AuthDivider or-pill.

handlers_auth_test.go: extend configured provider tests to assert
class="gsi-material-button" on the anchor element (AUTH-UI-03).

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-16 20:43:31 +02:00
Arthur Belleville
70fe3848fb
fix(14-02): shrink Google button to content width
width: auto on a block element still fills the parent. Use width: max-content
so the button wraps its icon + label + padding only. Remove flex-grow: 1 on
the label span so it doesn't stretch within the now-natural-width button.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-16 19:24:10 +02:00
Arthur Belleville
6a58b2970a
fix(14-02): shrink Google button to natural width per Google spec
Google's gsi-material-button uses width: auto, not 100%. Replace width: 100%
/ max-width: 400px with width: auto + margin: 0 auto so the button sizes to
its content (icon + label + padding) and stays centered in the card.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-16 19:21:41 +02:00
Arthur Belleville
4624fb305a
fix(14-02): load Roboto font and fix Google button SVG icon sizing
Per Google's branding guidelines, the gsi-material-button requires Roboto
Medium. Add Google Fonts preconnect + stylesheet link to AuthLayout head.
Also add display:block + 100% dimensions to the SVG inside the icon
container to prevent inline baseline gaps.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-16 19:18:58 +02:00
Arthur Belleville
808eaecc85
feat(14-02): migrate auth_login.templ to AuthLayout with ui.FormField inputs
- Replace Layout+Card pattern with AuthLayout("Sign in to Xtablo", csrfToken)
- Wire GoogleButton and AuthDivider into LoginPage body
- Replace raw <input> elements with @ui.FormField/@ui.Input design system components
- Add signup-copy nav link ("Don't have an account? Sign up")
- Preserve HTMX swap: hx-post="/login" hx-target="#login-form" hx-swap="outerHTML"
- Remove loginCardBody, AuthProviderButtonsBlock, AuthProviderButtonControl helpers
- Update test assertions for new GoogleButton labels ("Sign in with Google" / disabled attr)
2026-05-16 19:10:08 +02:00
Arthur Belleville
cf116ff696
feat(14-01): copy logo assets and replace auth.css with full auth card + animation CSS
- Copy logo_dark.png and logo_white.png from go-backend/static into backend/static
- Replace minimal 62-line auth.css with 828-line extraction from go-backend/static/styles.css
- Sections: login-screen shell, animated background (bg-01..35, size/opacity utilities), card wrapper, card internals, gsi-material-button, legacy auth-provider controls, 66 keyframe definitions, animate-* utility classes
- Added display:block and text-decoration:none to .gsi-material-button for the anchor variant
- Does NOT include .app-shell or .dashboard-shell rules
2026-05-16 19:04:44 +02:00
Arthur Belleville
caba6c15ee
fix(13-05): icon-button hover changes icon color only, no background fill 2026-05-16 18:02:37 +02:00
Arthur Belleville
d2c5a0cc07
fix(13-05): add tone-aware hover colors to icon-button (danger/warning/success/neutral) 2026-05-16 17:59:17 +02:00
Arthur Belleville
cae5e7c785
fix(13-05): wire /static/tailwind.css into catalog page head 2026-05-16 14:17:46 +02:00
Arthur Belleville
4046783fd4
feat(13-05): create catalog package with route files and router wiring
- Add backend/internal/web/ui/catalog/catalog.templ: single-page layout
  with 240px sidebar nav (11 anchor links) and 11 component sections with
  section headings matching DS-XX requirement IDs
- Add backend/internal/web/ui/catalog/examples.go: Example struct + typed
  example functions for all 11 component types (badge/button/card/empty-state/
  form-field/icon-button/input/modal/select/table/textarea); modal renders
  panel-only (no backdrop wrapper, Pitfall 7)
- Add backend/internal/web/catalog_route_catalog.go (//go:build catalog):
  RegisterCatalogRoute mounts GET /ui-catalog via catalogPageHandler()
- Add backend/internal/web/catalog_route_stub.go (//go:build !catalog):
  no-op RegisterCatalogRoute for production builds
- Wire RegisterCatalogRoute(r) unconditionally in NewRouter after protected routes
- Add justfile catalog target: just generate + go run -tags catalog ./cmd/web
- go build ./... and go build -tags catalog ./... both pass; go test ./... green
2026-05-16 14:13:30 +02:00
Arthur Belleville
c80ebcb9b1
feat(13-04): port icon-button/space components; wire UIIcon into button.templ; update tailwind.input.css (GREEN)
- icon-button.css + icon_button.templ: UIIcon switch (plus/grid3x3/list/filter/search/calendar/pencil/trash + fallback span)
- spacing.css + space.templ: SpaceX/SpaceY with SpacingStep classes
- button.templ: wire @UIIcon(props.Icon) replacing Plan 02 placeholder comment
- tailwind.input.css: add modal, empty-state, table, icon-button, form-field, spacing imports (14 total)
- All 7 new tests pass; full go test ./... green
2026-05-16 14:07:07 +02:00
Arthur Belleville
fa2405938a
test(13-04): add failing tests for IconButton, UIIcon, Space, and Button icon wiring (RED) 2026-05-16 14:05:44 +02:00
Arthur Belleville
fbdf188f5f
feat(13-04): port modal, empty-state, table components with CSS and templ (GREEN)
- modal.css + modal.templ: backdrop/panel structure, Title/Body/Actions props
- empty-state.css + empty_state.templ: dashed border, nil-guarded Icon/Action
- table.css + table.templ: ui-table-shell wrapper, Head/Body typed props
- All 6 TestModal/TestEmptyState/TestTable tests pass; full suite green
2026-05-16 14:05:11 +02:00
Arthur Belleville
4bdb78debf
test(13-04): add failing tests for Modal, EmptyState, Table components (RED) 2026-05-16 14:04:19 +02:00
Arthur Belleville
52fb77d4f8
feat(13-03): port select + form-field components with CSS and helpers (GREEN)
- select_helpers.go: 9 helper functions verbatim from go-backend
- select.templ: SelectProps/SelectOption structs, inline JS with __uiSelectInitAll
  and htmx:afterSwap re-init listener (Pitfall 6)
- select.css: .ui-select-control (min-height 44px), .ui-select-menu (max-height 16rem)
- form_field.templ: FormFieldProps with Label/For/Field/Error/Hint; conditional regions
- form-field.css: .ui-form-field/.ui-form-label/.ui-form-hint/.ui-form-error
- tailwind.input.css: add @import for select.css and form-field.css
- All 6 TestSelect/TestFormField tests passing; full go test ./... is green
2026-05-16 14:00:51 +02:00
Arthur Belleville
50e3fb0021
test(13-03): add failing tests for Select and FormField components (RED)
- TestSelect_RendersControl: expects ui-select-control in output
- TestSelect_HasInlineScript: expects __uiSelectInitAll in script block
- TestSelect_HasHtmxListener: expects htmx:afterSwap re-init listener
- TestFormField_RendersLabel: expects ui-form-field and ui-form-label
- TestFormField_RendersError: expects ui-form-error when Error is set
- TestFormField_NoErrorWhenEmpty: expects no ui-form-error when Error is empty
2026-05-16 13:59:21 +02:00
Arthur Belleville
9556b20ade
feat(13-03): port input.templ/input.css and textarea.templ/textarea.css (GREEN)
- input.css: .ui-input with min-height 44px, border-radius 0.75rem, focus ring
- input.templ: InputProps with ID/Name/Type/Placeholder/Value/Disabled/Required/Attrs
- textarea.css: .ui-textarea with min-height 7rem, resize vertical, focus ring
- textarea.templ: TextareaProps with ID/Name/Value/Placeholder/Rows/Disabled/Required/Attrs
- tailwind.input.css: add @import for input.css and textarea.css
- All 7 TestInput/TestTextarea tests passing
2026-05-16 13:59:03 +02:00
Arthur Belleville
ace9f5bdc4
test(13-03): add failing tests for Input and Textarea components (RED)
- TestInput_DefaultType: expects type="text" for empty Type
- TestInput_EmailType: expects type="email" for explicit Type
- TestInput_IDFallback: expects id from Name when no ID set
- TestInput_ExplicitID: expects explicit ID to take precedence
- TestTextarea_RendersClass: expects class="ui-textarea"
- TestTextarea_DefaultRows: expects rows="4" for zero Rows
- TestTextarea_ExplicitRows: expects rows="6" for explicit Rows
2026-05-16 13:58:19 +02:00
Arthur Belleville
a30a6f9088
feat(13-02): replace CSS files, migrate card.templ to typed API, update all template hardcodes
- button.css: replaced with go-backend multi-class selector version + ghost variant rules
- badge.css: replaced with go-backend pill-shape version + primary variant
- card.css: replaced with go-backend token-based header/body/footer version
- card.templ: migrated from children passthrough to typed CardProps{Header/Body/Footer}
- ui_test.go: rewrote TestCard_RendersChildren -> TestCard_RendersTypedRegions; added TestBadge_PrimaryVariant; added textComponent helper + io import
- auth_login.templ, auth_signup.templ: migrated Card usage to typed CardProps API
- tablos.templ: migrated TabloCard to typed CardProps API with extracted tabloCardBody
- planning.templ, tasks.templ, events.templ, etapes.templ: all compound button class strings updated to multi-class pattern
- go test ./... passes (all packages green)
- just generate succeeds
2026-05-16 13:55:30 +02:00
Arthur Belleville
66f23bba77
feat(13-02): multi-class ButtonClass() + Icon field + buttonType helper in button.templ
- ButtonClass() now emits "ui-button ui-button-solid ui-button-default ui-button-md"
- Ghost variant special case: "ui-button ui-button-ghost ui-button-md" (tone omitted)
- button.templ: added Icon string field to ButtonProps, replaced inline btnType with buttonType() helper
- ui_test.go: updated TestButton_DefaultSolidMD to multi-class slice assertions
- ui_test.go: updated TestButtonClass_String and TestButtonClass_GhostVariant expectations
- All 18 ui package tests pass
2026-05-16 13:52:01 +02:00