3 Commits (47dbb96c472f422e9ba86caa48ae4459476ab7d0)

Author SHA1 Message Date
Guillermo Pages 47dbb96c47 feat(admin): implement click-to-edit pattern for club profile fields
continuous-integration/drone/push Build is passing Details
UX Improvements:
- Fields with existing data display as read-only text (not inputs)
- Pencil icon appears on hover (right side of field)
- Click text or icon to convert to editable input
- Auto-blur closes edit mode when field has value
- Prevents accidental edits

Implementation:
- Created reusable EditableField component with pencil icon
- Applied to all optional fields: address (5 fields), contact (3 fields)
- Name and timezone use inline click-to-edit (no separate component)
- Edit state tracked per-field with Set<string>
- Form prefills with existing profile data from API

Visual Design:
- Hover: Border changes to slate-300, background to slate-50
- Pencil icon: slate-400, opacity 0→100 on hover
- Maintains existing validation error styling (red borders)
- Consistent with professional slate theme

User Request: "should not be an input directly (put a pen on the side as well as making the text clickable) and on click convert to input (prevents accidental edits)"
1 month ago
Guillermo Pages a61e64ded0 feat(admin): align UI with Backend Brooke Phase 2 contracts, flip mocks to real endpoints
continuous-integration/drone/push Build is passing Details
Phase 2 Integration Updates:
- Profile UI: Read/write address and contact fields from settings.address/settings.contact JSONB structure
- Court dependencies: Updated modal to show 3 counts (slot_definitions, slot_instances_future, slot_instances_booked)
- Error codes: Fixed duplicate court check to use court_name_duplicate (matches backend)
- Mock flags: Flipped all 9 USE_MOCKS flags to false (courts.ts x7, materialisation.ts x2)

Profile Tab (ClubProfileTab.tsx):
- Read address fields from profile.settings?.address?.line_1 etc.
- Read contact fields from profile.settings?.contact?.phone etc.
- Write to settings structure preserving existing settings
- Added Info icon tooltips: "Stored in settings until native fields ship"
- Removed Integration section (provider/remote_club_id not in API)

Court Dependencies Modal (ClubCourtsTab.tsx):
- Display slot_instances_future count (was upcoming_bookings)
- Display slot_instances_booked count (new field)
- Updated deletion instructions for 3-count structure

Types (courts.ts):
- Created ClubProfileSettings interface for JSONB structure
- Updated ClubProfile to use settings instead of flat fields
- Updated CourtDependencies with court_id + 3 dependency counts
- Updated ClubProfileUpdateRequest to support settings

API Clients:
- courts.ts: Updated mock data to match API contracts (settings structure, 3 counts, court_name_duplicate)
- materialisation.ts: Flipped USE_MOCKS to false for real backend integration

Integration Ready:
- All contract mismatches resolved
- Build succeeds
- Ready for Phase 1 smoke tests against BUILD:290-291

Related: Backend Brooke BUILD:290 (courts CRUD) + BUILD:291 (club profile PATCH)
Contract references: docs/owners/payloads/court-api-contract.md, club-profile-api-contract.md
1 month ago
Guillermo Pages 9a9c3a3b95 feat(admin): add court management UI with Profile/Courts tabs (Phase 2)
continuous-integration/drone/push Build is passing Details
Phase 2 implementation per Chief Cole approval (Chief_Cole-20251107103829)

Club Detail Page Restructure:
- Replaced single-view club detail with tabbed interface
- Three tabs: Profile, Courts, Slot Definitions (links to existing page)
- Tab navigation with active state highlighting
- Breadcrumb navigation maintained

Profile Tab (ClubProfileTab):
- Full club metadata editing form with sections:
  - Basic Information: name (required), timezone (required, IANA dropdown)
  - Location: address line 1/2, city, postal code, country (all optional)
  - Contact: phone, email (validated), website (validated) (all optional)
  - Integration: provider, remote club ID (read-only for Phase 2)
- Client-side validation: required fields, email format, URL format
- Server-side validation: maps backend errors to fields
- Success/error messaging with auto-hide success toast
- Cancel button resets form to original values
- Professional slate theme form styling

Courts Tab (ClubCourtsTab):
- Court list view with empty state
- Add/edit/delete actions per court
- Add Court modal: single field (name), duplicate name validation
- Edit Court modal: pre-populated, same validation
- Delete with cascade blocking:
  - Dependency check before delete (slot definitions, upcoming bookings)
  - Blocking modal shows dependency counts with resolution steps
  - Confirmation modal for clean delete (no dependencies)
- In-memory mock data management (3 courts default)
- Court 1 has mock dependencies (12 slot defs, 45 bookings) for testing

Modal Components:
- CourtFormModal: Add/edit with field-level validation
- DeleteConfirmationModal: Confirm before deletion
- DependenciesBlockingModal: Shows why delete is blocked + resolution steps

All components use professional slate theme
All modals use backdrop blur + center positioning
All forms have loading states + error handling
Build tested and passed (npm run build successful)

Total new lines: ~1400 across 3 components
Ready for mock-driven testing while Backend Brooke builds APIs
1 month ago