Story 2.4: Session Details Modal - Wireframe
Story: Epic 2, Story 4 - Current Event Landing Page (Session Details Modal)
Visual Wireframe
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β [β] β
β β
β ββββ SESSION DETAILS βββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β β β
β β 09:45 - 10:30 AM π 45 minutes β β
β β β β
β β KUBERNETES BEST PRACTICES: FROM DEV TO PRODUCTION β β
β β β β
β β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β β
β β β β
β β π Main Hall π― Technical Deep Dive β β
β β Kursaal Bern β Advanced Level β β
β β π₯ 87/150 registered π΄ Filling up fast! β β
β β β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β ββββ SPEAKER βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β β β
β β ββββββββββββ β β
β β β β Peter MΓΌller β β
β β β [Photo] β Senior Cloud Architect @ TechCorp AG β β
β β β β β β
β β ββββββββββββ 10+ years Kubernetes experience β’ CNCF Ambassador β β
β β β β
β β [View Full Profile β] β β
β β β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β ββββ SESSION DESCRIPTION βββββββββββββββββββββββββββββββββββββββββββββββ β
β β β β
β β Learn how to design, deploy, and manage Kubernetes clusters that β β
β β scale from development environments to production-ready systems. β β
β β This session covers: β β
β β β β
β β β’ Infrastructure as Code with GitOps workflows β β
β β β’ Security hardening and RBAC best practices β β
β β β’ High availability and disaster recovery strategies β β
β β β’ Monitoring, logging, and observability patterns β β
β β β’ Cost optimization techniques for cloud providers β β
β β β β
β β You'll leave with actionable strategies and real-world examples β β
β β from production deployments at scale. β β
β β β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β ββββ KEY TAKEAWAYS βββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β β β
β β β Production-ready Kubernetes architecture patterns β β
β β β Security best practices and compliance requirements β β
β β β Monitoring and troubleshooting strategies β β
β β β GitOps workflow implementation guide β β
β β β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β ββββ TARGET AUDIENCE βββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β β β
β β π₯ DevOps Engineers β’ Cloud Architects β’ Platform Engineers β β
β β β β
β β Prerequisites: Basic Kubernetes knowledge and container experience β β
β β β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β ββββ RELATED SESSIONS ββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β β β
β β β Service Mesh Architecture (11:00 AM) β β
β β β GitOps Implementation (11:45 AM) β β
β β β Container Orchestration Workshop (15:00 PM) β β
β β β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β ββββ ACTIONS βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β β β
β β [π
Add to My Schedule] [π Share Session] [π Download Slides*] β β
β β β β
β β * Available after the event β β
β β β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β [β Back to Agenda] [Register for Event β] β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Key Interactive Elements
-
[β] Close button: Closes modal and returns to current event landing page
-
[View Full Profile β] link: Navigates to speaker profile detail view (opens in new modal or page)
-
[π Add to My Schedule] button:
- For authenticated users: Adds session to personal schedule
- For unauthenticated users: Opens login/registration modal with message βRegister to build your personal scheduleβ
-
[π Share Session] button: Opens native share menu (mobile) or shows share options modal (desktop)
- Options: Copy link, Twitter, LinkedIn, Email
- Generates shareable deep link to this session
-
[π Download Slides] button:
- Disabled with tooltip before event: βAvailable after the eventβ
- After event: Downloads presentation PDF directly
- Tracks download analytics
-
[β Back to Agenda] link: Closes modal and scrolls to agenda section on landing page
-
[Register for Event β] button: Navigates to event registration page (story-2.4-event-registration.md)
-
Related session links: Clicking any related session closes current modal and opens that sessionβs detail modal (no modal stacking)
-
Real-time attendance counter: Shows live registration count (e.g., β87/150 registeredβ) with status indicator (βFilling up fastβ when >50% full)
Functional Requirements Met
-
FR6 (Current Event Prominence): Provides detailed session information for the current event with complete logistics (time, location, level)
-
FR15 (Mobile-Optimized Experience): Modal design adapts for mobile with scrollable content, touch-friendly buttons, and native share integration
-
FR14 (Personal Engagement): βAdd to My Scheduleβ enables personal schedule management for authenticated attendees
-
NFR1 (Responsive Design): Modal layout optimized for mobile, tablet, and desktop with appropriate sizing and scrolling
Technical Notes
- Modal implementation: Use React portal for overlay rendering outside DOM hierarchy
- Scroll behavior: Modal body scrollable while backdrop prevents page scroll (overflow: hidden on body)
- No deep linking support: Modal only opens via user interaction on event landing page (no direct URL access to modal state)
- Keyboard navigation: ESC key closes modal, Tab key cycles through interactive elements
- Focus management: Focus trap within modal, return focus to trigger element on close
- Animation: Smooth fade-in/scale animation for modal appearance (300ms transition)
- Mobile optimization: Full-screen modal on mobile (<768px), centered with max-width on desktop
- Share API: Use native Web Share API on mobile devices when available
- Calendar integration: βAdd to My Scheduleβ saves to userβs personal schedule in BATbern platform only (no external calendar app integration)
- Analytics tracking: Track modal views, share actions, and slide downloads for session popularity metrics
- Lazy loading: Speaker photo loaded only when modal opens (not on initial page load)
- State persistence: If user closes modal and reopens, scroll position resets to top
API Requirements
Initial Modal Load APIs
When the Session Details Modal opens, the following APIs are called:
- GET /api/v1/events/{eventId}/sessions/{sessionId}?include=speaker,relatedSessions
- Query params:
include=speaker,relatedSessions(consolidated resource expansion) - Returns: Complete session details with expanded speaker and related sessionsjson
{ "sessionId": "uuid", "title": "string", "description": "string", "startTime": "ISO-8601 datetime", "endTime": "ISO-8601 datetime", "duration": "integer (minutes)", "location": "string (Main Hall)", "venueDetails": "string (Kursaal Bern)", "sessionType": "enum (Keynote, Technical Deep Dive, Workshop, Panel)", "level": "enum (Beginner, Intermediate, Advanced)", "abstract": "string (max 1000 chars)", "keyTakeaways": ["string[]"], "targetAudience": "string", "prerequisites": "string", "capacity": "integer", "registeredCount": "integer", "registrationStatus": "enum (Open, Filling Fast, Almost Full, Full)", "tags": ["string[]"], "slidesAvailable": "boolean", "slidesUrl": "string | null", "speaker": { "speakerId": "uuid", "firstName": "string", "lastName": "string", "profilePhoto": "string (URL)", "company": "string", "position": "string", "bio": "string", "expertiseAreas": ["string[]"], "yearsExperience": "integer", "certifications": ["string[]"], "socialLinks": { "linkedin": "string | null", "twitter": "string | null", "github": "string | null" } }, "relatedSessions": [ { "sessionId": "uuid", "title": "string", "startTime": "ISO-8601 datetime", "sessionType": "string" } ] } - Used for: Display all session details including speaker info and related sessions in a single API call
- Performance: Single API call replaces 3 separate calls (session + speaker + related sessions)
- Query params:
User Action APIs
-
PATCH /api/v1/attendees/me
- Triggered by: User clicks [π Add to My Schedule] (authenticated users only)
- Payload:json
{ "schedule": { "add": [ { "sessionId": "uuid", "eventId": "uuid", "source": "session_modal" } ] } } - Returns: Updated attendee profile with schedule confirmationjson
{ "scheduleId": "uuid", "addedAt": "ISO-8601 datetime", "conflictingSessions": ["sessionId[]"] // empty if no conflicts } - Used for: Adds session to userβs personal schedule using consolidated Attendees API (Story 1.25), shows success toast message, handles conflicts if any
-
GET /api/v1/events/{eventId}/share-link (Event-level sharing, not session-specific)
- Triggered by: User clicks [π Share Session]
- Returns: Shareable event landing page URLjson
{ "shareUrl": "string (https://batbern.ch/events/{eventId})", "title": "string (event title for share preview)", "description": "string (includes session reference in share text: 'Check out this session: [Session Title]')", "imageUrl": "string (event banner)" } - Used for: Generates shareable event URL for social media, email, or copy to clipboard (no session-specific deep linking)
-
GET /api/v1/events/{eventId}/sessions/{sessionId}/slides
- Triggered by: User clicks [π Download Slides] (only if slidesAvailable = true)
- Returns: PDF file or redirect URL to S3/CloudFront
- Used for: Downloads session presentation slides, tracks download analytics
-
POST /api/v1/analytics/session-view
- Triggered by: Modal opens (automatic, no user action)
- Payload:json
{ "sessionId": "uuid", "eventId": "uuid", "userId": "uuid | null", "source": "landing_page", "timestamp": "ISO-8601 datetime" } - Returns: 204 No Content
- Used for: Track session popularity, modal view analytics, inform recommendations
Navigation Map
Primary Navigation Actions
-
[β] Close button β Closes modal
- Target: Returns to Current Event Landing Page (same page, modal closes)
- Context: No state change, scroll position preserved on landing page
- Behavior: Fade-out animation, remove modal from DOM, restore body scroll
-
[β Back to Agenda] link β Closes modal and scrolls to agenda
- Target: Current Event Landing Page, agenda section
- Context: Closes modal, scrolls page to agenda section
- Behavior: Modal closes, smooth scroll to #agenda anchor
-
[Register for Event β] button β Navigate to
Event Registrationpage- Target: Event Registration Form (story-2.4-event-registration.md)
- Context: eventId, source: βsession_modalβ, sessionId (to pre-register interest)
- Behavior: Full page navigation, modal closes automatically
-
[View Full Profile β] link β Navigate to
Speaker Profile Detail View- Target: Speaker Profile Detail View (story-7.1-speaker-profile-detail-view.md)
- Context: speakerId, source: βsession_modalβ
- Behavior: Closes current session modal, then navigates to speaker profile page (no modal stacking)
Secondary Navigation (Data Interactions)
-
Related session link click β Opens
Session Details Modalfor new session- Target: Session Details Modal for related session
- Context: New sessionId
- Behavior: Closes current modal first, then opens new session modal (no modal stacking, no content transition)
-
[π Add to My Schedule] button β Inline state update
- Target: Same modal (no navigation)
- Context: Updates userβs schedule, changes button state
- Behavior: Button changes to ββ Added to Scheduleβ with green checkmark, shows success toast
- Error handling: If conflict, shows conflict modal with options to resolve
-
[π Share Session] button β Opens
Share Modalor native share- Target: Share modal (desktop) or native share sheet (mobile)
- Context: Session title, description (no deep link URL - shares event landing page URL only)
- Behavior: On mobile, triggers Web Share API; on desktop, shows share options modal overlay with event landing page URL
Event-Driven Navigation
-
User not authenticated + clicks [π Add to My Schedule] β Opens
Login Modal- Target: Login/Registration modal
- Context: Return action = add session to schedule, sessionId
- Behavior: Shows login modal overlay with message βSign in to add sessions to your scheduleβ
- Post-login: Automatically adds session to schedule and shows success message
-
Slides not available yet (before event) β No navigation, shows tooltip
- Target: No navigation
- Behavior: Disabled button shows tooltip βSlides available after the eventβ
Error States & Redirects
-
Session not found (invalid sessionId) β Close modal, show error toast
- Target: Returns to Current Event Landing Page
- Behavior: Modal closes, error toast: βSession not found or no longer availableβ
-
API failure (500 error) β Show error state in modal
- Target: Modal remains open with error state
- Behavior: Shows error message in modal with [Retry] button to reload session data
-
Session canceled or removed β Show cancellation notice
- Target: Modal shows cancellation message instead of details
- Behavior: βThis session has been canceled. See updated agenda for alternatives.β
- Action: [View Updated Agenda] button closes modal and scrolls to agenda
Responsive Design Considerations
Mobile Layout Changes (<768px)
- Full-screen modal: Modal takes entire viewport (100vw Γ 100vh) with internal scrolling
- Close button: Larger tap target (44Γ44px minimum) positioned in top-right corner
- Speaker section: Speaker photo smaller (60Γ60px), info stacks below photo instead of beside
- Action buttons: Stack vertically, full-width with adequate spacing (16px between)
- Related sessions: Display as vertical list instead of horizontal
- Typography: Larger font sizes for readability (16px minimum body text)
- Share button: Triggers native share sheet on mobile devices
Tablet Layout Changes (768px - 1024px)
- Centered modal: Max-width 700px, centered with backdrop on sides
- Two-column layout: Speaker section and key takeaways side-by-side if space permits
- Action buttons: Remain horizontal but with responsive sizing
- Scroll behavior: Modal scrolls internally, page scroll disabled
Desktop Layout (>1024px)
- Centered modal: Max-width 900px, centered with darkened backdrop
- Hover states: All buttons show hover effects for better affordance
- Keyboard shortcuts: Display keyboard shortcut hints (ESC to close)
Mobile-Specific Interactions
- Swipe down gesture: Swipe down from top of modal to close (mobile only)
- Tap outside modal: Tap on backdrop closes modal (with visual feedback)
- Share via native sheet: Share button uses Web Share API on mobile for system sharing
- Add to My Schedule: Saves to BATbern personal schedule only (no native device calendar integration)
- Speaker photo tap: Tap on speaker photo opens full profile (not just link)
Accessibility Notes
-
Focus management:
- Focus trapped within modal when open
- First focusable element (close button) receives focus on open
- Focus returns to trigger element (session card) on close
- Tab order: Close β Speaker profile β Action buttons β Related sessions β Back/Register
-
Screen reader support:
- Modal announced as βDialog: Session Detailsβ with
role="dialog"andaria-modal="true" - Close button labeled βClose session details dialogβ
- All action buttons have descriptive
aria-labelattributes - Disabled slides button includes
aria-disabled="true"and tooltip text inaria-describedby
- Modal announced as βDialog: Session Detailsβ with
-
Keyboard navigation:
- ESC key closes modal
- TAB cycles through interactive elements
- SHIFT+TAB cycles backward
- ENTER/SPACE activates buttons and links
-
Color contrast:
- All text meets WCAG 2.1 AA standards (4.5:1 for body, 3:1 for large text)
- Interactive elements have sufficient contrast in all states (default, hover, focus, disabled)
-
Visual indicators:
- Focus indicators clearly visible (2px solid outline, high contrast color)
- Loading states announced with ARIA live regions
- Success/error toasts announced to screen readers
-
Content structure:
- Proper heading hierarchy (H2 for modal title, H3 for sections)
- Lists properly marked up with semantic HTML
- Time displayed in both human-readable and ISO-8601 format for screen readers
State Management
Local Component State
isOpen: boolean- Modal open/close state (managed by parent component)isLoadingSession: boolean- Loading state while fetching session detailsisLoadingSpeaker: boolean- Loading state while fetching speaker infoisAddingToSchedule: boolean- Loading state for βAdd to Scheduleβ actionisInSchedule: boolean- Whether session is already in userβs scheduleslideDownloadInProgress: boolean- Loading state for slide downloadshowShareOptions: boolean- Share modal visibility (desktop only)scrollPosition: number- Track modal scroll for analytics (time spent by section)
Global State (Zustand Store)
auth.user- Current user information (null if not authenticated)auth.isAuthenticated- Authentication statusattendee.mySchedule- List of sessionIds in userβs personal scheduleevents.currentEvent- Current event context (eventId, eventDate)
Server State (React Query)
-
sessionDetails - Cached session data with expanded speaker and related sessions (consolidated API)
- Query key:
['session', eventId, sessionId, 'speaker,relatedSessions'] - Cache time: 10 minutes
- Stale time: 5 minutes
- Refetch on mount: false (modal-specific data)
- Single API call replaces 3 separate queries (session + speaker + related sessions)
- Query key:
-
userSchedule - Userβs personal schedule, invalidated on add/remove
- Query key:
['attendee', 'me', 'schedule'] - Cache time: 5 minutes
- Refetch on window focus: true
- Managed via PATCH /api/v1/attendees/me (Story 1.25)
- Query key:
Real-Time Updates
-
Attendance count updates: WebSocket subscription to session registration updates
- Channel:
events/${eventId}/sessions/${sessionId}/registrations - Events:
registration.added,registration.removed - Behavior: Live update of βX/Y registeredβ counter and status indicator (βFilling up fastβ, βAlmost fullβ, βFullβ)
- Channel:
-
Session changes: WebSocket subscription to session updates (title, time, cancellation)
- Channel:
events/${eventId}/sessions/${sessionId} - Events:
session.updated,session.canceled,session.time_changed - Behavior: Show banner at top of modal with update notification
- Channel:
-
Slide availability: Poll every 30 seconds after event start to check for uploaded slides
- Condition: Only poll if
slidesAvailable === falseand event has started - Stop polling: When slides become available or modal closes
- Condition: Only poll if
Edge Cases & Error Handling
-
Empty State (No speaker assigned): Show placeholder: βSpeaker to be announcedβ with generic avatar
-
Loading State (Initial load): Display skeleton screens for session details, speaker info, and related sessions
-
Error State (Session not found): Show error message in modal: βSession not found. It may have been removed or rescheduled.β with [View Updated Agenda] button
-
Error State (API failure): Show error message with [Retry] button: βUnable to load session details. Please try again.β
-
Session canceled: Show prominent warning banner: ββ οΈ This session has been canceled. See updated agenda for alternatives.β Disable registration and schedule buttons
-
Time conflict: When adding to schedule, if another session overlaps, show conflict modal: βThis session conflicts with [Session Title] at [Time]. Which would you like to attend?β
-
Not authenticated + Add to Schedule: Show login prompt modal: βCreate a free account to build your personal scheduleβ with [Sign Up] and [Sign In] buttons
-
Slides not available: [Download Slides] button disabled with tooltip: βSlides will be available after the eventβ
-
Share API not supported: Fallback to copy-to-clipboard with confirmation toast: βLink copied to clipboardβ
-
Session full (capacity reached): Show βSession is fullβ badge (when registeredCount >= capacity), disable βAdd to Scheduleβ button, display message βThis session has reached capacityβ
-
Related sessions empty: Hide βRelated Sessionsβ section entirely if no related sessions found
-
Mobile landscape mode: Ensure modal scrollable in landscape orientation with proper safe area insets
-
Slow network: Show loading skeleton immediately, timeout after 15 seconds with retry option
-
Speaker photo failed to load: Show fallback initials avatar with speakerβs first and last name initials
-
Long session description: Show truncated text with βRead moreβ link that expands to full description
Change Log
| Date | Version | Description | Author |
|---|---|---|---|
| 2025-10-02 | 1.0 | Initial wireframe creation for Session Details Modal | Sally (UX Expert) |
| 2025-10-04 | 1.1 | Updated with stakeholder decisions: added real-time attendance, removed Q&A, no modal stacking, no calendar integration, no deep linking | Sally (UX Expert) |
| 2025-10-04 | 1.2 | Updated to use consolidated APIs from Stories 1.17, 1.19, 1.25: single session endpoint with ?include=speaker,relatedSessions (reduced 3 API calls to 1), schedule management via PATCH /api/v1/attendees/me | Winston (Architect) |
Review Notes
Stakeholder Feedback
- β βAdd to My Scheduleβ scope confirmed: Platform schedule only, no external calendar integration
- β Slides downloadable after event only (Download button disabled until event completion)
- β Real-time attendance counter approved for display
- β No modal stacking - close current before opening related session
- β No deep linking support in MVP
- β Q&A section, speaker ratings, and βother sessions by speakerβ deferred to future enhancements
Design Iterations
- Version 1.0: Initial creation based on current event landing page navigation flows
- Version 1.1: Updated based on stakeholder decisions:
- Added real-time attendance counter with status indicators
- Removed Q&A section (deferred)
- Clarified no modal stacking for related sessions
- Removed speaker ratings/reviews (deferred)
- Removed calendar app integration (platform schedule only)
- Removed deep linking support
- Removed βother sessions by speakerβ feature (deferred)
Open Questions
All open questions have been resolved:
-
β Real-time attendance count: Should we show real-time attendance count (β120/150 registeredβ)?
- DECISION: YES - Show live attendance counter with status indicators
- Display format: β87/150 registeredβ with status badge (βFilling up fastβ when >50%, βAlmost fullβ when >80%, βFullβ when at capacity)
- Updates via WebSocket for real-time accuracy
-
β Q&A section: Do we need a Q&A section for attendees to submit questions in advance?
- DECISION: NO - Not in MVP scope
- Q&A functionality deferred to future enhancement
- Focus on core session information and schedule management
-
β Related sessions navigation: Should related sessions be clickable from within the modal (modal stacking) or close current modal first?
- DECISION: Close current modal first - No modal stacking
- User experience: Click related session β current modal closes β new session modal opens
- Simpler state management and cleaner UX
-
β Speaker ratings/reviews: Should we display speaker rating/reviews from past events?
- DECISION: NO - Not in MVP scope
- Speaker ratings deferred to future enhancement (Epic 7)
- Focus on current session details and speaker credentials only
-
β Calendar app integration: Do we need to integrate with calendar apps for βAdd to My Scheduleβ (beyond authentication)?
- DECISION: NO - Platform schedule only
- βAdd to My Scheduleβ saves to BATbern personal schedule only
- No iCal export, no Google Calendar integration, no device calendar sync in MVP
- Users can view their schedule in attendee dashboard
-
β Deep linking support: Should the modal support deep linking (direct URL access)?
- DECISION: NO - No deep linking in MVP
- Modal only opens via user interaction on event landing page
- Share button shares event landing page URL only (not session-specific deep link)
- Simpler implementation and URL structure
-
β Other sessions by speaker: What happens if a speaker has multiple sessions at the event - show βOther sessions by this speakerβ?
- DECISION: NO - Not in MVP scope
- Related sessions shown by topic/theme only, not by speaker
- Speakerβs other sessions could be added in future enhancement
- Users can find speakerβs sessions via speaker profile page (Story 7.1)