Open In App

Create a Quiz App with Next JS

Last Updated : 29 Feb, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

In this article, we’ll explore the process of building a Quiz App utilizing NextJS. The quiz app provides users with a series of multiple-choice questions with options. Users can select the option and move to the next question. At the end, the user will be able to see the analysis of the quiz.

Output Preview: Let us have a look at how the final output will look like
Screenshot-(450)

Prerequisites:

Approach to Create Quiz App with Next JS:

  • Setup the Project by Creating a new Next JS project.
  • we will be using useState hook to manage the quiz state, including the current question, selected answer, and quiz results.
  • We will utilize Bootstrap to style our Quiz App.
  • Create a new QuestionSet.js file under Data folder where we will define the questions along with options and answers.
  • We will be creating different components for code readability and reusability. here we will be creating components such as Quiz to render the different questions and ScoreCard to display the result analysis.
  • Quiz app will start with taking user’s name once we click on start quiz button App component will render the Quiz component which is responsible to display the questions one by one.
  • After submitting the test ScoreCard component will be rendered which will display the result analysis including score, correct answers, wrong answers, percentage and status.

Steps to create the Quiz Application:

Step 1: Create a application of NextJS using the following command.

npx create-next-app@latest quiz-app

Step 2: Navigate to project directory

cd quiz-app

Step 3: Install the necessary package in your project using the following command.

npm install bootstrap

Project Structure:

Screenshot-(452)

The updated dependencies in package.json file will look like:

"dependencies": {
"bootstrap": "^5.3.3",
"next": "14.1.0",
"react": "^18",
"react-dom": "^18"
}

Example: Below are the components which describes the basic implementation of the Quiz App.

Javascript




// page.js
'use client'
import { useState } from "react";
import Quiz from "../Components/Quiz";
 
export default function Home() {
    const [quizStarted, setQuizStarted] = useState(false);
    const [name, setName] = useState('');
 
    return (
        <div className="container mt-5 ml-5">
            <div className="text-center">
 
                <h1 className='text-success mtb-1 '>
                    GeekForGeeks
                </h1>
                <h3 className='mb-4'>Quiz App</h3>
            </div>
 
            {quizStarted ? (
                <Quiz name={name} />
            ) : (
                <>
                    <div className="mb-3">
                        <label htmlFor="nameInput"
                            className="form-label">
                            Enter Your Name:
                        </label>
                        <input
                            type="text"
                            className="form-control"
                            id="nameInput"
                            value={name}
                            onChange={(e) =>
                                setName(e.target.value)}
                        />
                    </div>
                    <button
                        onClick={() => setQuizStarted(true)}
                        className="btn btn-primary"
                        // Disable button if name is empty or whitespace
                        disabled={!name.trim()}
                    >
                        Start Quiz
                    </button>
                </>
            )}
        </div>
    );
}


Javascript




// QuestionSet.js
export const quiz = {
    questions: [
        {
            id: 1,
            question: 'What does API stand for?',
            answers: ['Application Programming Interface',
                'Advanced Programming Interface',
                'Application Program Interface',
                'Automated Programming Interface'],
            correctAnswer: 'Application Programming Interface',
        },
 
        {
            id: 3,
            question: `Which programming language is often
            used for building web servers?`,
            answers: ['Java', 'Python', 'JavaScript', 'C#'],
            correctAnswer: 'JavaScript',
        },
        {
            id: 4,
            question: 'What is the purpose of SQL?',
            answers: ['Styling web pages', 'Querying databases',
                'Creating animations', 'Developing mobile apps'],
            correctAnswer: 'Querying databases',
        },
        {
            id: 5,
            question: 'What does MVC stand for in web development?',
            answers: ['Model View Controller', 'Model Visual Controller',
                'Model View Component', 'Model Visual Component'],
            correctAnswer: 'Model View Controller',
        },
    ],
};


Javascript




// Quiz.js
import React, { useState } from 'react';
import 'bootstrap/dist/css/bootstrap.min.css';
import { quiz } from '../Data/QuestionSet.js';
import ScoreCard from './ScoreCard.js';
 
