/**
* 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 && (
Your Interview Recording
Duration: {summary.video.duration}s
)}
{/* 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 && (
⚠️ 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!
);
}