# Session Handoff - January 3, 2026

## Current Status

### ✅ Completed This Session (January 3, 2026 - Evening)
1. **Schedule Grid Unification** - Unified layout across admin Schedule Builder and public Schedule/My Schedule views
2. **ScheduleGridBuilder Service** - Created shared rendering service with three modes (admin/public/my_schedule)
3. **Phase 1: Schedule Builder Display** - Time/Date headers per slot, Field labels with rowspan, home/away rows
4. **Phase 2: Shared Rendering** - Extracted grid logic to service, created shared CSS
5. **Phase 3: Public Schedule Update** - Updated to use shared service, added /my-schedule route
6. **Navigation Persistence** - Fixed position retention when dragging from workbench
7. **Removed "Fill Empty Slots"** - Simplified to only "Generate New Schedule" button

### ✅ Completed This Session (January 3, 2026 - Morning)
1. **Teams Page Redesign** - Pill-style season tabs, responsive grid, player sorting, user highlighting
2. **Schedule Page Redesign** - Horizontal grid layout matching schedule builder design
3. **Schedule Navigation** - Prev/Next buttons for week navigation
4. **Pill Tab Caching Fix** - Disabled page caching on Teams and Schedule pages
5. **Future Weeks Padding** - Added 10 weeks of "No games" columns after last game

### ✅ Completed Previous Session (January 2, 2026)
1. **Season Entity Boolean Fields Fix** - Removed `setRequired(TRUE)` from visibility checkboxes
2. **Registration Page Filtering** - Only shows seasons with `registration_visible = TRUE`
3. **Menu Cache Invalidation** - Season changes now take effect immediately
4. **Menu Sort Order Fix** - Seasons display in correct `start_date DESC` order
5. **Season View Page** - Built comprehensive admin view page for seasons
6. **Menu Cleanup** - Removed redundant "Add Season" and "Add Tournament" links
7. **Dev Banner Repositioned** - Moved from page_top to admin toolbar integration

---

## Schedule Grid Unification ✅ (NEW)

### Overview
Unified the schedule grid layout across three views:
- **Admin Schedule Builder** (`/admin/ccsoccer/season/{id}/schedule`) - With drag-drop
- **Public Schedule** (`/schedule`) - View all games, highlights user's team
- **My Schedule** (`/my-schedule`) - Only shows logged-in user's games

### Visual Layout (All Views)
```
┌─────────┬─────────┬─────────┬─────────┬─────────┐
│ 6:00 PM │  JAN 6  │  JAN 13 │  JAN 20 │  JAN 27 │  ← Time/Date header row
├─────────┼─────────┼─────────┼─────────┼─────────┤
│         │ Galaxy  │ Quakes⚽│ Dynamo  │ Rapids  │  ← Home team (pink)
│ Field 1 ├─────────┼─────────┼─────────┼─────────┤
│         │Sounders │  Dash   │  Pride  │Sporting │  ← Away team (white)
├─────────┼─────────┼─────────┼─────────┼─────────┤
│         │ Dynamo  │Red Stars│ Galaxy  │  Dash   │
│ Field 2 ├─────────┼─────────┼─────────┼─────────┤
│         │Redbulls │  Fire   │ Rapids  │Angel City│
├─────────┼─────────┼─────────┼─────────┼─────────┤  ← Dark spacer between slots
│ 7:00 PM │  JAN 6  │  JAN 13 │  JAN 20 │  JAN 27 │  ← Next time slot header
└─────────┴─────────┴─────────┴─────────┴─────────┘
```

### Key Features
- **Time/Date header row** repeats at start of each time slot section
- **Field labels** in left column with `rowspan="2"` spanning home+away rows
- **Home team row** has pink background (`#f8d7da`)
- **Away team row** has white background
- **Dark spacer** (4px) between time slot sections
- **⚽ soccer ball icon** next to user's team (logged-in users)
- **"No games"** displayed in bye weeks and future weeks
- **Prev/Next navigation** with auto-scroll to current week

---

## ScheduleGridBuilder Service ✅ (NEW)

**File:** `src/Service/ScheduleGridBuilder.php`

### Service Registration
```yaml
# ccsoccer.services.yml
ccsoccer.schedule_grid_builder:
  class: Drupal\ccsoccer\Service\ScheduleGridBuilder
  arguments: ['@entity_type.manager']
```

### Mode Constants
```php
const MODE_ADMIN = 'admin';       // Drag-drop enabled
const MODE_PUBLIC = 'public';     // View all games, highlight user's team
const MODE_MY_SCHEDULE = 'my_schedule';  // Only user's games shown
```

