| import React, { useState, useEffect } from 'react';
|
| import { Link } from 'react-router-dom';
|
| import { createPageUrl } from '@/utils';
|
| import { motion, AnimatePresence } from 'framer-motion';
|
| import { Brain, CheckCircle2, XCircle, ArrowLeft, Trophy, RotateCcw, Sparkles, Target } from 'lucide-react';
|
| import { Button } from '@/components/ui/button';
|
| import { Progress } from '@/components/ui/progress';
|
| import confetti from 'canvas-confetti';
|
|
|
| const questions = [
|
| {
|
| id: 1,
|
| question: "In YOLO (You Only Look Once), what makes it faster than traditional object detection methods?",
|
| options: [
|
| "It uses smaller images",
|
| "It processes the entire image in a single pass instead of multiple regions",
|
| "It only detects one object at a time",
|
| "It uses black and white images"
|
| ],
|
| correct: 1,
|
| topic: "Object Detection"
|
| },
|
| {
|
| id: 2,
|
| question: "What does a confidence score of 95% mean in object detection?",
|
| options: [
|
| "The object is 95% visible in the image",
|
| "The AI is 95% certain about its prediction",
|
| "95% of the object is inside the bounding box",
|
| "The detection took 95% of the processing time"
|
| ],
|
| correct: 1,
|
| topic: "Object Detection"
|
| },
|
| {
|
| id: 3,
|
| question: "How many keypoints does a standard pose estimation model typically track on the human body?",
|
| options: [
|
| "7 keypoints",
|
| "10 keypoints",
|
| "17 keypoints",
|
| "25 keypoints"
|
| ],
|
| correct: 2,
|
| topic: "Pose Estimation"
|
| },
|
| {
|
| id: 4,
|
| question: "What are 'skeleton lines' in pose estimation?",
|
| options: [
|
| "Lines that show bones in an X-ray",
|
| "Connections between keypoints showing body structure",
|
| "Errors in the detection algorithm",
|
| "Grid lines dividing the image"
|
| ],
|
| correct: 1,
|
| topic: "Pose Estimation"
|
| },
|
| {
|
| id: 5,
|
| question: "Which of these is NOT one of the 7 basic emotions in FER (Facial Emotion Recognition)?",
|
| options: [
|
| "Fear",
|
| "Disgust",
|
| "Confused",
|
| "Surprise"
|
| ],
|
| correct: 2,
|
| topic: "Emotion Recognition"
|
| },
|
| {
|
| id: 6,
|
| question: "Why do facial emotion recognition models use 48×48 pixel images?",
|
| options: [
|
| "Larger images don't work with AI",
|
| "Smaller size allows faster processing while retaining key facial features",
|
| "48×48 is the size of human faces",
|
| "It's the only size cameras can capture"
|
| ],
|
| correct: 1,
|
| topic: "Emotion Recognition"
|
| },
|
| {
|
| id: 7,
|
| question: "Which technology would be BEST for analyzing a dancer's movements in real-time?",
|
| options: [
|
| "Object Detection",
|
| "Emotion Recognition",
|
| "Pose Estimation",
|
| "Voice Recognition"
|
| ],
|
| correct: 2,
|
| topic: "Pose Estimation"
|
| },
|
| {
|
| id: 8,
|
| question: "In object detection, what happens during 'non-max suppression'?",
|
| options: [
|
| "The AI stops detecting objects",
|
| "Duplicate or overlapping bounding boxes are removed",
|
| "The confidence threshold is lowered",
|
| "The image brightness is reduced"
|
| ],
|
| correct: 1,
|
| topic: "Object Detection"
|
| },
|
| {
|
| id: 9,
|
| question: "Why is consent important before using emotion recognition technology on someone?",
|
| options: [
|
| "It makes the AI more accurate",
|
| "People have a right to privacy and to know when they're being analyzed",
|
| "It's required by all cameras",
|
| "Consent improves the lighting in photos"
|
| ],
|
| correct: 1,
|
| topic: "Emotion Recognition"
|
| },
|
| {
|
| id: 10,
|
| question: "What is the main advantage of using grayscale images in emotion recognition instead of color?",
|
| options: [
|
| "Grayscale images look more professional",
|
| "Color doesn't exist in emotions",
|
| "It reduces processing complexity and focuses on facial structure rather than skin tone",
|
| "Grayscale cameras are cheaper"
|
| ],
|
| correct: 2,
|
| topic: "Emotion Recognition"
|
| },
|
| {
|
| id: 11,
|
| question: "If pose estimation detects 2 people in a video, how many total keypoints might it track?",
|
| options: [
|
| "17 keypoints total",
|
| "34 keypoints (17 per person)",
|
| "25 keypoints total",
|
| "10 keypoints total"
|
| ],
|
| correct: 1,
|
| topic: "Pose Estimation"
|
| },
|
| {
|
| id: 12,
|
| question: "What is a potential bias concern with emotion recognition AI?",
|
| options: [
|
| "It works too slowly",
|
| "It might perform differently across different cultures, ages, or demographics",
|
| "It can only detect happy emotions",
|
| "It requires too much computer power"
|
| ],
|
| correct: 1,
|
| topic: "Emotion Recognition"
|
| }
|
| ];
|
|
|
|
|
| const COMPLETED_KEY = 'completedChapters_v1';
|
| const TTL_MS = 60 * 60 * 1000;
|
|
|
| function checkLessonsCompleted() {
|
| try {
|
| const raw = localStorage.getItem(COMPLETED_KEY);
|
| if (!raw) return false;
|
|
|
| const parsed = JSON.parse(raw);
|
| const savedAt = parsed?.savedAt;
|
| const value = parsed?.value;
|
|
|
| if (!Array.isArray(value) || typeof savedAt !== 'number') return false;
|
|
|
| if (Date.now() - savedAt > TTL_MS) {
|
| localStorage.removeItem(COMPLETED_KEY);
|
| return false;
|
| }
|
|
|
| return value.length === 3;
|
| } catch {
|
| return false;
|
| }
|
| }
|
|
|
| export default function Quiz() {
|
| const [started, setStarted] = useState(false);
|
| const [currentQuestion, setCurrentQuestion] = useState(0);
|
| const [selectedAnswer, setSelectedAnswer] = useState(null);
|
| const [showResult, setShowResult] = useState(false);
|
| const [score, setScore] = useState(0);
|
| const [answers, setAnswers] = useState([]);
|
| const [finished, setFinished] = useState(false);
|
|
|
| const [allLessonsCompleted, setAllLessonsCompleted] = useState(checkLessonsCompleted);
|
|
|
|
|
| useEffect(() => {
|
| if (finished && score === questions.length) {
|
| triggerConfetti();
|
| }
|
| }, [finished, score]);
|
|
|
| const triggerConfetti = () => {
|
| const duration = 5 * 1000;
|
| const animationEnd = Date.now() + duration;
|
| const defaults = { startVelocity: 30, spread: 360, ticks: 60, zIndex: 0 };
|
|
|
| const random = (min, max) => Math.random() * (max - min) + min;
|
|
|
| const interval = setInterval(function() {
|
| const timeLeft = animationEnd - Date.now();
|
|
|
| if (timeLeft <= 0) {
|
| return clearInterval(interval);
|
| }
|
|
|
| const particleCount = 50 * (timeLeft / duration);
|
|
|
|
|
| confetti({
|
| ...defaults,
|
| particleCount,
|
| origin: { x: random(0.1, 0.3), y: Math.random() - 0.2 }
|
| });
|
| confetti({
|
| ...defaults,
|
| particleCount,
|
| origin: { x: random(0.7, 0.9), y: Math.random() - 0.2 }
|
| });
|
| }, 250);
|
| };
|
|
|
| const handleStart = () => {
|
| setStarted(true);
|
| setCurrentQuestion(0);
|
| setScore(0);
|
| setAnswers([]);
|
| setFinished(false);
|
| };
|
|
|
| const handleAnswer = (index) => {
|
| if (showResult) return;
|
|
|
| setSelectedAnswer(index);
|
| setShowResult(true);
|
|
|
| const isCorrect = index === questions[currentQuestion].correct;
|
| if (isCorrect) {
|
| setScore(score + 1);
|
| }
|
|
|
| setAnswers([...answers, { questionId: currentQuestion, selected: index, correct: isCorrect }]);
|
| };
|
|
|
| const handleNext = () => {
|
| if (currentQuestion < questions.length - 1) {
|
| setCurrentQuestion(currentQuestion + 1);
|
| setSelectedAnswer(null);
|
| setShowResult(false);
|
| } else {
|
| setFinished(true);
|
| }
|
| };
|
|
|
| const getScoreMessage = () => {
|
| const percentage = (score / questions.length) * 100;
|
| if (percentage === 100) return { emoji: "🏆", message: "PERFECT SCORE! You're an AI Vision Master!" };
|
| if (percentage >= 80) return { emoji: "🌟", message: "Amazing! You really know your AI stuff!" };
|
| if (percentage >= 60) return { emoji: "👍", message: "Good job! Keep learning and you'll be an expert!" };
|
| if (percentage >= 40) return { emoji: "📚", message: "Nice try! Review the lessons and try again!" };
|
| return { emoji: "💪", message: "Don't give up! Go through the lessons and come back stronger!" };
|
| };
|
|
|
|
|
| if (!started) {
|
| return (
|
| <div className="min-h-screen bg-gradient-to-br from-slate-900 via-purple-900 to-slate-900 pt-24 pb-12 px-6">
|
| <div className="fixed inset-0 overflow-hidden pointer-events-none">
|
| <div className="absolute top-20 left-10 w-72 h-72 bg-yellow-500/20 rounded-full blur-3xl animate-pulse" />
|
| <div className="absolute bottom-20 right-10 w-96 h-96 bg-orange-500/20 rounded-full blur-3xl animate-pulse" />
|
| </div>
|
|
|
| <div className="max-w-2xl mx-auto relative text-center">
|
| <Link to={createPageUrl('Home')}>
|
| <Button className="text-white/70 hover:text-white mb-8 bg-transparent border-0 hover:bg-white/5">
|
| <ArrowLeft className="w-4 h-4 mr-2" />
|
| Back to Home
|
| </Button>
|
| </Link>
|
|
|
| <motion.div
|
| initial={{ scale: 0 }}
|
| animate={{ scale: 1 }}
|
| transition={{ type: "spring" }}
|
| className="w-32 h-32 mx-auto rounded-3xl bg-gradient-to-br from-yellow-500 to-orange-500 flex items-center justify-center shadow-2xl shadow-yellow-500/30 mb-8"
|
| >
|
| <Target className="w-16 h-16 text-white" />
|
| </motion.div>
|
|
|
| <motion.h1
|
| initial={{ opacity: 0, y: 20 }}
|
| animate={{ opacity: 1, y: 0 }}
|
| className="text-4xl md:text-5xl font-black text-white mb-4"
|
| >
|
| AI Vision Quiz
|
| </motion.h1>
|
|
|
| <motion.p
|
| initial={{ opacity: 0, y: 20 }}
|
| animate={{ opacity: 1, y: 0 }}
|
| transition={{ delay: 0.1 }}
|
| className="text-xl text-white/70 mb-8"
|
| >
|
| Test your knowledge with {questions.length} questions about Object Detection, Pose Estimation, and Emotion Recognition!
|
| </motion.p>
|
|
|
| <motion.div
|
| initial={{ opacity: 0, y: 20 }}
|
| animate={{ opacity: 1, y: 0 }}
|
| transition={{ delay: 0.2 }}
|
| className="bg-white/5 backdrop-blur-xl rounded-3xl p-8 border border-white/10 mb-8"
|
| >
|
| <div className="grid grid-cols-3 gap-4 text-center">
|
| <div>
|
| <div className="text-3xl font-bold text-cyan-400">{questions.length}</div>
|
| <div className="text-white/60">Questions</div>
|
| </div>
|
| <div>
|
| <div className="text-3xl font-bold text-purple-400">3</div>
|
| <div className="text-white/60">Topics</div>
|
| </div>
|
| <div>
|
| <div className="text-3xl font-bold text-emerald-400">∞</div>
|
| <div className="text-white/60">Retries</div>
|
| </div>
|
| </div>
|
| </motion.div>
|
|
|
| <motion.div
|
| initial={{ opacity: 0, y: 20 }}
|
| animate={{ opacity: 1, y: 0 }}
|
| transition={{ delay: 0.3 }}
|
| >
|
| {allLessonsCompleted ? (
|
| <Button
|
| onClick={handleStart}
|
| size="lg"
|
| className="text-xl px-12 py-8 bg-gradient-to-r from-yellow-500 to-orange-500 hover:from-yellow-600 hover:to-orange-600 rounded-2xl shadow-2xl shadow-orange-500/30 text-white font-bold border-0 transition-all hover:scale-105"
|
| >
|
| <Sparkles className="w-6 h-6 mr-2" />
|
| Start Quiz
|
| </Button>
|
| ) : (
|
| <div>
|
| <Button
|
| disabled
|
| size="lg"
|
| className="text-xl px-12 py-8 bg-slate-700 text-slate-400 rounded-2xl font-bold border-0 cursor-not-allowed opacity-60 mb-4"
|
| >
|
| 🔒 Quiz Locked
|
| </Button>
|
| <p className="text-white/60">Complete all 3 lessons to unlock the quiz!</p>
|
| <Link to={createPageUrl('Lessons')} className="inline-block mt-4">
|
| <Button className="bg-blue-600 hover:bg-blue-700 text-white border-0 rounded-xl px-6 py-3">
|
| Go to Lessons
|
| </Button>
|
| </Link>
|
| </div>
|
| )}
|
| </motion.div>
|
| </div>
|
| </div>
|
| );
|
| }
|
|
|
|
|
| if (finished) {
|
| const { emoji, message } = getScoreMessage();
|
| const percentage = Math.round((score / questions.length) * 100);
|
|
|
| return (
|
| <div className="min-h-screen bg-gradient-to-br from-slate-900 via-purple-900 to-slate-900 pt-24 pb-12 px-6">
|
| <div className="fixed inset-0 overflow-hidden pointer-events-none">
|
| <div className="absolute top-20 left-10 w-72 h-72 bg-yellow-500/20 rounded-full blur-3xl animate-pulse" />
|
| <div className="absolute bottom-20 right-10 w-96 h-96 bg-orange-500/20 rounded-full blur-3xl animate-pulse" />
|
| </div>
|
|
|
| <div className="max-w-2xl mx-auto relative">
|
| <motion.div
|
| initial={{ scale: 0 }}
|
| animate={{ scale: 1 }}
|
| transition={{ type: "spring" }}
|
| className="text-center"
|
| >
|
| <div className="text-8xl mb-6">{emoji}</div>
|
|
|
| <h1 className="text-4xl md:text-5xl font-black text-white mb-4">
|
| Quiz Complete!
|
| </h1>
|
|
|
| <div className="bg-white/5 backdrop-blur-xl rounded-3xl p-8 border border-white/10 mb-8">
|
| <div className="text-6xl font-black text-transparent bg-clip-text bg-gradient-to-r from-yellow-400 to-orange-400 mb-2">
|
| {score}/{questions.length}
|
| </div>
|
| <div className="text-xl text-white/70 mb-6">
|
| {percentage}% Correct
|
| </div>
|
| <Progress value={percentage} className="h-4 bg-white/10" />
|
| <p className="text-white/80 mt-6 text-lg">{message}</p>
|
| </div>
|
|
|
| {/* Answer Summary */}
|
| <div className="bg-white/5 backdrop-blur-xl rounded-3xl p-6 border border-white/10 mb-8">
|
| <h3 className="text-lg font-bold text-white mb-4">Your Answers</h3>
|
| <div className="grid grid-cols-5 gap-2">
|
| {answers.map((answer, i) => (
|
| <motion.div
|
| key={i}
|
| initial={{ scale: 0 }}
|
| animate={{ scale: 1 }}
|
| transition={{ delay: i * 0.05 }}
|
| className={`w-12 h-12 rounded-xl flex items-center justify-center font-bold text-white ${
|
| answer.correct
|
| ? 'bg-gradient-to-br from-emerald-500 to-teal-500'
|
| : 'bg-gradient-to-br from-red-500 to-rose-500'
|
| }`}
|
| >
|
| {i + 1}
|
| </motion.div>
|
| ))}
|
| </div>
|
| </div>
|
|
|
| <div className="flex flex-col sm:flex-row gap-4 justify-center mb-12">
|
| <Button
|
| onClick={handleStart}
|
| size="lg"
|
| className="bg-gradient-to-r from-yellow-500 to-orange-500 hover:from-yellow-600 hover:to-orange-600 rounded-xl text-white font-bold border-0 px-8 py-6 text-lg shadow-xl shadow-orange-500/25 transition-all hover:scale-105"
|
| >
|
| <RotateCcw className="w-5 h-5 mr-2" />
|
| Try Again
|
| </Button>
|
| <Link to={createPageUrl('Lessons')}>
|
| <Button
|
| size="lg"
|
| className="border-2 border-white/30 text-white bg-white/5 hover:bg-white/10 rounded-xl w-full px-8 py-6 text-lg font-bold transition-all"
|
| >
|
| Review Lessons
|
| </Button>
|
| </Link>
|
| </div>
|
|
|
| {/* Test It Yourself Section */}
|
| <motion.div
|
| initial={{ opacity: 0, y: 20 }}
|
| animate={{ opacity: 1, y: 0 }}
|
| transition={{ delay: 0.3 }}
|
| className="bg-gradient-to-br from-blue-500/10 to-purple-500/10 rounded-3xl p-10 border border-blue-500/20"
|
| >
|
| <div className="text-center mb-6">
|
| <div className="text-5xl mb-4">🚀</div>
|
| <h2 className="text-3xl font-black text-white mb-3">Ready to Test It Yourself?</h2>
|
| <p className="text-white/70 text-lg mb-8">
|
| Now that you've mastered the concepts, try building your own AI vision projects!
|
| </p>
|
| </div>
|
|
|
| <div className="grid md:grid-cols-3 gap-4 mb-8">
|
| <div className="bg-white/5 rounded-2xl p-6 border border-white/10">
|
| <div className="text-3xl mb-3">👁️</div>
|
| <h3 className="text-white font-bold mb-2">Object Detection</h3>
|
| <p className="text-white/60 text-sm">Build your own detector</p>
|
| </div>
|
| <div className="bg-white/5 rounded-2xl p-6 border border-white/10">
|
| <div className="text-3xl mb-3">🏃</div>
|
| <h3 className="text-white font-bold mb-2">Pose Tracking</h3>
|
| <p className="text-white/60 text-sm">Create motion games</p>
|
| </div>
|
| <div className="bg-white/5 rounded-2xl p-6 border border-white/10">
|
| <div className="text-3xl mb-3">😊</div>
|
| <h3 className="text-white font-bold mb-2">Emotion AI</h3>
|
| <p className="text-white/60 text-sm">Analyze expressions</p>
|
| </div>
|
| </div>
|
|
|
| <Button
|
| size="lg"
|
| onClick={() => {
|
| window.location.href = "/Lab-Selection.html";
|
| }}
|
| className="w-full bg-gradient-to-r from-blue-500 via-purple-500 to-pink-500 hover:from-blue-600 hover:via-purple-600 hover:to-pink-600 text-white font-bold text-xl py-8 rounded-2xl border-0 shadow-2xl transition-all hover:scale-105"
|
| >
|
| <Sparkles className="w-6 h-6 mr-3" />
|
| Launch AI Playground
|
| </Button>
|
| </motion.div>
|
| </motion.div>
|
| </div>
|
| </div>
|
| );
|
| }
|
|
|
|
|
| const question = questions[currentQuestion];
|
|
|
| return (
|
| <div className="min-h-screen bg-gradient-to-br from-slate-900 via-purple-900 to-slate-900 pt-24 pb-12 px-6">
|
| <div className="fixed inset-0 overflow-hidden pointer-events-none">
|
| <div className="absolute top-20 left-10 w-72 h-72 bg-yellow-500/20 rounded-full blur-3xl animate-pulse" />
|
| <div className="absolute bottom-20 right-10 w-96 h-96 bg-orange-500/20 rounded-full blur-3xl animate-pulse" />
|
| </div>
|
|
|
| <div className="max-w-2xl mx-auto relative">
|
| {/* Progress */}
|
| <div className="mb-8">
|
| <div className="flex items-center justify-between text-white/60 mb-2">
|
| <span>Question {currentQuestion + 1} of {questions.length}</span>
|
| <span className="px-3 py-1 rounded-full bg-white/10 text-sm">{question.topic}</span>
|
| </div>
|
| <Progress
|
| value={((currentQuestion + 1) / questions.length) * 100}
|
| className="h-2 bg-white/10"
|
| />
|
| </div>
|
|
|
| {/* Question */}
|
| <AnimatePresence mode="wait">
|
| <motion.div
|
| key={currentQuestion}
|
| initial={{ opacity: 0, x: 50 }}
|
| animate={{ opacity: 1, x: 0 }}
|
| exit={{ opacity: 0, x: -50 }}
|
| >
|
| <div className="bg-white/5 backdrop-blur-xl rounded-3xl p-8 border border-white/10 mb-6">
|
| <div className="flex items-start gap-4 mb-6">
|
| <div className="w-12 h-12 rounded-xl bg-gradient-to-br from-yellow-500 to-orange-500 flex items-center justify-center flex-shrink-0">
|
| <Brain className="w-6 h-6 text-white" />
|
| </div>
|
| <h2 className="text-2xl font-bold text-white leading-relaxed">
|
| {question.question}
|
| </h2>
|
| </div>
|
|
|
| {/* Options */}
|
| <div className="space-y-3">
|
| {question.options.map((option, index) => {
|
| const isSelected = selectedAnswer === index;
|
| const isCorrect = index === question.correct;
|
| const showCorrect = showResult && isCorrect;
|
| const showWrong = showResult && isSelected && !isCorrect;
|
|
|
| return (
|
| <motion.button
|
| key={index}
|
| onClick={() => handleAnswer(index)}
|
| disabled={showResult}
|
| className={`w-full p-4 rounded-2xl text-left transition-all border-2 ${
|
| showCorrect
|
| ? 'bg-emerald-500/20 border-emerald-500 text-white'
|
| : showWrong
|
| ? 'bg-red-500/20 border-red-500 text-white'
|
| : isSelected
|
| ? 'bg-white/20 border-white/40 text-white'
|
| : 'bg-white/5 border-white/10 text-white/80 hover:bg-white/10 hover:border-white/20'
|
| }`}
|
| whileHover={!showResult ? { scale: 1.02 } : {}}
|
| whileTap={!showResult ? { scale: 0.98 } : {}}
|
| >
|
| <div className="flex items-center gap-4">
|
| <div className={`w-10 h-10 rounded-xl flex items-center justify-center font-bold ${
|
| showCorrect
|
| ? 'bg-emerald-500 text-white'
|
| : showWrong
|
| ? 'bg-red-500 text-white'
|
| : 'bg-white/10 text-white/60'
|
| }`}>
|
| {showCorrect ? (
|
| <CheckCircle2 className="w-5 h-5" />
|
| ) : showWrong ? (
|
| <XCircle className="w-5 h-5" />
|
| ) : (
|
| String.fromCharCode(65 + index)
|
| )}
|
| </div>
|
| <span className="text-lg">{option}</span>
|
| </div>
|
| </motion.button>
|
| );
|
| })}
|
| </div>
|
| </div>
|
|
|
| {/* Feedback */}
|
| <AnimatePresence>
|
| {showResult && (
|
| <motion.div
|
| initial={{ opacity: 0, y: 20 }}
|
| animate={{ opacity: 1, y: 0 }}
|
| exit={{ opacity: 0, y: -20 }}
|
| className={`rounded-2xl p-6 mb-6 ${
|
| selectedAnswer === question.correct
|
| ? 'bg-gradient-to-br from-emerald-500/20 to-teal-500/20 border border-emerald-500/30'
|
| : 'bg-gradient-to-br from-red-500/20 to-rose-500/20 border border-red-500/30'
|
| }`}
|
| >
|
| <div className="flex items-center gap-3">
|
| {selectedAnswer === question.correct ? (
|
| <>
|
| <CheckCircle2 className="w-8 h-8 text-emerald-400" />
|
| <div>
|
| <h3 className="text-xl font-bold text-white">Correct! 🎉</h3>
|
| <p className="text-white/70">Great job! You got this one right.</p>
|
| </div>
|
| </>
|
| ) : (
|
| <>
|
| <XCircle className="w-8 h-8 text-red-400" />
|
| <div>
|
| <h3 className="text-xl font-bold text-white">Not quite! 🤔</h3>
|
| <p className="text-white/70">
|
| The correct answer was: {question.options[question.correct]}
|
| </p>
|
| </div>
|
| </>
|
| )}
|
| </div>
|
| </motion.div>
|
| )}
|
| </AnimatePresence>
|
|
|
| {/* Next Button */}
|
| {showResult && (
|
| <motion.div
|
| initial={{ opacity: 0 }}
|
| animate={{ opacity: 1 }}
|
| className="text-center"
|
| >
|
| <Button
|
| onClick={handleNext}
|
| size="lg"
|
| className="bg-gradient-to-r from-blue-500 to-purple-600 hover:from-blue-600 hover:to-purple-700 rounded-2xl px-12 py-6 text-lg font-bold text-white border-0 shadow-xl shadow-purple-500/30 transition-all hover:scale-105"
|
| >
|
| {currentQuestion < questions.length - 1 ? 'Next Question →' : '✨ See Results'}
|
| </Button>
|
| </motion.div>
|
| )}
|
| </motion.div>
|
| </AnimatePresence>
|
| </div>
|
| </div>
|
| );
|
| }
|
|
|