Story 5.7: Speaker Preferences Panel - Slot Assignment
Story: Epic 5, Story 5.7 - Slot Assignment & Progressive Publishing
Purpose
This wireframe documents how speaker preferences are displayed during session timing assignment, including time preferences, A/V requirements, room setup needs, and real-time preference match scoring as organizers assign timings.
Context: Used within the dedicated slot assignment page during drag-drop timing assignment workflow.
Preference Data Model
Speaker Preferences Schema
interface SpeakerPreferences {
// Time preferences
timeOfDay: {
morning: 'preferred' | 'neutral' | 'avoid'; // 6:00 - 12:00
afternoon: 'preferred' | 'neutral' | 'avoid'; // 12:00 - 18:00
evening: 'preferred' | 'neutral' | 'avoid'; // 18:00 - 22:00
};
// Specific avoid times
specificAvoidTimes: Array<{
start: Date;
end: Date;
reason: string; // e.g., "Morning commute", "Prior commitment"
}>;
// A/V requirements
avRequirements: {
microphone: 'required' | 'optional' | 'not_needed';
projector: 'required' | 'optional' | 'not_needed';
clickerRemote: 'required' | 'optional' | 'not_needed';
whiteboard: 'required' | 'optional' | 'not_needed';
recordingPermission: 'approved' | 'denied' | 'pending';
};
// Room setup preferences
roomSetup: {
standingDesk: 'preferred' | 'neutral' | 'not_needed';
naturalLight: 'preferred' | 'neutral' | 'not_needed';
flipChart: 'preferred' | 'neutral' | 'not_needed';
quietRoom: 'preferred' | 'neutral' | 'not_needed';
notes: string; // Free-form text
};
// Session preferences
sessionPreferences: {
preferredDuration: number; // In minutes (60, 90, 120, etc.)
maxSessionsPerDay: number;
};
}
UI Component Types
1. Tooltip (Hover Summary)
Trigger: Mouse hover over speaker card in pool sidebar
Purpose: Quick preview of key preferences without opening full drawer
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Speaker Pool β
β ββββββββββββββββββββββββββββββββββββββ β
β β πΆ Dr. Sarah Miller βοΈ π β β Mouse hover here β
β β AI in Architecture β β
β β [View Preferences] β β
β ββββββββββββββββββββββββββββββββββββββ β
β β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β Dr. Sarah Miller - Quick Preferences β β
β β β β
β β Time: βοΈ Prefers afternoon β β
β β β Avoid morning (before 09:00) β β
β β A/V: Microphone, Projector required β β
β β Room: Natural light, Quiet room preferred β β
β β β β
β β Click [View Preferences] for full details β β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Tooltip Appearance:
- Position: Below speaker card, aligned left
- Delay: Appears after 500ms hover
- Dismiss: Disappears on mouse leave or click
- Mobile: Tap speaker card to toggle tooltip
2. Preference Match Highlights (During Drag)
Trigger: User starts dragging speaker card from pool
Purpose: Real-time visual feedback showing which session slots are good/poor matches
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β DRAGGING: Dr. Sarah Miller (prefers afternoon, avoid morning <09:00) β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β Session Timeline Grid - June 10, 2025 β
β β
β Room A Room B Main Hall β
β 08:00 βββββββββββββββββββ βββββββββββββββββββ βββββββββββββββββββ β
β β Workshop 1 β β β β β β
β β (No timing) β β [Empty Slot] β β [Empty Slot] β β
β 09:30 β β β β β β β
β β π΄ Poor Match β β π΄ Poor Match β β π΄ Poor Match β β
β β 15% score β β 20% score β β 18% score β β
β βββββββββββββββββββ βββββββββββββββββββ βββββββββββββββββββ β
β β
β 11:00 βββββββββββββββββββ βββββββββββββββββββ β
β β Panel Session β β [Empty Slot] β β
β 12:30 β (Assigned) β β β β
β β β β π‘ Acceptable β β
β β β β 65% score β β
β βββββββββββββββββββ βββββββββββββββββββ β
β β
β 14:00 βββββββββββββββββββ βββββββββββββββββββ βββββββββββββββββββ β
β β [Empty Slot] β β [Empty Slot] β β [Empty Slot] β β
β 15:30 β β β β β β β
β β π’ Strong Match β β π’ Strong Match β β π’ Strong Match β β
β β 85% score β β 92% score β β 88% score β β
β βββββββββββββββββββ βββββββββββββββββββ βββββββββββββββββββ β
β β
β 18:30 βββββββββββββββββββ β
β β [Empty Slot] β β
β 20:00 β β β
β β π΄ Poor Match β β
β β 12% score β β
β βββββββββββββββββββ β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Color Coding:
-
π’ Green Border (Strong Match): 80-100% score
- Slot background: Light green tint (#e8f5e9)
- Border: 2px solid green (#4caf50)
- Shadow: Green glow effect
-
π‘ Yellow Border (Acceptable Match): 50-79% score
- Slot background: Light yellow tint (#fff9c4)
- Border: 2px solid yellow (#ffc107)
- Shadow: Yellow glow effect
-
π΄ Red Border (Poor Match): <50% score
- Slot background: Light red tint (#ffebee)
- Border: 2px solid red (#f44336)
- Shadow: Red glow effect
Match Score Display:
- Position: Bottom of slot, centered
- Font: Small, bold, colored to match border
- Format: β85% scoreβ or βStrong Matchβ
3. Slot Hover Tooltip (Match Details)
Trigger: While dragging speaker, mouse hovers over a specific session slot
Purpose: Show detailed breakdown of why slot is a good/poor match
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Session Timeline Grid - June 10, 2025 β
β β
β 14:00 βββββββββββββββββββ βββββββββββββββββββ β
β β [Empty Slot] β β [Empty Slot] β β Mouse hover here β
β 15:30 β β β β β
β β π’ Strong Match β β π’ Strong Match β β
β β 85% score β β 92% score β β
β βββββββββββββββββββ βββββββββββββββββββ β
β β β
β ββββββββββββββββββββββββββββ΄βββββββββββββββββββββββββββββββββββ β
β β Match Details: Room B, 14:00-15:30 β β
β β β β
β β Overall Score: 92% π’ Strong Match β β
β β β β
β β β Time: Afternoon slot (preferred) +30 points β β
β β β Timing: No conflict with avoid times +40 points β β
β β β Room: Natural light available +10 points β β
β β β A/V: Projector & microphone ready +12 points β β
β β β οΈ Duration: 1.5h (speaker prefers 1h) -5 points β β
β β β β
β β Recommendation: Excellent match - Assign here β β
β β β β
β β Drop to assign Dr. Sarah Miller to this slot β β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Tooltip Features:
- Position: Above or beside slot (auto-adjust to fit screen)
- Scoring Breakdown: Line items with +/- points
- Checkmarks: β for matched criteria, β οΈ for minor issues, β for conflicts
- Recommendation: AI-generated suggestion (βExcellent matchβ, βAcceptableβ, βNot recommendedβ)
- Call-to-Action: βDrop to assignβ instruction
4. Full Preferences Drawer
Trigger: User clicks [View Preferences] button on speaker card OR clicks speaker name
Purpose: Comprehensive view of all speaker preferences, used for detailed review before assignment
Panel Type: Material-UI Drawer sliding from right (400px width on desktop)
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Session Timeline Grid β DRAWER β β
β β β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β β β
β β Speaker cards and timeline grid... β β β β
β β β β β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β β β
β β β β
β β β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ΄βββββββββββ΄βββ
β β
β Drawer β
β slides β
β from β
β right β
β β
ββββββββββββ
Full Drawer Layout:
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Dr. Sarah Miller - Preferences [X] β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β ββββ Time Preferences βββββββββββββββββββββββββββββββββ β
β β β β
β β Time of Day: β β
β β β β
β β βοΈ Afternoon (12:00 - 18:00) β Preferred β β
β β Best availability, highest energy levels β β
β β β β
β β βͺ Morning (6:00 - 12:00) βͺ Neutral β β
β β Available after 09:00 β β
β β β β
β β β Evening (18:00 - 22:00) β Avoid β β
β β Family commitments, low energy β β
β β β β
β β βββββββββββββββββββββββββββββββββββββββββββββββββ β β
β β β β
β β Specific Avoid Times: β β
β β β β
β β π΄ June 10, 08:00 - 09:00 β β
β β Reason: Morning commute from Zurich β β
β β β β
β β π΄ June 11, 17:00 - 19:00 β β
β β Reason: Prior commitment (family event) β β
β β β β
β β π΄ June 12, All day β β
β β Reason: Unavailable (traveling) β β
β β β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β ββββ A/V Requirements βββββββββββββββββββββββββββββββββ β
β β β β
β β Audio/Visual Setup: β β
β β β β
β β β Microphone Required β β
β β Needs wireless lavalier or headset mic β β
β β β β
β β β Projector/Screen Required β β
β β HDMI connection, 1080p minimum β β
β β β β
β β β Clicker/Remote Required β β
β β For presentation slides β β
β β β β
β β - Whiteboard Not needed β β
β β β β
β β β Recording Permission Approved β β
β β Video recording allowed, requires attribution β β
β β β β
β β βββββββββββββββββββββββββββββββββββββββββββββββββ β β
β β β β
β β Technical Notes: β β
β β "Bringing MacBook Pro (2023) with USB-C ports. β β
β β Will need HDMI adapter. Prefer confidence β β
β β monitor for presenter notes." β β
β β β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β ββββ Room Setup βββββββββββββββββββββββββββββββββββββββ β
β β β β
β β Room Preferences: β β
β β β β
β β β Standing Desk Preferred β β
β β Better for energy, audience engagement β β
β β β β
β β β Natural Light Preferred β β
β β Helps with mood and presentation quality β β
β β β β
β β - Flip Chart Not needed β β
β β β β
β β β Quiet Room Preferred β β
β β Minimal background noise for recording β β
β β β β
β β βββββββββββββββββββββββββββββββββββββββββββββββββ β β
β β β β
β β Seating Setup: β β
β β "Prefer interactive workshop setup with audience β β
β β seating in semi-circle or U-shape. Classroom- β β
β β style seating also acceptable. Avoid theater β β
β β seating if possible as it limits interaction." β β
β β β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β ββββ Session Preferences ββββββββββββββββββββββββββββββ β
β β β β
β β Preferred Session Duration: 60-90 minutes β β
β β (Can extend to 120 min if needed) β β
β β β β
β β Maximum Sessions per Day: 2 sessions β β
β β (Need breaks to maintain energy) β β
β β β β
β β Presentation Style: Interactive workshop β β
β β (Q&A, live demos, hands-on exercises) β β
β β β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β ββββ Match Score (Dynamic) ββββββββββββββββββββββββββββ β
β β β β
β β π Current Slot Match Analysis: β β
β β β β
β β [No slot selected] β β
β β β β
β β Hover over a session slot or drag this speaker β β
β β to see preference match score. β β
β β β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β [Assign to Best Match] [Close] β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Drawer Sections:
-
Time Preferences:
- Icons: βοΈ (preferred), βͺ (neutral), β (avoid)
- Color coding: Green for preferred, gray for neutral, red for avoid
- Specific avoid times listed with date ranges and reasons
- Visual emphasis on hard constraints (specific avoid times)
-
A/V Requirements:
- Checklist format with status indicators
- β = Required, - = Not needed
- Recording permission status (approved/denied/pending)
- Technical notes field for additional context
-
Room Setup:
- Preference items with preferred/neutral/not needed status
- Free-form notes for seating arrangement preferences
- Helps organizers match room capabilities to needs
-
Session Preferences:
- Duration preferences (impacts session slot sizing)
- Max sessions per day (prevents over-scheduling speaker)
- Presentation style (informational)
-
Match Score (Dynamic):
- Updates in real-time when user hovers over slots
- Shows which slot is currently being evaluated
- Displays score breakdown
Dynamic Match Score Section (When Hovering Over Slot):
β ββββ Match Score (Dynamic) ββββββββββββββββββββββββββββ β
β β β β
β β π Evaluating: Room B, June 10, 14:00-15:30 β β
β β β β
β β Overall Match: 92% π’ Strong Match β β
β β β β
β β β Time of Day: Afternoon (preferred) β β
β β Score: +30 points β β
β β β β
β β β Avoid Times: No conflicts β β
β β Score: +40 points β β
β β β β
β β β Room Features: Natural light available β β
β β Score: +10 points β β
β β β β
β β β A/V Setup: Projector, mic available β β
β β Score: +12 points β β
β β β β
β β β οΈ Duration: 1.5h (prefer 1-1.5h) β β
β β Score: 0 points (neutral) β β
β β β β
β β Total: 92/100 β β
β β β β
β β Recommendation: Excellent match! This slot aligns β β
β β with all major preferences. Assign with confidence. β β
β β β β
β β [Assign to This Slot β] β β
β β β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
[Assign to Best Match] Button:
- When clicked: Automatically suggests slot with highest match score
- Opens confirmation modal showing suggested slot
- User can accept or decline suggestion
Interaction Flow
Flow 1: Quick Preview (Tooltip)
1. User hovers over speaker card in pool
β
2. Tooltip appears after 500ms delay
- Shows: Time preference icons, A/V summary, room needs
β
3. User moves mouse away OR clicks [View Preferences]
β
4. Tooltip disappears (if mouse away) OR Drawer opens (if clicked)
Use Case: Organizer wants quick check before dragging speaker
Flow 2: Drag-and-Drop with Match Highlighting
1. User clicks and holds on speaker card
β
2. Drag gesture begins
β
3. Session grid updates:
- All empty slots show match score overlays (green/yellow/red)
- Occupied slots remain grayed out
β
4. User hovers over specific slot while dragging
β
5. Detailed match tooltip appears above slot
- Shows: Breakdown of score, recommendation
β
6. User drops speaker onto slot
β
7. Match score displayed in assignment confirmation
OR
Conflict modal appears (if poor match <50% or hard conflict)
Use Case: Organizer is actively assigning timing and wants visual guidance
Flow 3: Full Preferences Review
1. User clicks speaker card or [View Preferences] button
β
2. Drawer slides in from right (400ms animation)
β
3. Drawer displays all preference sections (scrollable)
β
4. User reviews preferences
β
5. User hovers over session slot in background
β
6. Match Score section in drawer updates dynamically
- Shows score for hovered slot
β
7. User clicks [Assign to This Slot β] in drawer
OR
User clicks [Assign to Best Match]
β
8. Assignment confirmation appears
β
9. Drawer closes automatically
Use Case: Organizer wants detailed understanding of speaker needs before assignment
Match Scoring Algorithm
Scoring Breakdown
interface MatchScore {
total: number; // 0-100
severity: 'strong' | 'acceptable' | 'poor';
breakdown: {
timeOfDay: number; // 0-30 points
avoidTimes: number; // 0-40 points
roomFeatures: number; // 0-15 points
avSetup: number; // 0-15 points
};
recommendation: string;
}
function calculateMatchScore(
slot: SessionSlot,
preferences: SpeakerPreferences
): MatchScore {
let timeOfDay = 0;
let avoidTimes = 0;
let roomFeatures = 0;
let avSetup = 0;
// 1. Time of Day (0-30 points)
const slotTimeOfDay = getTimeOfDay(slot.startTime); // 'morning' | 'afternoon' | 'evening'
if (preferences.timeOfDay[slotTimeOfDay] === 'preferred') {
timeOfDay = 30;
} else if (preferences.timeOfDay[slotTimeOfDay] === 'neutral') {
timeOfDay = 15;
} else {
timeOfDay = 0; // 'avoid'
}
// 2. Avoid Times (0-40 points)
const conflictsAvoidTime = preferences.specificAvoidTimes.some(avoid =>
overlaps(slot.startTime, slot.endTime, avoid.start, avoid.end)
);
if (!conflictsAvoidTime) {
avoidTimes = 40; // No conflicts
} else {
avoidTimes = 0; // Hard conflict with specific avoid time
}
// 3. Room Features (0-15 points)
let roomScore = 0;
if (preferences.roomSetup.naturalLight === 'preferred' && slot.room.hasNaturalLight) {
roomScore += 5;
}
if (preferences.roomSetup.quietRoom === 'preferred' && slot.room.isQuiet) {
roomScore += 5;
}
if (preferences.roomSetup.standingDesk === 'preferred' && slot.room.hasStandingDesk) {
roomScore += 5;
}
roomFeatures = Math.min(roomScore, 15); // Cap at 15
// 4. A/V Setup (0-15 points)
let avScore = 0;
if (preferences.avRequirements.microphone === 'required' && slot.room.hasMicrophone) {
avScore += 5;
} else if (preferences.avRequirements.microphone === 'required' && !slot.room.hasMicrophone) {
avScore -= 10; // Penalty for missing required equipment
}
if (preferences.avRequirements.projector === 'required' && slot.room.hasProjector) {
avScore += 5;
} else if (preferences.avRequirements.projector === 'required' && !slot.room.hasProjector) {
avScore -= 10;
}
if (preferences.avRequirements.clickerRemote === 'required' && slot.room.hasClicker) {
avScore += 5;
}
avSetup = Math.max(0, Math.min(avScore, 15)); // Cap at 15, floor at 0
// Total score
const total = timeOfDay + avoidTimes + roomFeatures + avSetup;
// Severity
let severity: 'strong' | 'acceptable' | 'poor';
if (total >= 80) severity = 'strong';
else if (total >= 50) severity = 'acceptable';
else severity = 'poor';
// Recommendation
let recommendation: string;
if (total >= 90) {
recommendation = 'Excellent match! This slot aligns with all major preferences. Assign with confidence.';
} else if (total >= 80) {
recommendation = 'Strong match. Most preferences are met. Good choice for assignment.';
} else if (total >= 65) {
recommendation = 'Acceptable match. Some preferences not met, but workable.';
} else if (total >= 50) {
recommendation = 'Below average match. Consider alternative slots if available.';
} else {
recommendation = 'Poor match. Assignment not recommended without speaker confirmation.';
}
return {
total,
severity,
breakdown: { timeOfDay, avoidTimes, roomFeatures, avSetup },
recommendation
};
}
Scoring Criteria Weights
| Criterion | Max Points | Rationale |
|---|---|---|
| Avoid Times | 40 | Hard constraint - highest weight |
| Time of Day | 30 | Strong preference - second highest |
| Room Features | 15 | Nice-to-have - moderate weight |
| A/V Setup | 15 | Required equipment - moderate weight |
| Total | 100 |
Threshold Levels:
- Strong Match (80-100): π’ Green - Highly recommended
- Acceptable Match (50-79): π‘ Yellow - Workable, some compromises
- Poor Match (<50): π΄ Red - Not recommended, triggers warning
Visual Design
Color Palette
Match Score Colors:
- Strong Match (80-100):
#4caf50(Material Green 500) - Acceptable Match (50-79):
#ffc107(Material Amber 500) - Poor Match (<50):
#f44336(Material Red 500)
Preference Icons:
- Preferred: βοΈ (sun emoji) +
#4caf50background - Neutral: βͺ (white circle) +
#9e9e9ebackground - Avoid: β (prohibited sign) +
#f44336background
Drawer Background:
- Header:
#f5f5f5(Material Grey 100) - Body:
#ffffff(White) - Section dividers:
#e0e0e0(Material Grey 300)
Accessibility
Screen Reader Support
Drawer Opening Announcement:
"Speaker preferences drawer opened for Dr. Sarah Miller.
Showing time preferences, A/V requirements, and room setup.
Press Escape to close."
Match Score Announcement (During Drag):
"Dragging Dr. Sarah Miller. Hovering over Room B, 14:00-15:30.
Match score: 92 percent, strong match.
Drop to assign to this slot."
ARIA Attributes:
<!-- Drawer -->
<div role="complementary" aria-labelledby="drawer-title">
<h2 id="drawer-title">Dr. Sarah Miller - Preferences</h2>
<!-- Time preferences section -->
<section aria-labelledby="time-prefs-heading">
<h3 id="time-prefs-heading">Time Preferences</h3>
<div role="list" aria-label="Time of day preferences">
<div role="listitem">
<span aria-label="Afternoon preferred">
βοΈ Afternoon (12:00 - 18:00) β Preferred
</span>
</div>
</div>
</section>
<!-- Match score section -->
<section aria-labelledby="match-score-heading" aria-live="polite">
<h3 id="match-score-heading">Match Score</h3>
<div role="status">
Overall Match: 92% Strong Match
</div>
</section>
</div>
<!-- Session slot with match indicator -->
<div
role="button"
tabindex="0"
aria-label="Session slot: Room B, 14:00 to 15:30. Match score 92 percent, strong match. Press Enter to assign."
class="session-slot match-strong"
>
<!-- Slot content -->
</div>
Keyboard Navigation
Drawer Controls:
Escape: Close drawerTab: Navigate between preference sectionsShift+Tab: Navigate backwardsEnter: Activate [Assign to Best Match] or [Assign to This Slot] buttons
During Drag (Keyboard Alternative):
Arrow Keys: Navigate between session slotsSpace: Select slot to view match scoreEnter: Assign speaker to selected slotEscape: Cancel drag operation
Responsive Design
Desktop (β₯1200px)
- Drawer Width: 400px fixed
- Tooltip Width: 320px max
- Match Score Overlay: Appears at bottom of slot (full text visible)
Tablet (768px - 1199px)
- Drawer Width: 350px fixed
- Tooltip Width: 280px max
- Match Score Overlay: Abbreviated (e.g., β85%β only, hide βStrong Matchβ label)
Mobile (<768px)
- Drawer: Full-screen modal (not side drawer)
- Tooltip: Bottom sheet (anchored to bottom of screen)
- Match Score: Badge icon only during drag (number visible on tap)
- Drawer Sections: Collapsible accordions to save vertical space
Mobile Drawer Header:
βββββββββββββββββββββββββββββββββββββββββββ
β β Dr. Sarah Miller - Preferences β
βββββββββββββββββββββββββββββββββββββββββββ€
β βΌ Time Preferences β
β βΆ A/V Requirements β
β βΆ Room Setup β
β βΆ Session Preferences β
β βΆ Match Score β
β β
β [Assign to Best Match] [Close] β
βββββββββββββββββββββββββββββββββββββββββββ
Edge Cases
Missing Preferences Data
Scenario: Speaker has not filled out preferences form
Display:
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Dr. John Chen - Preferences [X] β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β β οΈ No preferences on file β
β β
β This speaker has not provided time preferences, β
β A/V requirements, or room setup details. β
β β
β All session slots will show neutral match (50% score). β
β β
β Actions: β
β β’ Assign to any available slot β
β β’ Contact speaker for preference collection β
β β
β [Send Preference Request Email] [Close] β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Match Score Behavior:
- All slots show π‘ Yellow (Acceptable - 50% default score)
- Tooltip message: βNo preferences on file. Neutral match.β
Conflicting Preferences
Scenario: Speaker marked all time slots as βAvoidβ (invalid state)
Validation on Preference Save:
β οΈ Invalid Preference Configuration
You have marked all time slots (Morning, Afternoon, Evening) as "Avoid."
Please mark at least one time slot as "Preferred" or "Neutral."
[Edit Preferences]
Fallback if Invalid Data in Database:
- System overrides βAvoidβ on all slots to βNeutralβ
- Admin notification sent to fix data inconsistency
Zero Match Slots
Scenario: All available slots conflict with speakerβs avoid times
Display in Drawer:
β ββββ Match Score (Dynamic) ββββββββββββββββββββββββββββ β
β β β β
β β β οΈ No Available Slots Match Preferences β β
β β β β
β β All current empty slots conflict with this β β
β β speaker's avoid times or preferences. β β
β β β β
β β Recommendations: β β
β β 1. Contact speaker to check flexibility β β
β β 2. Create new time slot outside current schedule β β
β β 3. Reassign a different speaker to this topic β β
β β β β
β β [Contact Speaker] [View All Slots Anyway] β β
β β β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
Grid Behavior:
- All slots show π΄ Red (Poor Match <30%)
- Tooltip includes: βConflicts with avoid times. Contact speaker before assigning.β
Implementation Notes
Data Fetching
API Endpoints:
// Fetch speaker preferences
GET /api/v1/speakers/{speakerId}/preferences
Response: SpeakerPreferences
// Calculate match score for slot
POST /api/v1/speakers/{speakerId}/match-score
Body: { sessionSlot: { startTime, endTime, room } }
Response: { score: number, breakdown: {...}, recommendation: string }
React Query Hook:
const useSpeakerPreferences = (speakerId: string) => {
return useQuery({
queryKey: ['speaker-preferences', speakerId],
queryFn: () => fetchSpeakerPreferences(speakerId),
staleTime: 5 * 60 * 1000, // 5 minutes
});
};
const useMatchScore = (speakerId: string, slot: SessionSlot) => {
return useQuery({
queryKey: ['match-score', speakerId, slot.id],
queryFn: () => calculateMatchScore(speakerId, slot),
enabled: !!slot, // Only fetch when slot is hovered
});
};
Real-Time Updates
WebSocket Event (when preferences updated by speaker):
{
"type": "SPEAKER_PREFERENCES_UPDATED",
"data": {
"speakerId": "uuid",
"updatedAt": "2025-06-10T14:30:00Z"
}
}
React Update Handler:
useEffect(() => {
const handlePreferenceUpdate = (event: WebSocketEvent) => {
if (event.type === 'SPEAKER_PREFERENCES_UPDATED') {
queryClient.invalidateQueries(['speaker-preferences', event.data.speakerId]);
queryClient.invalidateQueries(['match-score', event.data.speakerId]);
}
};
websocket.on('message', handlePreferenceUpdate);
return () => websocket.off('message', handlePreferenceUpdate);
}, []);
Testing Checklist
Tooltip Display
Match Highlighting During Drag
Slot Hover Tooltip
Full Preferences Drawer
Match Scoring Algorithm
Edge Cases
Accessibility
Responsive Design
Related Wireframes
- story-5.7-slot-assignment-page.md: Main slot assignment interface where preferences are used
- story-5.7-conflict-resolution-modal.md: Conflict modal triggered when match score <50%
- story-5.7-navigation-integration.md: Navigation flows to/from slot assignment page
Change Log
| Date | Version | Description | Author |
|---|---|---|---|
| 2025-12-25 | 1.0 | Initial speaker preferences panel wireframe | Sally (UX Expert) |