### Public Methods
| Method | Purpose |
|--------|---------|
| `buildGrid($scheduleState, $allWeeks, $options)` | Main grid HTML generation |
| `calculateAllWeeks($season, $scheduleState)` | Get all weeks including bye/future |
| `calculateCurrentWeekIndex($allWeeks)` | Find current week for auto-scroll |
| `getUserTeamIds($userId)` | Get team IDs for user highlighting |

### Options Array
```php
$options = [
  'mode' => ScheduleGridBuilder::MODE_PUBLIC,
  'user_team_ids' => [123 => TRUE, 456 => TRUE],  // Keys are team IDs
  'season_id' => 99,
  'season_name' => 'Coed Winter 2026',
  'current_week_index' => 5,
  'enable_drag_drop' => FALSE,  // Auto-set based on mode
];
```

---

## Files Created/Modified (Evening Session)

### New Files
| File | Purpose |
|------|---------|
| `src/Service/ScheduleGridBuilder.php` | Shared grid rendering service |
| `css/schedule-grid.css` | Shared grid CSS (navigation, table, colors) |

### Modified Files
| File | Changes |
|------|---------|
| `src/Controller/ContentController.php` | Use ScheduleGridBuilder, add mySchedulePage() |
| `src/Form/ScheduleBuilderForm.php` | Remove "Fill Empty Slots" button |
| `js/schedule-navigation.js` | Updated selectors for `.date-header-cell` |
| `js/schedule-builder.js` | Added navigation persistence on workbench drag |
| `css/schedule-builder.css` | Trimmed to admin-only styles |
| `ccsoccer.routing.yml` | Added `/my-schedule` route |
| `ccsoccer.services.yml` | Added schedule_grid_builder service |
| `ccsoccer.libraries.yml` | Added schedule-grid library |

---

## Routes

### Public Schedule Routes
| Route | Path | Access | Description |
|-------|------|--------|-------------|
| `ccsoccer.schedule_all` | `/schedule` | Public | All games, highlights user's team |
| `ccsoccer.my_schedule_all` | `/my-schedule` | Logged in | Only user's games |
| `ccsoccer.schedule_ical` | `/schedule/{season}/ical` | Public | iCal export |
| `ccsoccer.schedule_pdf` | `/schedule/{season}/pdf` | Public | PDF export |

### Admin Schedule Routes
| Route | Path | Access | Description |
|-------|------|--------|-------------|
| `ccsoccer.schedule_builder` | `/admin/ccsoccer/season/{season}/schedule` | Admin | Schedule Builder form |

---

## CSS Architecture

### Library Dependencies
```yaml
# Schedule Builder (admin) uses both:
schedule-builder:
  css:
    theme:
      css/schedule-grid.css: {}      # Shared styles
      css/schedule-builder.css: {}   # Admin-only (drag-drop, workbench)

# Public Schedule uses:
schedule-grid:
  css:
    theme:
      css/schedule-grid.css: {}      # Shared styles
  js:
    js/schedule-navigation.js: {}
```

### CSS Class Summary
| Class | Purpose |
|-------|---------|
| `.schedule-grid` | Main container |
| `.grid-scroll-container` | Overflow hidden wrapper |
| `.schedule-table` | The table element |
| `.time-date-row` | Row with time + date headers |
| `.time-header-cell` | Left column time (dark red) |
| `.date-header-cell` | Date column headers (grey) |
| `.field-label-cell` | Left column field label (green) |
| `.game-cell.home-team` | Home team cell (pink) |
| `.game-cell.away-team` | Away team cell (white) |
| `.slot-spacer` | Dark gap between time slots |
| `.team-name.draggable` | Admin drag-drop styling |
| `.user-team-icon` | Soccer ball (⚽) icon |

---

## Navigation Persistence Fix ✅

### Problem
When dragging a team from workbench to a game cell in later weeks (e.g., MAR 24), the page would reload and reset to the default position (JAN 6 visible).

### Solution
Store navigation offset in `sessionStorage` before reload, restore on init.

### Implementation (schedule-builder.js)
```javascript
// Before reload (in handleDropOnCell):
sessionStorage.setItem('scheduleBuilderOffset_' + config.seasonId, state.offset.toString());

// On init (in initScheduleGrid):
const savedOffset = sessionStorage.getItem('scheduleBuilderOffset_' + config.seasonId);
if (savedOffset !== null) {
  state.offset = parseInt(savedOffset, 10);
  sessionStorage.removeItem('scheduleBuilderOffset_' + config.seasonId);
}
```

---

## "Fill Empty Slots" Removal ✅

