/** * PerformanceSummary - Interview Analytics Summary Component * * Displays comprehensive performance metrics after Strict/High-Pressure interviews: * - Eye Contact Analysis * - Posture/Stability Score * - Filler Word Report * - Silence Analysis * - Speaking Speed * - Video Playback */ import React, { useState, useRef } from 'react'; import { Eye, Activity, MessageSquare, Clock, Zap, Video, Download, ChevronDown, ChevronUp, CheckCircle, AlertTriangle, XCircle, Award, TrendingUp } from 'lucide-react'; import './PerformanceSummary.css'; export default function PerformanceSummary({ summary, onClose, onDownloadVideo }) { const [expandedSections, setExpandedSections] = useState({ eyeContact: true, posture: true, fillerWords: false, silence: false, speed: true, }); const videoRef = useRef(null); if (!summary) return null; const toggleSection = (section) => { setExpandedSections(prev => ({ ...prev, [section]: !prev[section] })); }; const getGradeIcon = (grade) => { if (grade === 'Excellent') return ; if (grade === 'Good') return ; if (grade === 'Fair') return ; return ; }; const getScoreColor = (score) => { if (score >= 80) return 'excellent'; if (score >= 60) return 'good'; if (score >= 40) return 'fair'; return 'poor'; }; const handleDownloadVideo = () => { if (summary.video?.url) { const a = document.createElement('a'); a.href = summary.video.url; a.download = `interview-recording-${new Date().toISOString().split('T')[0]}.webm`; document.body.appendChild(a); a.click(); document.body.removeChild(a); } }; return (
{/* Header */}

Interview Performance Analysis

{summary.mode === 'strict' ? 'Strict Mode' : 'High-Pressure Mode'} Interview Complete

{/* Overall Score */}
{summary.overallScore} Overall
Eye Contact {summary.eyeContact?.percentage || 0}%
Stability {summary.posture?.stabilityScore || 0}%
Speed {summary.speed?.wordsPerMinute || 0} WPM
{/* Video Section */} {summary.video?.available && summary.video?.url && (
)} {/* Detailed Metrics */}
{/* Eye Contact */}
toggleSection('eyeContact')}>

Eye Contact Analysis

{getGradeIcon(summary.eyeContact?.grade)}
{expandedSections.eyeContact ? : }
{expandedSections.eyeContact && (
Eye Contact Time {summary.eyeContact?.percentage}%
Grade {summary.eyeContact?.grade}

{summary.eyeContact?.recommendation}

)}
{/* Posture/Stability */}
toggleSection('posture')}>

Posture & Stability

{getGradeIcon(summary.posture?.grade)}
{expandedSections.posture ? : }
{expandedSections.posture && (
Stability Score {summary.posture?.stabilityScore}%
Fidget Count {summary.posture?.fidgetCount}

{summary.posture?.recommendation}

)}
{/* Filler Words */}
toggleSection('fillerWords')}>

Filler Words

10 ? 'warning' : 'good'}`}> {summary.fillerWords?.totalCount || 0} found
{expandedSections.fillerWords ? : }
{expandedSections.fillerWords && (
{Object.entries(summary.fillerWords?.breakdown || {}).map(([word, count]) => (
"{word}" {count}x
))} {Object.keys(summary.fillerWords?.breakdown || {}).length === 0 && (

No filler words detected! 🎉

)}

{summary.fillerWords?.recommendation}

)}
{/* Silence Analysis */}
toggleSection('silence')}>

Silence Analysis

3 ? 'warning' : 'good'}`}> {summary.silence?.instanceCount || 0} pauses
{expandedSections.silence ? : }
{expandedSections.silence && (
Total Silence {summary.silence?.totalSilenceSeconds}s
Longest Pause {summary.silence?.longestSilenceSeconds}s

{summary.silence?.recommendation}

)}
{/* Speaking Speed */}
toggleSection('speed')}>

Speaking Speed

{summary.speed?.wordsPerMinute} WPM
{expandedSections.speed ? : }
{expandedSections.speed && (
Too Slow Optimal (120-160) Too Fast

{summary.speed?.grade}

{summary.speed?.recommendation}

)}
{/* Timed Out Questions */} {summary.timer?.timedOutQuestions > 0 && (

Time Management

⚠️ You ran out of time on {summary.timer.timedOutQuestions} question(s).

Practice giving concise answers. Aim to complete your response within the time limit.

)}
{/* Footer */}

💡 These metrics help you improve your interview performance. Practice makes perfect!

); }