Files
SerpentRace/SerpentRace_Frontend/src/pages/Game/ConsequenceModal.jsx
T

203 lines
7.8 KiB
React
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import React from "react"
import { motion, AnimatePresence } from "framer-motion"
/**
* ConsequenceModal - Következmények megjelenítése (jó/rossz válasz után)
*
* @param {Object} props
* @param {boolean} props.isOpen - Modal megjelenítése
* @param {Function} props.onClose - Modal bezárása
* @param {boolean} props.isCorrect - Helyes volt-e a válasz
* @param {string} props.consequence - Következmény szövege
* @param {number} props.consequenceType - Következmény típusa:
* 0 = MOVE_FORWARD (előre lépés)
* 1 = MOVE_BACKWARD (hátra lépés)
* 2 = LOSE_TURN (körkihagyás)
* 3 = EXTRA_TURN (extra kör)
* 5 = GO_TO_START (vissza a starthoz)
* @param {number} props.consequenceValue - Következmény értéke (hány mező/kör)
* @param {string} props.playerAnswer - Játékos válasza
* @param {string} props.correctAnswer - Helyes válasz
* @param {string} props.explanation - Magyarázat
*/
const ConsequenceModal = ({
isOpen,
onClose,
isCorrect,
consequence,
consequenceType,
consequenceValue,
playerAnswer,
correctAnswer,
explanation
}) => {
const getConsequenceIcon = (type) => {
switch(type) {
case 0: return "🚀" // MOVE_FORWARD
case 1: return "⬅️" // MOVE_BACKWARD
case 2: return "😴" // LOSE_TURN
case 3: return "🎉" // EXTRA_TURN
case 5: return "🏁" // GO_TO_START
default: return "📢"
}
}
const getConsequenceText = (type, value) => {
switch(type) {
case 0: return `${value} mezőt léphetsz előre! 🚀`
case 1: return `${value} mezőt lépsz vissza! `
case 2: return `${value} kört ki kell hagyni! `
case 3: return `${value} extra kör jár neked! 🎉`
case 5: return "Vissza a starthoz! 🏁"
default: return consequence || "Következmény"
}
}
const getBgGradient = () => {
if (isCorrect) {
return "from-green-600 via-teal-600 to-green-600"
}
return "from-red-600 via-orange-600 to-red-600"
}
const getBorderColor = () => {
if (isCorrect) return "border-green-500/50"
return "border-red-500/50"
}
if (!isOpen) return null
return (
<AnimatePresence>
{isOpen && (
<div className="fixed inset-0 z-50 flex items-center justify-center p-4">
{/* Backdrop */}
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
className="absolute inset-0 bg-black/80 backdrop-blur-sm"
onClick={onClose}
/>
{/* Modal Content */}
<motion.div
initial={{ scale: 0.5, opacity: 0, rotate: -10 }}
animate={{ scale: 1, opacity: 1, rotate: 0 }}
exit={{ scale: 0.5, opacity: 0, rotate: 10 }}
transition={{ type: "spring", duration: 0.6 }}
className={`relative bg-gradient-to-br from-gray-900 via-gray-800 to-gray-900 rounded-2xl shadow-2xl border-2 ${getBorderColor()} max-w-2xl w-full overflow-hidden`}
>
{/* Header with result */}
<div className={`bg-gradient-to-r ${getBgGradient()} p-6 relative overflow-hidden`}>
<div className="absolute inset-0 bg-gradient-to-r from-transparent via-white/20 to-transparent animate-pulse" />
<div className="relative text-center">
<motion.div
initial={{ scale: 0 }}
animate={{ scale: 1 }}
transition={{ delay: 0.2, type: "spring" }}
className="text-8xl mb-2"
>
{isCorrect ? "✅" : "❌"}
</motion.div>
<h2 className="text-3xl font-bold text-white mb-2">
{isCorrect ? "Helyes válasz!" : "Helytelen válasz!"}
</h2>
<p className="text-white/90 text-lg">
{isCorrect ? "Gratulálunk! 🎉" : "Ne add fel! 💪"}
</p>
</div>
</div>
{/* Content */}
<div className="p-6 space-y-6">
{/* Player Answer */}
{playerAnswer && (
<div className="bg-gray-800/50 rounded-xl p-4 border border-gray-700">
<div className="flex items-start gap-3">
<div className="text-2xl">💭</div>
<div className="flex-1">
<p className="text-gray-400 text-sm mb-1">A te válaszod:</p>
<p className="text-white font-semibold">{playerAnswer}</p>
</div>
</div>
</div>
)}
{/* Correct Answer - ha helytelen volt */}
{!isCorrect && correctAnswer && (
<div className="bg-green-900/20 rounded-xl p-4 border border-green-500/30">
<div className="flex items-start gap-3">
<div className="text-2xl"></div>
<div className="flex-1">
<p className="text-green-300 text-sm mb-1">A helyes válasz:</p>
<p className="text-white font-semibold">{correctAnswer}</p>
</div>
</div>
</div>
)}
{/* Explanation */}
{explanation && (
<div className="bg-blue-900/20 rounded-xl p-4 border border-blue-500/30">
<div className="flex items-start gap-3">
<div className="text-2xl">💡</div>
<div className="flex-1">
<p className="text-blue-300 text-sm mb-1">Magyarázat:</p>
<p className="text-gray-300">{explanation}</p>
</div>
</div>
</div>
)}
{/* Consequence */}
<motion.div
initial={{ scale: 0.8, opacity: 0 }}
animate={{ scale: 1, opacity: 1 }}
transition={{ delay: 0.4 }}
className={`${isCorrect ? 'bg-gradient-to-br from-green-900/30 to-teal-900/30 border-green-500/40' : 'bg-gradient-to-br from-red-900/30 to-orange-900/30 border-red-500/40'} rounded-xl p-6 border-2`}
>
<div className="text-center">
<motion.div
animate={{ rotate: [0, 10, -10, 10, 0] }}
transition={{ repeat: Infinity, duration: 2 }}
className="text-6xl mb-3"
>
{getConsequenceIcon(consequenceType)}
</motion.div>
<h3 className={`text-xl font-bold mb-2 ${isCorrect ? 'text-green-300' : 'text-red-300'}`}>
Következmény:
</h3>
<p className="text-white text-2xl font-bold">
{getConsequenceText(consequenceType, consequenceValue)}
</p>
</div>
</motion.div>
{/* Close Button */}
<button
onClick={onClose}
className={`w-full bg-gradient-to-r ${
isCorrect
? 'from-green-600 to-teal-600 hover:from-green-500 hover:to-teal-500 border-green-500/50'
: 'from-red-600 to-orange-600 hover:from-red-500 hover:to-orange-500 border-red-500/50'
} text-white font-bold py-4 px-6 rounded-xl shadow-lg
transform transition-all duration-200 hover:scale-105 active:scale-95 border`}
>
<div className="flex items-center justify-center gap-2">
<span className="text-2xl">👍</span>
<span className="text-lg">Rendben, folytatom!</span>
</div>
</button>
</div>
</motion.div>
</div>
)}
</AnimatePresence>
)
}
export default ConsequenceModal