8
Fullstack

Quiz System

A comprehensive, interactive quiz system with builder, management, and results components for creating engaging educational quizzes with multiple question types and real-time scoring.

Quiz System

A comprehensive, interactive quiz system that provides complete quiz creation, management, and taking capabilities. Features a powerful quiz builder with multiple question types, real-time scoring, progress tracking, and beautiful responsive UI components.

Quiz System Components
Loading component registry...

Installation

Install the component using the AxionsJS CLI:

npx axionjs-ui add quiz

Configure your environment variables in .env:

# Database
DATABASE_URL="postgresql://username:password@localhost:5432/database_name"

# Authentication (if using auth)
AUTH_SECRET="your-auth-secret"
NEXT_PUBLIC_APP_URL="http://localhost:3000"

Set up Prisma schema and push to database:

npx prisma db push

The component includes complete database models for quizzes, questions, options, and submissions. All CRUD operations and scoring logic are pre-configured and ready to use.

Database Schema

Add the following models to your schema.prisma file:

schema.prisma
model UserProfile {
  id                  String   @id @default(cuid())
  email               String   @unique
  name                String?
  bio                 String?  @db.Text
  avatarUrl           String?
  createdAt           DateTime @default(now())
  updatedAt           DateTime @updatedAt
  preferences         Json?
  completedOnboarding Boolean  @default(false)
 
  // Relations
  quizzes         Quiz[]
  quizSubmissions QuizSubmission[]
 
  @@map("user_profiles")
}
 
model Quiz {
  id                  String   @id @default(cuid())
  title               String
  description         String?  @db.Text
  createdAt           DateTime @default(now())
  updatedAt           DateTime @updatedAt
  createdById         String?
  isPublished         Boolean  @default(false)
  timeLimit           Int?     // in minutes
  allowRetakes        Boolean  @default(true)
 
  // Relations
  createdBy   UserProfile?     @relation(fields: [createdById], references: [id], onDelete: SetNull)
  questions   Question[]
  submissions QuizSubmission[]
 
  @@map("quizzes")
}
 
model Question {
  id     String @id @default(cuid())
  text   String @db.Text
  type   String // "multiple-choice", "single-choice", "true-false"
  points Int    @default(1)
  order  Int    @default(0)
  quizId String
 
  // Relations
  quiz    Quiz             @relation(fields: [quizId], references: [id], onDelete: Cascade)
  options QuestionOption[]
  answers Answer[]
 
  @@map("questions")
}
 
model QuestionOption {
  id         String  @id @default(cuid())
  text       String  @db.Text
  isCorrect  Boolean @default(false)
  order      Int     @default(0)
  questionId String
 
  // Relations
  question Question @relation(fields: [questionId], references: [id], onDelete: Cascade)
  answers  Answer[]
 
  @@map("question_options")
}
 
model QuizSubmission {
  id        String   @id @default(cuid())
  quizId    String
  userId    String
  score     Int?
  maxScore  Int?
  completed Boolean  @default(false)
  startedAt DateTime @default(now())
  completedAt DateTime?
  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt
 
  // Relations
  quiz    Quiz        @relation(fields: [quizId], references: [id], onDelete: Cascade)
  user    UserProfile @relation(fields: [userId], references: [id], onDelete: Cascade)
  answers Answer[]
 
  @@unique([quizId, userId])
  @@map("quiz_submissions")
}
 
model Answer {
  id           String  @id @default(cuid())
  questionId   String
  optionId     String?
  submissionId String
  isCorrect    Boolean @default(false)
 
  // Relations
  question       Question        @relation(fields: [questionId], references: [id], onDelete: Cascade)
  selectedOption QuestionOption? @relation(fields: [optionId], references: [id], onDelete: SetNull)
  submission     QuizSubmission  @relation(fields: [submissionId], references: [id], onDelete: Cascade)
 
  @@map("answers")
}

Run npx prisma db push after adding the schema to apply changes to your database.

Usage

Create and edit quizzes with the powerful quiz builder:

app/quiz/create/page.tsx
"use client";
import { QuizBuilder } from "@/components/quiz-builder";
 
