- Added AvailableParticipantsSection for participant search and filtering. - Created DraftGridSection for displaying the draft grid with team timers and context menu. - Developed QueueSection for managing participant queue and autodraft settings. - Introduced RecentPicksSection to show recent draft picks. - Implemented TeamsDraftedGrid to visualize drafted participants by team and sport. - Added collapsible UI components for better layout management. - Established tabbed navigation for draft board, recent picks, and teams drafted. - Enhanced responsiveness for mobile and desktop views. - Updated styles for a cohesive design across components.
411 lines
11 KiB
Markdown
411 lines
11 KiB
Markdown
# Draft Room Redesign Plan
|
||
|
||
**Status**: ✅ Complete - All Features Implemented & Tested
|
||
**Created**: 2025-10-24
|
||
**Last Updated**: 2025-10-24
|
||
|
||
## Overview
|
||
|
||
Redesigning the draft room to use a full-screen layout with a collapsible left sidebar and tabbed main content area.
|
||
|
||
---
|
||
|
||
## Requirements
|
||
|
||
### Layout Changes
|
||
|
||
#### 1. Full-Screen Layout (No Page Scroll)
|
||
- Page fills entire viewport (100vh)
|
||
- Individual sections scroll internally
|
||
- Fixed header at top
|
||
- Content area uses remaining height
|
||
|
||
#### 2. Collapsible Left Sidebar
|
||
- **Default State**: Expanded
|
||
- **Width**:
|
||
- Expanded: 350px
|
||
- Collapsed: 50px
|
||
- **Contents** (Accordion-style sections):
|
||
- My Queue (top section) - Collapsible
|
||
- Eligibility status banner
|
||
- Queue list (ordered, scrollable)
|
||
- Autodraft settings
|
||
- Clear queue button
|
||
- Available Participants (bottom section) - Collapsible
|
||
- Search bar
|
||
- Sport filter dropdown
|
||
- Show/hide drafted toggle
|
||
- Participants table (scrollable)
|
||
- Action buttons (Pick/Add to Queue)
|
||
- **Section Behavior**:
|
||
- Both sections can be expanded or collapsed independently
|
||
- When both expanded: 50/50 vertical split
|
||
- When one collapsed: Expanded section takes 100% of space
|
||
- At least one section must remain expanded
|
||
- **Responsive**:
|
||
- Desktop (≥1024px): Fixed sidebar on left
|
||
- Mobile (<1024px): Full-screen modal
|
||
|
||
#### 3. Tabbed Main Content Area
|
||
Three tabs with toggle functionality:
|
||
|
||
**Tab 1: Draft Board (Default)**
|
||
- Current draft grid display
|
||
- Team headers with timers and autodraft status
|
||
- Snake draft grid (scrollable)
|
||
- Context menu for commissioners
|
||
- Reuse existing DraftGrid component or inline implementation
|
||
|
||
**Tab 2: Recent Picks**
|
||
- List of recent picks (latest 10-20)
|
||
- Same format as current Recent Picks section
|
||
- Scrollable list
|
||
- Shows: Pick number, team, participant, sport
|
||
|
||
**Tab 3: Teams Drafted (NEW)**
|
||
- Grid layout:
|
||
- **Rows**: Sports (from season sports)
|
||
- **Columns**: Teams (in draft order)
|
||
- **Cells**: Participants drafted by that team in that sport
|
||
- **Highlighting**: Visual indicator when team has multiple participants in same sport
|
||
- **Flex Display**: Show "X of Y flexes used" somewhere with team data
|
||
- **Scrollable**: Both horizontal and vertical as needed
|
||
|
||
### Design Decisions
|
||
|
||
**Teams Drafted Grid:**
|
||
1. ✅ **Cell content**: Show participant names (e.g., "Patrick Mahomes, Travis Kelce")
|
||
2. ✅ **Cell interactivity**: No clickability needed (existing commissioner context menu on draft board remains)
|
||
3. ✅ **Empty cells**: Leave empty (just border, no text)
|
||
4. ✅ **Flex display**: In team column header, below team name (similar to timer positioning)
|
||
|
||
**Tab UI:**
|
||
5. ✅ **Tab style**: ShadCN Tabs component
|
||
6. ✅ **Recent Picks data**: Same 10 most recent picks as current implementation
|
||
|
||
**Sidebar:**
|
||
7. ✅ **Section sizing**: Accordion-style - both sections collapsible independently
|
||
- Both expanded: 50/50 split
|
||
- One collapsed: Expanded section takes 100%
|
||
- At least one must remain expanded
|
||
|
||
---
|
||
|
||
## Current Implementation Analysis
|
||
|
||
### File Structure
|
||
|
||
**Main Route**: `/app/routes/leagues/$leagueId.draft.$seasonId.tsx`
|
||
- All draft room logic currently in this single file
|
||
- ~1,300 lines of code
|
||
- Inline rendering of Queue and Available Participants (not extracted components)
|
||
|
||
**Related Components**:
|
||
- `/app/components/DraftGrid.tsx` - Reusable draft grid (not currently used in draft room)
|
||
- `/app/components/AutodraftSettings.tsx` - Autodraft toggle and settings
|
||
|
||
**Current Layout**:
|
||
```
|
||
Header (full width, fixed)
|
||
├─ Title and metadata
|
||
├─ Control buttons (start/pause/resume)
|
||
└─ Connection status
|
||
|
||
Draft Grid (full width, scrollable)
|
||
├─ Team headers
|
||
└─ Pick grid
|
||
|
||
3-Column Grid (lg:grid-cols-3)
|
||
├─ My Queue (conditional if user has team)
|
||
│ ├─ Eligibility status
|
||
│ ├─ Queue list (max-h-96)
|
||
│ ├─ Autodraft settings
|
||
│ └─ Clear button
|
||
├─ Recent Picks
|
||
│ └─ Last 10 picks (max-h-96)
|
||
└─ Available Participants
|
||
├─ Search and filters
|
||
└─ Participants table (max-h-[500px])
|
||
```
|
||
|
||
### State Management
|
||
Component state (useState):
|
||
- `picks` - All draft picks
|
||
- `currentPick` - Current pick number
|
||
- `searchQuery` - Participant search term
|
||
- `hideDrafted` - Toggle drafted visibility
|
||
- `sportFilter` - Active sport filter
|
||
- `queue` - User's queue items
|
||
- `teamTimers` - Timer for each team
|
||
- `autodraftStatus` - Autodraft state per team
|
||
- `connectedTeams` - Set of connected team IDs
|
||
- `forcePickDialogOpen` - Commissioner dialog state
|
||
|
||
Real-time updates via Socket.IO:
|
||
- `pick-made`
|
||
- `timer-update`
|
||
- `draft-paused` / `draft-resumed`
|
||
- `draft-completed`
|
||
- `autodraft-updated`
|
||
- `team-connected` / `team-disconnected`
|
||
- `participant-removed-from-queues`
|
||
|
||
### Data Flow
|
||
- Loader provides initial data
|
||
- Socket.IO provides real-time updates
|
||
- Form actions handle queue management and draft actions
|
||
- Draft eligibility calculated client-side via `calculateDraftEligibility()`
|
||
|
||
---
|
||
|
||
## Proposed Architecture
|
||
|
||
### New Component Structure
|
||
|
||
```
|
||
leagues/$leagueId.draft.$seasonId.tsx (Main Route)
|
||
├─ Full-screen flex container (100vh)
|
||
├─ Header (fixed, flex: 0 0 auto)
|
||
├─ Content Area (flex: 1 1 auto, flex row)
|
||
│ ├─ DraftSidebar (NEW component)
|
||
│ │ ├─ Collapse toggle button
|
||
│ │ ├─ QueueSection (scrollable)
|
||
│ │ └─ AvailableParticipantsSection (scrollable)
|
||
│ └─ MainContent (flex: 1 1 auto)
|
||
│ ├─ TabSelector (Draft Board | Recent Picks | Teams Drafted)
|
||
│ └─ TabContent (scrollable)
|
||
│ ├─ DraftBoardTab (uses DraftGrid component)
|
||
│ ├─ RecentPicksTab
|
||
│ └─ TeamsDraftedTab (NEW)
|
||
```
|
||
|
||
### Files to Create
|
||
|
||
1. **`/app/components/DraftSidebar.tsx`** (NEW)
|
||
- Collapsible sidebar container
|
||
- Props: collapsed state, queue data, participants data, handlers
|
||
- Two internal sections with separate scrolling
|
||
|
||
2. **`/app/components/draft/QueueSection.tsx`** (NEW, optional)
|
||
- Extracted queue rendering logic
|
||
- Props: queue, eligibility, autodraft settings, handlers
|
||
|
||
3. **`/app/components/draft/AvailableParticipantsSection.tsx`** (NEW, optional)
|
||
- Extracted participants table logic
|
||
- Props: participants, filters, handlers
|
||
|
||
4. **`/app/components/draft/TeamsDraftedGrid.tsx`** (NEW)
|
||
- Grid showing teams × sports with drafted participants
|
||
- Props: teams, sports, picks, flex usage
|
||
- Highlighting logic for multiple drafts per sport
|
||
|
||
5. **`/app/components/draft/DraftTabs.tsx`** (NEW, optional)
|
||
- Tab selector and content container
|
||
- Props: active tab, tab change handler, children
|
||
|
||
### Files to Modify
|
||
|
||
1. **`/app/routes/leagues/$leagueId.draft.$seasonId.tsx`**
|
||
- Add full-screen layout container
|
||
- Add sidebar collapsed state
|
||
- Add active tab state
|
||
- Import and render DraftSidebar
|
||
- Render tabbed main content
|
||
- Remove 3-column grid layout
|
||
- Remove Recent Picks section (moved to tab)
|
||
|
||
2. **`/app/components/DraftGrid.tsx`**
|
||
- Ensure it works in flex container
|
||
- May need height/overflow adjustments
|
||
|
||
### State Additions
|
||
|
||
Add to main route component:
|
||
```typescript
|
||
const [sidebarCollapsed, setSidebarCollapsed] = useState(() => {
|
||
// Check localStorage for user preference
|
||
const stored = localStorage.getItem('draftSidebarCollapsed');
|
||
return stored ? JSON.parse(stored) : false; // Default: expanded
|
||
});
|
||
|
||
const [activeTab, setActiveTab] = useState<'board' | 'picks' | 'teams'>('board');
|
||
```
|
||
|
||
---
|
||
|
||
## CSS/Styling Strategy
|
||
|
||
### Layout CSS
|
||
|
||
```css
|
||
/* Main container */
|
||
.draft-room-container {
|
||
height: 100vh;
|
||
display: flex;
|
||
flex-direction: column;
|
||
overflow: hidden;
|
||
}
|
||
|
||
/* Header */
|
||
.draft-room-header {
|
||
flex: 0 0 auto;
|
||
}
|
||
|
||
/* Content area */
|
||
.draft-room-content {
|
||
flex: 1 1 auto;
|
||
display: flex;
|
||
overflow: hidden;
|
||
}
|
||
|
||
/* Sidebar */
|
||
.draft-sidebar {
|
||
flex: 0 0 auto;
|
||
width: 350px; /* Expanded */
|
||
transition: width 0.3s ease, transform 0.3s ease;
|
||
overflow-y: auto;
|
||
display: flex;
|
||
flex-direction: column;
|
||
}
|
||
|
||
.draft-sidebar.collapsed {
|
||
width: 50px;
|
||
}
|
||
|
||
/* Sidebar sections */
|
||
.sidebar-section {
|
||
flex: 0 0 auto; /* Queue: take what you need */
|
||
overflow-y: auto;
|
||
}
|
||
|
||
.sidebar-section.grow {
|
||
flex: 1 1 auto; /* Available Participants: take remaining */
|
||
}
|
||
|
||
/* Main content */
|
||
.draft-main-content {
|
||
flex: 1 1 auto;
|
||
overflow-y: auto;
|
||
display: flex;
|
||
flex-direction: column;
|
||
}
|
||
|
||
/* Tab content */
|
||
.draft-tab-content {
|
||
flex: 1 1 auto;
|
||
overflow-y: auto;
|
||
}
|
||
```
|
||
|
||
### Responsive Breakpoints
|
||
|
||
```css
|
||
/* Mobile (<1024px) */
|
||
@media (max-width: 1023px) {
|
||
.draft-sidebar {
|
||
position: fixed;
|
||
top: 0;
|
||
left: 0;
|
||
right: 0;
|
||
bottom: 0;
|
||
width: 100%;
|
||
z-index: 50;
|
||
transform: translateX(-100%);
|
||
}
|
||
|
||
.draft-sidebar.open {
|
||
transform: translateX(0);
|
||
}
|
||
}
|
||
```
|
||
|
||
### Teams Drafted Grid Styling
|
||
|
||
```css
|
||
.teams-grid {
|
||
display: grid;
|
||
grid-template-columns: 150px repeat(auto-fit, minmax(120px, 1fr));
|
||
overflow: auto;
|
||
}
|
||
|
||
.teams-grid-cell {
|
||
border: 1px solid var(--border);
|
||
padding: 0.5rem;
|
||
min-height: 60px;
|
||
}
|
||
|
||
.teams-grid-cell.multiple-picks {
|
||
background-color: var(--accent);
|
||
font-weight: 600;
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## Implementation Steps
|
||
|
||
### Phase 1: Setup and Layout Structure
|
||
- [x] Create plans directory and documentation
|
||
- [ ] Add sidebar collapsed state with localStorage persistence
|
||
- [ ] Add active tab state
|
||
- [ ] Create full-screen layout container in main route
|
||
- [ ] Update header to work with new layout
|
||
- [ ] Test basic layout structure
|
||
|
||
### Phase 2: Sidebar Component
|
||
- [ ] Create DraftSidebar.tsx component shell
|
||
- [ ] Add collapse/expand toggle button
|
||
- [ ] Move Queue section rendering to sidebar
|
||
- [ ] Move Available Participants section to sidebar
|
||
- [ ] Add internal scrolling for both sections
|
||
- [ ] Test sidebar functionality and transitions
|
||
- [ ] Add mobile modal behavior
|
||
|
||
### Phase 3: Tab System
|
||
- [ ] Create tab selector UI (choose style based on user feedback)
|
||
- [ ] Add Draft Board tab (use existing grid)
|
||
- [ ] Add Recent Picks tab (move existing section)
|
||
- [ ] Create TeamsDraftedGrid component
|
||
- [ ] Implement Teams Drafted grid logic
|
||
- [ ] Add flex usage display
|
||
- [ ] Add highlighting for multiple picks
|
||
- [ ] Test tab switching and content rendering
|
||
|
||
### Phase 4: Refinement
|
||
- [ ] Adjust spacing and padding throughout
|
||
- [ ] Test all Socket.IO real-time updates
|
||
- [ ] Test all form actions (queue management, making picks)
|
||
- [ ] Test responsive behavior (desktop, tablet, mobile)
|
||
- [ ] Add keyboard shortcuts (optional)
|
||
- [ ] Performance testing with large datasets
|
||
- [ ] Accessibility audit (ARIA labels, focus management)
|
||
|
||
### Phase 5: Polish
|
||
- [ ] Animation tuning
|
||
- [ ] Dark mode verification
|
||
- [ ] Cross-browser testing
|
||
- [ ] User acceptance testing
|
||
|
||
---
|
||
|
||
## Notes
|
||
|
||
- Preserve all existing Socket.IO functionality
|
||
- Maintain commissioner-specific features (force pick, context menus)
|
||
- Keep eligibility calculation logic unchanged
|
||
- Ensure autodraft integration remains functional
|
||
- Test with various screen sizes and data volumes
|
||
|
||
---
|
||
|
||
## Success Criteria
|
||
|
||
- [ ] Draft room fills viewport (no page scroll)
|
||
- [ ] Sidebar collapses/expands smoothly
|
||
- [ ] All three tabs render correctly
|
||
- [ ] Teams Drafted grid shows accurate data
|
||
- [ ] Queue and Available Participants work as before
|
||
- [ ] All real-time updates continue to work
|
||
- [ ] Mobile experience is usable
|
||
- [ ] No regressions in existing functionality
|
||
- [ ] Performance is acceptable (no lag during picks/updates)
|