Removed the "Fill Empty Slots" button from Schedule Builder. Now only "Generate New Schedule" is available.

### Files Changed
- `src/Form/ScheduleBuilderForm.php`
  - Removed `$form['actions']['fill']` definition
  - Removed `fillEmptySubmit()` method

---

## Teams Page Redesign ✅

**Route:** `/teams` (authenticated users only)

### Features Implemented:
- **Pill-style season tabs** - Switch between Coed and Men's 35+ leagues
- **Responsive multi-column grid** - 4 columns on large screens, scaling down to 1 on mobile
- **Empty team filtering** - Only shows teams with players assigned
- **Alphabetical player sorting** - Players sorted A-Z within each team
- **Current user highlighting** - Green background on logged-in user's name
- **User's team highlighting** - Border highlight on teams the user belongs to
- **Cache disabled** - `max-age => 0` for proper tab switching

---

## Testing Commands

```bash
# Clear cache after changes
ddev drush cr

# Test admin Schedule Builder
# Visit: /admin/ccsoccer/season/100/schedule
# - Check Time/Date headers per slot
# - Check drag-drop works
# - Navigate with Prev/Next
# - Drag from workbench, verify position persists after reload

# Test public Schedule
# Visit: /schedule?season=99
# - Check layout matches admin
# - Check ⚽ icon next to your team
# - Check Prev/Next navigation

# Test My Schedule
# Visit: /my-schedule?season=99 (must be logged in)
# - Only your games should show team names
# - Other cells should be empty (pink/white background only)

# Test anonymous Schedule
# Log out and visit: /schedule?season=99
# - Should work with no ⚽ icons
```

---

## Git Commit Message

```
Unify schedule grid layout across admin and public views

- Phase 1: Update Schedule Builder display
  - Restructure grid with Time/Date headers per time slot section
  - Field labels in left column with rowspan for home/away rows
  - Home team row (pink) + Away team row (white) per field
  - Add visual spacer between time slots
  - Fix navigation persistence when dragging from workbench

- Phase 2: Extract shared rendering
  - Create ScheduleGridBuilder service with three modes (admin/public/my_schedule)
  - Add shared schedule-grid.css for consistent styling
  - Move getUserTeamIds() and calculateAllWeeks() to service

- Phase 3: Update public schedule
  - Add /my-schedule route for logged-in users to see only their games
  - Add soccer ball icon (⚽) to highlight user's team
  - Update ContentController to use ScheduleGridBuilder service

- Remove "Fill Empty Slots" button from Schedule Builder
```

---

## Known Issues / Future Work

### From Previous Sessions (Still Pending)
- **Season-filtered views** - Menu items like View Registrations/Teams/Games go to global collections
- **Tournament menus** - Will add when tournament schedule/roster builder routes exist
- **Additional season actions** - May need Notifications, Reporting, Player Management, Credit Management

### Potential Enhancements
- Add tournament view page similar to season view page
- Add links to filtered registrations/teams/games from season view page
- Add quick stats to season list builder
- Test iCal and PDF export links on schedule page
- Consider adding My Schedule link to user menu

---

## Visibility Flags Behavior Summary

| Flag | Purpose | Where Used |
|------|---------|------------|
| `active` | Season appears in admin menus | `hook_menu_links_discovered_alter()` |
| `registration_visible` | Season appears on public `/register` page | `RegistrationController::available()` |
| `roster_visible` | Players can view team rosters on `/teams` | `ContentController::teamsPage()` |
| `schedule_visible` | Players can view schedule on `/schedule` | `ContentController::schedulePage()` |

---

## Session Continuity

### Current Architecture Patterns
- Public pages in `ContentController.php`
- Shared rendering in `ScheduleGridBuilder` service
- Entity view pages in entity-specific controllers (e.g., `SeasonController.php`)
- Global CSS via `content-pages` library
- Shared schedule CSS via `schedule-grid` library
- Admin-specific schedule CSS via `schedule-builder` library
- Entity-specific CSS via dedicated libraries (e.g., `season-view`)
- Dynamic admin menus via hook in `.module`
- Cache invalidation on entity save for menu updates
- Drupal behaviors with `once()` for JavaScript initialization
- `max-age => 0` for pages with dynamic query parameters
- `sessionStorage` for cross-reload state persistence

### For Next Session
- Consider building tournament view page
- May want to add season-specific links to registrations/teams/games
- Continue with registration/tournament features as needed
- Test iCal/PDF export functionality
- Consider adding My Schedule to user menu

---

**End of Session - Schedule Grid Unification Complete!**
