0% found this document useful (0 votes)
1 views5 pages

Text

The document contains a React application that implements a vocabulary quiz using a predefined word list with definitions. It includes functionalities to start the quiz, select answers, provide feedback, and track scores. The app also allows users to restart the quiz upon completion and utilizes Tailwind CSS for styling.

Uploaded by

TruthSeeker101
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
1 views5 pages

Text

The document contains a React application that implements a vocabulary quiz using a predefined word list with definitions. It includes functionalities to start the quiz, select answers, provide feedback, and track scores. The app also allows users to restart the quiz upon completion and utilizes Tailwind CSS for styling.

Uploaded by

TruthSeeker101
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 5

import React, { useState, useEffect, useCallback } from 'react';

// Define the word list data


const wordList = [
{ word: "afraid", definition: "When someone is afraid, they feel fear." },
{ word: "agree", definition: "To agree is to say 'yes' or to think the same way."
},
{ word: "angry", definition: "When someone is angry, they may want to speak
loudly or fight." },
{ word: "arrive", definition: "To arrive is to get to or reach some place." },
{ word: "attack", definition: "To attack is to try to fight or to hurt." },
{ word: "bottom", definition: "The bottom is the lowest part." },
{ word: "clever", definition: "When someone is clever, they can solve a hard
puzzle or problem." },
{ word: "cruel", definition: "When someone is cruel, they do bad things to hurt
others." },
{ word: "finally", definition: "If something happens finally, it happens after a
long time or at the end." },
{ word: "hide", definition: "To hide is to try not to let others see you." },
];

// Function to shuffle an array


const shuffleArray = (array) => {
let currentIndex = array.length, randomIndex;
while (currentIndex !== 0) {
randomIndex = Math.floor(Math.random() * currentIndex);
currentIndex--;
[array[currentIndex], array[randomIndex]] = [
array[randomIndex], array[currentIndex]];
}
return array;
};

// Main App component


const App = () => {
const [currentQuestionIndex, setCurrentQuestionIndex] = useState(0);
const [score, setScore] = useState(0);
const [quizStarted, setQuizStarted] = useState(false);
const [quizCompleted, setQuizCompleted] = useState(false);
const [questions, setQuestions] = useState([]);
const [selectedAnswer, setSelectedAnswer] = useState(null);
const [feedback, setFeedback] = useState('');

// Function to generate a single question with options


const generateQuestion = useCallback((correctWordObj) => {
const allWords = wordList.map(item => item.word);
// Filter out the correct word to pick distinct incorrect options
const incorrectWords = allWords.filter(word => word !== correctWordObj.word);

// Pick 3 random incorrect words, ensuring they are unique


const shuffledIncorrect = shuffleArray([...incorrectWords]);
const options = [correctWordObj.word, ...shuffledIncorrect.slice(0, 3)];

return {
definition: correctWordObj.definition,
correctAnswer: correctWordObj.word,
options: shuffleArray(options), // Shuffle options for each question
};
}, []);
// Initialize questions when the quiz starts
useEffect(() => {
if (quizStarted) {
const shuffledWordList = shuffleArray([...wordList]);
const generatedQuestions = shuffledWordList.map(generateQuestion);
setQuestions(generatedQuestions);
}
}, [quizStarted, generateQuestion]);

// Handle answer selection


const handleAnswerSelect = (answer) => {
if (selectedAnswer !== null) return; // Prevent multiple selections

setSelectedAnswer(answer);
const currentQuestion = questions[currentQuestionIndex];

if (answer === currentQuestion.correctAnswer) {


setScore((prevScore) => prevScore + 1);
setFeedback('Correct!');
} else {
setFeedback(`Incorrect. The correct answer was "$
{currentQuestion.correctAnswer}".`);
}
};

// Move to the next question


const handleNextQuestion = () => {
setSelectedAnswer(null);
setFeedback('');
if (currentQuestionIndex < questions.length - 1) {
setCurrentQuestionIndex((prevIndex) => prevIndex + 1);
} else {
setQuizCompleted(true);
}
};

// Restart the quiz


const handleRestartQuiz = () => {
setQuizStarted(false);
setQuizCompleted(false);
setCurrentQuestionIndex(0);
setScore(0);
setSelectedAnswer(null);
setFeedback('');
setQuestions([]);
};

// Render quiz content based on state


const renderQuizContent = () => {
if (!quizStarted) {
return (
<div className="text-center">
<h2 className="text-2xl font-semibold mb-4 text-gray-800">Welcome to the
Word List Quiz!</h2>
<p className="text-lg text-gray-600 mb-6">Test your knowledge of the
vocabulary words.</p>
<button
onClick={() => setQuizStarted(true)}
className="bg-blue-600 hover:bg-blue-700 text-white font-bold py-3 px-6
rounded-lg shadow-lg transform transition-all duration-300 hover:scale-105
focus:outline-none focus:ring-4 focus:ring-blue-300"
>
Start Quiz
</button>
</div>
);
}

if (quizCompleted) {
return (
<div className="text-center">
<h2 className="text-3xl font-bold mb-6 text-green-700">Quiz
Completed!</h2>
<p className="text-2xl text-gray-800 mb-8">Your final score: <span
className="font-extrabold text-blue-600">{score} / {questions.length}</span></p>
<button
onClick={handleRestartQuiz}
className="bg-purple-600 hover:bg-purple-700 text-white font-bold py-3
px-6 rounded-lg shadow-lg transform transition-all duration-300 hover:scale-105
focus:outline-none focus:ring-4 focus:ring-purple-300"
>
Restart Quiz
</button>
</div>
);
}

const currentQuestion = questions[currentQuestionIndex];


if (!currentQuestion) {
return <div className="text-center text-gray-600">Loading questions...</div>;
}

return (
<div className="w-full">
<div className="text-lg font-medium text-gray-700 mb-4">
Question {currentQuestionIndex + 1} of {questions.length}
</div>
<div className="bg-blue-100 p-6 rounded-lg shadow-md mb-6">
<p className="text-xl font-semibold text-blue-
800">{currentQuestion.definition}</p>
</div>
<div className="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6">
{currentQuestion.options.map((option, index) => (
<button
key={index}
onClick={() => handleAnswerSelect(option)}
className={`
w-full py-3 px-4 rounded-lg text-lg font-medium transition-all
duration-200
${selectedAnswer === option
? (option === currentQuestion.correctAnswer ? 'bg-green-200 text-
green-800 ring-2 ring-green-500' : 'bg-red-200 text-red-800 ring-2 ring-red-500')
: 'bg-gray-100 hover:bg-gray-200 text-gray-800'
}
${selectedAnswer !== null ? 'cursor-not-allowed opacity-80' :
'cursor-pointer'}
${selectedAnswer === null && 'hover:shadow-md'}
`}
disabled={selectedAnswer !== null}
>
{option}
</button>
))}
</div>
{feedback && (
<div className={`text-center text-lg font-semibold mb-4 $
{feedback.startsWith('Correct') ? 'text-green-600' : 'text-red-600'}`}>
{feedback}
</div>
)}
{selectedAnswer !== null && (
<div className="text-center">
<button
onClick={handleNextQuestion}
className="bg-indigo-600 hover:bg-indigo-700 text-white font-bold py-
3 px-6 rounded-lg shadow-lg transform transition-all duration-300 hover:scale-105
focus:outline-none focus:ring-4 focus:ring-indigo-300"
>
{currentQuestionIndex < questions.length - 1 ? 'Next Question' :
'Finish Quiz'}
</button>
</div>
)}
</div>
);
};

return (
<div className="min-h-screen bg-gradient-to-br from-blue-50 to-indigo-100 flex
items-center justify-center p-4 font-sans">
{/* Tailwind CSS CDN */}
<script src="https://cdn.tailwindcss.com"></script>
{/* Inter font from Google Fonts */}
<link href="https://fonts.googleapis.com/css2?
family=Inter:wght@400;500;600;700;800&display=swap" rel="stylesheet" />

<style>
{`
body {
font-family: 'Inter', sans-serif;
}
.quiz-container {
max-width: 700px;
width: 100%;
background-color: #ffffff;
border-radius: 16px;
padding: 32px;
box-shadow: 0 10px 25px rgba(0, 0, 0, 0.1);
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
min-height: 50vh; /* Ensure it takes up enough vertical space */
}
@media (max-width: 768px) {
.quiz-container {
padding: 24px;
}
}
`}
</style>

<div className="quiz-container">
{renderQuizContent()}
</div>
</div>
);
};

export default App;

You might also like