168 lines
6.2 KiB
React
168 lines
6.2 KiB
React
import React, { useState, useEffect } from 'react';
|
||
import './ComparisonScreen.css';
|
||
|
||
const ComparisonScreen = ({
|
||
question,
|
||
userAnswer,
|
||
otherPlayers,
|
||
currentQuestionNumber,
|
||
totalQuestions,
|
||
onContinue
|
||
}) => {
|
||
const [showConfetti, setShowConfetti] = useState(false);
|
||
const [sortedPlayers, setSortedPlayers] = useState([]);
|
||
|
||
useEffect(() => {
|
||
// Если ответ правильный, показываем конфетти
|
||
if (userAnswer.isCorrect === true) {
|
||
setShowConfetti(true);
|
||
setTimeout(() => setShowConfetti(false), 3000);
|
||
}
|
||
|
||
// Сортируем игроков по правильности ответа и времени
|
||
const allPlayers = [
|
||
{
|
||
name: "Вы",
|
||
avatar: "👤",
|
||
isCorrect: userAnswer.isCorrect,
|
||
answerText: userAnswer.answerText,
|
||
timeSpent: userAnswer.timeSpent,
|
||
isUser: true
|
||
},
|
||
...otherPlayers
|
||
];
|
||
|
||
const sorted = allPlayers.sort((a, b) => {
|
||
if (a.isCorrect === b.isCorrect) {
|
||
return a.timeSpent - b.timeSpent;
|
||
}
|
||
return b.isCorrect ? 1 : -1;
|
||
});
|
||
|
||
setSortedPlayers(sorted);
|
||
}, [userAnswer, otherPlayers]);
|
||
|
||
const getRankEmoji = (index) => {
|
||
switch(index) {
|
||
case 0: return "🥇";
|
||
case 1: return "🥈";
|
||
case 2: return "🥉";
|
||
default: return `${index + 1}️⃣`;
|
||
}
|
||
};
|
||
|
||
const getScoreChange = (isCorrect, timeSpent) => {
|
||
if (isCorrect) {
|
||
if (timeSpent < 10) return "+15 ⚡";
|
||
if (timeSpent < 20) return "+10 ✨";
|
||
return "+5 📝";
|
||
}
|
||
return "0 ❌";
|
||
};
|
||
|
||
const getSpeedRating = (timeSpent) => {
|
||
if (timeSpent < 10) return "Молниеносно! 🚀";
|
||
if (timeSpent < 20) return "Быстро ⚡";
|
||
if (timeSpent < 30) return "Средне 🐌";
|
||
return "Медленно 🐢";
|
||
};
|
||
|
||
return (
|
||
<div className="comparison-container">
|
||
{showConfetti && <div className="confetti">🎉✨🎊</div>}
|
||
|
||
<div className="comparison-card">
|
||
<div className="comparison-header">
|
||
<h2>Результаты вопроса {currentQuestionNumber}</h2>
|
||
<div className="question-preview">
|
||
<p className="question-text-preview">{question.text}</p>
|
||
</div>
|
||
</div>
|
||
|
||
<div className="your-result">
|
||
<div className={`result-badge ${userAnswer.isCorrect ? 'correct' : userAnswer.isCorrect === null ? 'pending' : 'incorrect'}`}>
|
||
{userAnswer.isCorrect === true && "✅ Правильно!"}
|
||
{userAnswer.isCorrect === false && "❌ Неправильно!"}
|
||
{userAnswer.isCorrect === null && "⏳ Ожидает оценки"}
|
||
</div>
|
||
|
||
<div className="your-stats">
|
||
<div className="stat-item">
|
||
<span className="stat-label">Ваш ответ:</span>
|
||
<span className="stat-value">{userAnswer.answerText}</span>
|
||
</div>
|
||
<div className="stat-item">
|
||
<span className="stat-label">Время ответа:</span>
|
||
<span className="stat-value">{userAnswer.timeSpent} сек</span>
|
||
</div>
|
||
<div className="stat-item">
|
||
<span className="stat-label">Скорость:</span>
|
||
<span className="stat-value">{getSpeedRating(userAnswer.timeSpent)}</span>
|
||
</div>
|
||
<div className="stat-item">
|
||
<span className="stat-label">Очки:</span>
|
||
<span className="stat-value points">{getScoreChange(userAnswer.isCorrect, userAnswer.timeSpent)}</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div className="comparison-section">
|
||
<h3>🏆 Сравнение с другими игроками</h3>
|
||
<div className="players-ranking">
|
||
{sortedPlayers.map((player, index) => (
|
||
<div key={index} className={`player-row ${player.isUser ? 'current-user' : ''}`}>
|
||
<div className="player-rank">{getRankEmoji(index)}</div>
|
||
<div className="player-avatar">{player.avatar}</div>
|
||
<div className="player-info">
|
||
<div className="player-name">
|
||
{player.name}
|
||
{player.isUser && <span className="user-badge">(Вы)</span>}
|
||
</div>
|
||
<div className="player-answer">{player.answerText}</div>
|
||
</div>
|
||
<div className="player-stats">
|
||
<div className={`player-correct ${player.isCorrect ? 'correct' : 'incorrect'}`}>
|
||
{player.isCorrect ? "✓" : "✗"}
|
||
</div>
|
||
<div className="player-time">{player.timeSpent}с</div>
|
||
</div>
|
||
</div>
|
||
))}
|
||
</div>
|
||
</div>
|
||
|
||
<div className="statistics-summary">
|
||
<h3>📊 Статистика вопроса</h3>
|
||
<div className="stats-grid">
|
||
<div className="stat-card">
|
||
<div className="stat-number">
|
||
{Math.round((sortedPlayers.filter(p => p.isCorrect).length / sortedPlayers.length) * 100)}%
|
||
</div>
|
||
<div className="stat-description">игроков ответили правильно</div>
|
||
</div>
|
||
<div className="stat-card">
|
||
<div className="stat-number">
|
||
{Math.min(...sortedPlayers.map(p => p.timeSpent))}с
|
||
</div>
|
||
<div className="stat-description">самый быстрый ответ</div>
|
||
</div>
|
||
<div className="stat-card">
|
||
<div className="stat-number">
|
||
{Math.round(sortedPlayers.reduce((sum, p) => sum + p.timeSpent, 0) / sortedPlayers.length)}с
|
||
</div>
|
||
<div className="stat-description">среднее время ответа</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div className="navigation-buttons">
|
||
<button onClick={onContinue} className="continue-button">
|
||
{currentQuestionNumber === totalQuestions ? "Завершить викторину 🏁" : "Следующий вопрос →"}
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
);
|
||
};
|
||
|
||
export default ComparisonScreen; |