continuous-integration/drone/push Build is passingDetails
Added debug logging to investigate sport variation dropdown issue:
- Log court data object on mount
- Log extracted sport_variation_id value
- Added visual disabled state (gray background) for locked dropdown
- Extracted initialSportVariationId to const for better debugging
This will help identify if:
1. Court data has sport_variation nested structure
2. sport_variation_id is being extracted correctly
3. Dropdown value is being set properly
Related: BUILD #21 sport variation display issue
continuous-integration/drone/push Build is passingDetails
Fixed two issues reported by user:
1. Slot definition duration validation error:
- Changed step from "15" to "1" on duration input
- HTML5 validation was failing because with min="1" and step="15",
valid values were 1, 16, 31, 46, 61, 76, 91... (not 90!)
- Now accepts any integer duration >= 1 minute
- Error "nearest 76 or 91" resolved
2. Sport variation not showing in court edit form:
- Updated Court type to include nested sport_variation structure
- Backend now returns full sport_variation object with sport details
- Updated CourtFormModal to extract sport_variation_id from nested
structure: court.sport_variation.sport_variation_id
- Added sport variation display in court list (e.g., "Padel - Indoor")
- Maintains backward compatibility with deprecated flat field
Changes:
- SlotDefinitionForm: step="1" instead of step="15"
- Court interface: added optional sport_variation nested object
- ClubCourtsTab: reads sport_variation_id from nested structure
- ClubCourtsTab: displays "Sport - Variation" in court list
Related: Backend Brooke nested sport_variation response structure
continuous-integration/drone/push Build is passingDetails
Court Sport Variation (BUILD:296-297 requirement):
- Added Sport and SportVariation types to courts.ts
- Created getSports() API client for GET /admin/sports
- Updated Court and CourtRequest types with sport_variation_id field
- Added sport variation dropdown to court creation modal
- Auto-selects first variation for new courts
- Sport type locked after creation (disabled in edit mode)
- Mock data updated with sport_variation_id values
Profile Bug Fix:
- Fixed click-to-edit crash when field values are empty/undefined
- Added null checks before calling .trim() in hasFieldValue() and EditableField
- Error: "Cannot read properties of undefined (reading 'trim')"
- Now safely handles empty string values
UI Details:
- Sport dropdown shows "Padel - Indoor", "Padel - Outdoor", etc.
- Loading spinner while fetching sports
- Validation error if no sport variation selected
- Form includes both name and sport_variation_id in POST request
Backend Brooke message: Court creation now requires sport_variation_id parameter
continuous-integration/drone/push Build is passingDetails
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