const Quiz = ({ name }) => {
    const [currentQuestionIndex, setCurrentQuestionIndex] = useState(0);
    const [selectedAnswer, setSelectedAnswer] = useState('');
    const [answerChecked, setAnswerChecked] = useState(false);
    const [selectedAnswerIndex, setSelectedAnswerIndex] = useState(null);
    const [showResults, setShowResults] = useState(false);
    const [quizResult, setQuizResult] = useState({
        score: 0,
        correctAnswers: 0,
        wrongAnswers: 0,
    });
 
    const { questions } = quiz;
    const { question, answers, correctAnswer } =
                                                questions[currentQuestionIndex];
 
    const onAnswerSelected = (answer, idx) => {
        setSelectedAnswerIndex(idx);
        setSelectedAnswer(answer);
        setAnswerChecked(true);
    };
 
    const handleNextQuestion = () => {
        if (selectedAnswer === correctAnswer) {
            setQuizResult((prev) => ({
                ...prev,
                score: prev.score + 5,
                correctAnswers: prev.correctAnswers + 1,
            }));
        } else {
            setQuizResult((prev) => ({
                ...prev,
                wrongAnswers: prev.wrongAnswers + 1,
            }));
        }
        if (currentQuestionIndex !== questions.length - 1) {
            setCurrentQuestionIndex((prev) => prev + 1);
        } else {
            setShowResults(true);
        }
        setSelectedAnswer('');
        setSelectedAnswerIndex(null);
        setAnswerChecked(false);
    };
 
    return (
        <div className='container mt-5'>
 
            <div>
                {!showResults ? (
                    <div className='card p-4'>
                        <h4>{question}</h4>
                        <ul className='list-group'>
                            {answers.map((answer, idx) => (
                                <li
                                    key={idx}
                                    onClick={() => onAnswerSelected(answer,idx)}
                                    className={
                                        'list-group-item ' +
                                        (selectedAnswerIndex ===
                                                idx ? 'active' : '') +
                                        ' cursor-pointer'
                                    }
                                >
                                    {answer}
                                </li>
                            ))}
                        </ul>
                        <div className='d-flex justify-content-between mt-3'>
                            <b>Question
                                {currentQuestionIndex + 1}/{questions.length}
                            </b>
                            <button
                                onClick={handleNextQuestion}
                                className='btn btn-primary'
                                disabled={!answerChecked}
                            >
                                {currentQuestionIndex === questions.length - 1 ?
                                    'Submit' : 'Next Question'}
                            </button>
                        </div>
                    </div>
                ) : (
                    <ScoreCard
                        quizResult={quizResult}
                        questions={questions}
                        name={name}
                    />
                )}
            </div>
        </div>
    );
};
 
export default Quiz;


Javascript




// ScoreCard.js
import React from 'react';
 
const ScoreCard = ({ quizResult, questions, name }) => {
    const passPercentage = 60;
 
    const percentage = (quizResult.score / (questions.length * 5)) * 100;
    const status = percentage >= passPercentage ? 'Pass' : 'Fail';
 
    return (
        <>
            <div className='card p-4'>
                <h3>Hello, {name}. Here is your Result Analysis</h3>
                <table className='table'>
                    <tbody>
                        <tr>
                            <td>Total Questions:</td>
                            <td>{questions.length}</td>
                        </tr>
                        <tr>
                            <td>Total Score:</td>
                            <td>{quizResult.score}</td>
                        </tr>
                        <tr>
                            <td>Correct Answers:</td>
                            <td>{quizResult.correctAnswers}</td>
                        </tr>
                        <tr>
                            <td>Wrong Answers:</td>
                            <td>{quizResult.wrongAnswers}</td>
                        </tr>
                        <tr>
                            <td>Percentage:</td>
                            <td>{percentage}%</td>
                        </tr>
                        <tr>
                            <td>Status:</td>
                            <td>{status}</td>
                        </tr>
                    </tbody>
                </table>
                <button
                    onClick={() => window.location.reload()}
                    className='btn btn-primary mt-3'
                >
                    Restart
                </button>
            </div>
        </>
    );
};
 
export default ScoreCard;


Start your application using the following command.

npm run dev

Output: Naviage to the URL http://localhost:3000.

gfg_quiz_app



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads