Example output
import React, { useState, useEffect } from 'react';
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { Progress } from "@/components/ui/progress";
import { Trophy } from "lucide-react";
import { Alert, AlertDescription } from "@/components/ui/alert";
const StrangerThingsQuiz = () => {
// Replace this URL with your actual image URL
const imageUrl = "/api/placeholder/900/900"; // Replace with your image URL
const [currentQuestion, setCurrentQuestion] = useState(0);
const [score, setScore] = useState(0);
const [revealedPieces, setRevealedPieces] = useState(new Set());
const [showFeedback, setShowFeedback] = useState(false);
const [isCorrect, setIsCorrect] = useState(false);
const [gameComplete, setGameComplete] = useState(false);
const [imageLoaded, setImageLoaded] = useState(false);
useEffect(() => {
const img = new Image();
img.src = imageUrl;
img.onload = () => setImageLoaded(true);
}, [imageUrl]);
const questions = [
{
question: "What is the name of the parallel dimension in Stranger Things?",
options: [
"The Other Side",
"The Upside Down",
"The Dark World",
"The Mirror Dimension"
],
correct: 1
},
{
question: "What is Eleven's favorite frozen food?",
options: [
"Ice Cream",
"Frozen Pizza",
"Eggo Waffles",
"Frozen Yogurt"
],
correct: 2
},
{
question: "What is the name of the monster in Season 1?",
options: [
"Demogorgon",
"Mind Flayer",
"Vecna",
"Thessalhydra"
],
correct: 0
},
{
question: "What is the name of the secret government facility in Hawkins?",
options: [
"Area 51",
"Site B",
"The Complex",
"Hawkins Lab"
],
correct: 3
},
{
question: "What game do the boys frequently play?",
options: [
"Dungeons & Dragons",
"Monopoly",
"Risk",
"Chess"
],
correct: 0
},
{
question: "What is Will's nickname given by his mom Joyce?",
options: [
"Sweetie",
"Baby",
"Honey",
"Zombie Boy"
],
correct: 3
},
{
question: "What is Steve Harrington's signature accessory?",
options: [
"Sunglasses",
"Baseball Cap",
"Hair Spray",
"Leather Jacket"
],
correct: 2
},
{
question: "What is the name of Dustin's pet from the Upside Down?",
options: [
"Dart",
"Spike",
"Rex",
"Monster"
],
correct: 0
},
{
question: "What song saves Max from Vecna?",
options: [
"Should I Stay or Should I Go",
"Time After Time",
"Every Breath You Take",
"Running Up That Hill"
],
correct: 3
}
];
const handleAnswer = (selectedIndex) => {
const correct = selectedIndex === questions[currentQuestion].correct;
setIsCorrect(correct);
if (correct) {
setScore(score + 1);
setRevealedPieces(prev => new Set([...prev, currentQuestion]));
}
setShowFeedback(true);
setTimeout(() => {
setShowFeedback(false);
if (currentQuestion < questions.length - 1) {
setCurrentQuestion(currentQuestion + 1);
} else {
setGameComplete(true);
}
}, 1500);
};
const renderPuzzlePiece = (index) => {
const row = Math.floor(index / 3);
const col = index % 3;
const revealed = revealedPieces.has(index);
return (
<div
key={index}
className={`relative aspect-square overflow-hidden border border-purple-300 transition-all duration-700 ${
revealed ? 'opacity-100 scale-100' : 'opacity-0 scale-95'
}`}
style={{
backgroundColor: revealed ? 'transparent' : '#1f1f1f'
}}
>
{revealed && imageLoaded && (
<div
className="absolute w-full h-full transform transition-transform duration-700 hover:scale-105"
style={{
backgroundImage: `url(${imageUrl})`,
backgroundSize: '300% 300%',
backgroundPosition: `${col * 50}% ${row * 50}%`,
transform: 'scale(1.01)',
}}
/>
)}
</div>
);
};
return (
<Card className="w-full max-w-4xl mx-auto bg-gradient-to-b from-gray-900 to-purple-900 text-white shadow-2xl">
<CardHeader className="text-center border-b border-purple-500">
<CardTitle className="text-3xl font-bold text-purple-300">
Stranger Things Quiz
</CardTitle>
</CardHeader>
<CardContent className="p-6">
{!gameComplete ? (
<>
<div className="mb-6">
<Progress
value={(currentQuestion / questions.length) * 100}
className="mb-2"
style={{
backgroundColor: '#2D3748',
'--tw-progress-bar-color': '#B794F4'
}}
/>
<p className="text-sm text-purple-300 text-right">
Question {currentQuestion + 1} of {questions.length}
</p>
</div>
<div className="grid grid-cols-3 gap-1 aspect-square w-full max-w-md mx-auto bg-gray-800 p-1 rounded-lg shadow-xl mb-6">
{[...Array(9)].map((_, index) => renderPuzzlePiece(index))}
</div>
<div className="space-y-6">
<h3 className="text-xl font-semibold text-purple-200">
{questions[currentQuestion].question}
</h3>
<div className="grid grid-cols-1 gap-3">
{questions[currentQuestion].options.map((option, index) => (
<Button
key={index}
onClick={() => handleAnswer(index)}
variant="outline"
className={`w-full text-left justify-start h-auto py-3 px-4
border-purple-500 text-purple-100 hover:bg-purple-800
hover:text-white transition-colors duration-300`}
disabled={showFeedback}
>
{option}
</Button>
))}
</div>
</div>
{showFeedback && (
<Alert className={`mt-4 ${isCorrect ? 'bg-green-900' : 'bg-red-900'} text-white border-none`}>
<AlertDescription>
{isCorrect ?
'Correct! Another piece of the Upside Down revealed!' :
'Wrong! The Mind Flayer clouds your judgment!'}
</AlertDescription>
</Alert>
)}
</>
) : (
<div className="text-center space-y-4">
<Trophy className="w-16 h-16 mx-auto text-yellow-500" />
<h3 className="text-2xl font-bold text-purple-300">
Quiz Complete!
</h3>
<p className="text-lg text-purple-200">
You scored {score} out of {questions.length}!
</p>
<div className="grid grid-cols-3 gap-1 aspect-square w-full max-w-md mx-auto bg-gray-800 p-1 rounded-lg shadow-xl mt-6">
{[...Array(9)].map((_, index) => renderPuzzlePiece(index))}
</div>
<Button
onClick={() => {
setCurrentQuestion(0);
setScore(0);
setRevealedPieces(new Set());
setGameComplete(false);
}}
className="mt-6 bg-purple-600 hover:bg-purple-700 text-white"
>
Play Again
</Button>
</div>
)}
</CardContent>
</Card>
);
};
export default StrangerThingsQuiz;