export default function CreateQuizPage() {
  return (
    <div className="min-h-screen bg-gray-50 py-12">
      <div className="mx-auto max-w-4xl px-4">
        <QuizBuilder
          onSuccess={(quiz) => {
            console.log("Quiz created:", quiz);
            // Redirect to quiz list or management
          }}
          onError={(error) => {
            console.error("Quiz creation error:", error);
            // Handle error state
          }}
        />
      </div>
    </div>
  );
}

Key Features

Component Props

PropTypeDefault
QuizBuilder
object
-
QuizTaker
object
-
QuizResults
object
-

Server Actions

The component utilizes Next.js server actions for all quiz operations:

actions/quiz-actions.ts
export const createQuiz = async (
  values: QuizFormData
): Promise<QuizActionResult> => {
  const validatedFields = QuizSchema.safeParse(values);
  
  if (!validatedFields.success) {
    return { error: "Invalid quiz data" };
  }
 
  const { title, description, questions } = validatedFields.data;
  
  try {
    const quiz = await db.quiz.create({
      data: {
        title,
        description,
        createdById: userId, // from auth
        questions: {
          create: questions.map((q, index) => ({
            text: q.text,
            type: q.type,
            points: q.points,
            order: index,
            options: {
              create: q.options.map((opt, optIndex) => ({
                text: opt.text,
                isCorrect: opt.isCorrect,
                order: optIndex,
              })),
            },
          })),
        },
      },
      include: { questions: { include: { options: true } } },
    });
 
    return { success: "Quiz created successfully", quiz };
  } catch (error) {
    return { error: "Failed to create quiz" };
  }
};

Features:

  • Comprehensive validation with Zod schemas
  • Nested creation of questions and options
  • Automatic ordering of questions and options
  • Full relationship management

Question Types

The quiz system supports multiple question formats:

components/question-types.tsx
export const QuestionTypes = {
  SINGLE_CHOICE: "single-choice",
  MULTIPLE_CHOICE: "multiple-choice", 
  TRUE_FALSE: "true-false",
} as const;
 
export const QuestionTypeConfig = {
  [QuestionTypes.SINGLE_CHOICE]: {
    label: "Single Choice",
    description: "Select one correct answer",
    icon: "radio-button",
    maxOptions: 6,
    minOptions: 2,
  },
  [QuestionTypes.MULTIPLE_CHOICE]: {
    label: "Multiple Choice", 
    description: "Select multiple correct answers",
    icon: "check-square",
    maxOptions: 8,
    minOptions: 2,
  },
  [QuestionTypes.TRUE_FALSE]: {
    label: "True/False",
    description: "True or false question",
    icon: "toggle",
    maxOptions: 2,
    minOptions: 2,
  },
};

Question Type Features:

  • Single Choice: Radio button selection with one correct answer
  • Multiple Choice: Checkbox selection with multiple correct answers
  • True/False: Simple binary choice questions
  • Custom Points: Configurable scoring per question
  • Rich Text: Support for formatted question text
  • Media Support: Images and videos in questions (coming soon)

Analytics & Reporting

The quiz system provides comprehensive analytics:

  • Performance Metrics: Success rates, average scores, completion times
  • Question Analysis: Difficulty assessment, answer distribution

Analytics data is automatically collected and can be viewed through the QuizAnalytics component.

Security Features

The Quiz System implements multiple security layers:

  • Input Validation: Comprehensive validation with Zod schemas
  • SQL Injection Protection: Prisma provides built-in protection
  • Answer Verification: Server-side scoring prevents cheating
  • Attempt Tracking: Monitors quiz retakes and submission integrity

Always validate quiz submissions on the server side and implement proper user authentication to prevent unauthorized access.

Conclusion

The Quiz System provides a complete, production-ready solution for creating and managing interactive quizzes in your Next.js applications. With its comprehensive question types, real-time scoring, detailed analytics, and beautiful responsive design, it delivers both excellent user experience and powerful educational capabilities for any learning platform or assessment tool.

On this page