Skip to content

UjjwalSaini07/Academic-Ballot

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

43 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

πŸŽ“ Academic Ballot

Academic-Ballot is a resilient real-time classroom polling platform built on the MERN stack, designed for seamless teacher–student interaction. It features synchronized server-authoritative timers, secure single-vote enforcement, late-join recovery, and persistent state management to ensure reliability even after refresh or reconnection. Teachers can create polls and monitor live analytics, while students participate instantly, making academic decision-making interactive, scalable, and dependable.

Github License Info Generic badge Generic Repo Size badge GitHub stars Github Release

image

πŸ“š Table of Contents

✨ Features

For Teachers

  • Create Polls - Create multiple-choice questions with customizable duration (30s, 45s, 60s, 90s)
  • Mark Correct Answers - Set the correct answer when creating a poll
  • Live Results - View real-time vote counts and percentage distributions
  • Reveal Answers - Optionally reveal the correct answer to all participants
  • Participant Management - View list of all connected students
  • Kick Participants - Remove disruptive students from the session
  • Poll History - Access complete history of all past polls
  • In-App Chat - Communicate with students during sessions

For Students

  • Join Sessions - Simple name-based registration to join a poll session
  • Real-Time Voting - Submit votes instantly with real-time feedback
  • Live Timer - See countdown timer for each poll
  • Answer Reveal - View correct answers when revealed by teacher
  • In-App Chat - Communicate with the class during sessions

System Features

  • Real-Time Updates - WebSocket-powered instant updates
  • Responsive Design - Works on desktop and mobile devices
  • Auto Reconnection - Handles network interruptions gracefully
  • Kick Prevention - Prevents previously kicked students from rejoining πŸ› οΈ Tech

Stack

🎨 Frontend Technology Stack

The frontend of Academic-Ballot is built using a modern, performance-driven ecosystem designed for scalability, real-time responsiveness, and clean UI architecture.

  • React 18 – A powerful component-based library for building dynamic and interactive user interfaces
  • Vite – A fast, next-generation build tool ensuring optimized development and production performance
  • Tailwind CSS – A utility-first CSS framework for crafting clean, consistent, and modern designs
  • React Router – Declarative routing for smooth navigation across multiple application views
  • Socket.io Client – Enables real-time, bidirectional communication between client and server
  • Axios – A promise-based HTTP client for structured and secure API interactions

βš™οΈ Backend Technology Stack

The backend of Academic-Ballot is engineered for reliability, scalability, and real-time performance, forming the core of the system’s resilient architecture.

  • Node.js – A high-performance runtime environment powering the server-side logic
  • Express.js – A minimalist and flexible web framework for building structured REST APIs
  • Socket.io – Enables real-time, event-driven communication with synchronized state updates
  • MongoDB – A scalable NoSQL database ensuring persistent and reliable data storage
  • Mongoose – An elegant ODM for schema modeling, validation, and data integrity management

πŸš€ Deployment

Academic-Ballot is deployed on a modern cloud platform to ensure high availability, scalability, and seamless performance in production.

  • Vercel – Hosts both frontend and backend services with optimized build pipelines, automatic deployments, and global edge distribution for fast and reliable access

πŸ“ Project Structure

academic-ballot/
β”œβ”€β”€ LICENSE                    # MIT License
β”œβ”€β”€ README.md                  # Project Documentation
β”œβ”€β”€ version.json               # Version Information
β”œβ”€β”€ client/                    # Frontend Application
β”‚   β”œβ”€β”€ public/                # Static Assets
β”‚   β”œβ”€β”€ src/
β”‚   β”‚   β”œβ”€β”€ api/              # API Configuration
β”‚   β”‚   β”‚   └── index.js      # Axios Instance & API URL
β”‚   β”‚   β”œβ”€β”€ components/       # Reusable UI Components
β”‚   β”‚   β”‚   β”œβ”€β”€ ChatPopup.jsx         # Chat Interface
β”‚   β”‚   β”‚   β”œβ”€β”€ Layout.jsx            # Main Layout
β”‚   β”‚   β”‚   β”œβ”€β”€ ParticipantsModal.jsx # Participants Management
β”‚   β”‚   β”‚   β”œβ”€β”€ ParticipantsPopup.jsx # Participants Quick View
β”‚   β”‚   β”‚   └── PollCard.jsx          # Poll Display Component
β”‚   β”‚   β”œβ”€β”€ hooks/            # Custom React Hooks
β”‚   β”‚   β”‚   β”œβ”€β”€ usePollTimer.js        # Countdown Timer
β”‚   β”‚   β”‚   └── useSocket.js           # Socket Connection
β”‚   β”‚   β”œβ”€β”€ pages/            # Page Components
β”‚   β”‚   β”‚   β”œβ”€β”€ Home.jsx             # Landing Page
β”‚   β”‚   β”‚   β”œβ”€β”€ PollHistory.jsx       # Past Polls History
β”‚   β”‚   β”‚   β”œβ”€β”€ RoleSelection.jsx     # Teacher/Student Selection
β”‚   β”‚   β”‚   β”œβ”€β”€ Student.jsx           # Student Entry Page
β”‚   β”‚   β”‚   β”œβ”€β”€ StudentDashboard.jsx  # Student Main Interface
β”‚   β”‚   β”‚   β”œβ”€β”€ StudentOnboarding.jsx # Student Registration
β”‚   β”‚   β”‚   β”œβ”€β”€ Teacher.jsx           # Teacher Entry Page
β”‚   β”‚   β”‚   └── TeacherDashboard.jsx  # Teacher Main Interface
β”‚   β”‚   β”œβ”€β”€ App.jsx           # Root Component
β”‚   β”‚   β”œβ”€β”€ index.css         # Global Styles
β”‚   β”‚   └── main.jsx          # Entry Point
β”‚   β”œβ”€β”€ package.json          # Frontend Dependencies
β”‚   β”œβ”€β”€ tailwind.config.js    # Tailwind Configuration
β”‚   β”œβ”€β”€ vite.config.js        # Vite Configuration
β”‚   └── vercel.json           # Vercel Deployment Config
β”‚
└── server/                   # Backend Application
    β”œβ”€β”€ config/
    β”‚   └── db.js             # MongoDB Connection
    β”œβ”€β”€ controllers/
    β”‚   └── poll.controller.js    # Request Handlers
    β”œβ”€β”€ models/
    β”‚   β”œβ”€β”€ participant.model.js  # Participant Schema
    β”‚   β”œβ”€β”€ poll.model.js         # Poll Schema
    β”‚   └── vote.moel.js          # Vote Schema
    β”œβ”€β”€ routes/
    β”‚   └── poll.routes.js       # API Routes
    β”œβ”€β”€ services/
    β”‚   └── poll.service.js      # Business Logic
    β”œβ”€β”€ sockets/
    β”‚   └── poll.socket.js       # Socket Event Handlers
    β”œβ”€β”€ package.json             # Backend Dependencies
    β”œβ”€β”€ server.js                # Server Entry Point
    └── vercel.json              # Vercel Deployment Config

πŸš€ Getting Started

Prerequisites

Ensure you have the following installed:

  • Node.js (v14 or higher)
  • npm or pnpm
  • MongoDB (local or Atlas)

Installation

  1. Clone the Repository

         git clone https://github.com/UjjwalSaini07/Academic-Ballot.git
        cd Academic-Ballot
  2. Install Backend Dependencies

        cd server
        pnpm install
  3. Install Frontend Dependencies

        cd ../client
        pnpm install
    

Running the Application

Development Mode

  1. Start MongoDB (if using local instance)

        mongod
  2. Start Backend Server

        cd server
        pnpm dev
  3. Start Frontend Development Server

        cd client
        pnpm dev

Production Mode

  1. Build Frontend

        cd client
        pnpm run build
  2. Start Production Server

        cd server
        pnpm start

πŸ”§ Environment Variables

  • Create a .env file in the server/ directory:
    # Server Configuration
    PORT=5000
    NODE_ENV=development
    
    # MongoDB Connection
    # Option 1: Local MongoDB
    MONGODB_URI=mongodb://localhost:27017/academic-ballot
    
    # Option 2: MongoDB Atlas
    MONGODB_URI=mongodb+srv://<username>:<password>@cluster.mongodb.net/academic-ballot
    
    # Frontend API URL (for CORS)
    CLIENT_URL=http://localhost:3000
  • Create a .env file in the client/ directory:
    # Development (use this when running server locally with npm run dev)
    # VITE_API_URL=http://localhost:5000
    
    # Production (use this when deploying to Vercel)
    VITE_API_URL=https://academic-ballot-backend.vercel.app

πŸ“‘ API Endpoints

Base URL

    http://localhost:5000/api

Poll Endpoints

Method Endpoint Description
GET /poll/active Get currently active poll
GET /poll/history Get all completed polls
GET /poll/participants Get all active participants
GET /poll/check-kicked Check if student is kicked
POST /poll Create a new poll
POST /poll/vote Submit a vote
POST /poll/kick Kick a participant
POST /poll/register Register a student
PUT /poll/:id/complete Complete a poll
PUT /poll/:id/reveal Reveal the answer

Health Check

Method Endpoint Description
GET /health Server health status
GET /api API information & endpoints

πŸ”Œ Socket Events

Client β†’ Server Events

Event Payload Description
join { name: string } Join as participant
create_poll { question, options[], duration, correctOption } Create new poll
vote { pollId, studentName, optionIndex } Submit vote
kick { socketId } Kick participant
chat_message { message } Send chat message

Server β†’ Client Events

Event Payload Description
poll_created { poll object } New poll created
poll_ended { poll object } Poll completed
vote_update { poll object } Vote count updated
answer_revealed { poll object } Answer revealed
participants [{ id, name }] Participants list updated
kicked - Current user was kicked
chat_message { message } New chat message
error_message { error } Error occurred

πŸ“± Application Screens

User Flow

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚   Home Page     β”‚  β†’  Role Selection
β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜
         β”‚
    β”Œβ”€β”€β”€β”€β”΄β”€β”€β”€β”€β”
    β”‚         β”‚
    β–Ό         β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚Teacherβ”‚ β”‚ Studentβ”‚
β””β”€β”€β”€β”¬β”€β”€β”€β”˜ β””β”€β”€β”€β”¬β”€β”€β”€β”€β”˜
    β”‚         β”‚
    β–Ό         β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Teacher   β”‚ β”‚ Student            β”‚
β”‚ Dashboard β”‚ β”‚ Onboarding         β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                        β”‚
                        β–Ό
                  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                  β”‚  Student   β”‚
                  β”‚  Dashboard β”‚
                  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Page Descriptions

Page Route Description
Role Selection / Choose Teacher or Student role
Teacher Dashboard /teacher Create & manage polls, view results
Student Onboarding /student Enter name to join
Student Dashboard /student/dashboard View polls, submit votes
Poll History /history View past poll results

πŸ—οΈ Architecture

Data Flow

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚   Client   │────▢│   Server    │────▢│  MongoDB    β”‚
β”‚  (React)   │◀────│  (Express)  │◀────│  (Database) β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
       β”‚                   β”‚
       β”‚                   β”‚
       β–Ό                   β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  Socket.io  │◀───▢│  Socket.io β”‚
β”‚  (Client)   β”‚     β”‚  (Server)   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Database Schemas

Poll Schema

{
  question: String,           // Poll question
  options: [String],           // Answer options
  duration: Number,            // Duration in seconds
  startTime: Number,           // Poll start timestamp
  status: String,              // 'active' or 'completed'
  correctOption: Number,      // Index of correct answer (-1 if not set)
  showAnswer: Boolean,        // Whether answer is revealed
  results: [{                 // Vote counts per option
    optionIndex: Number,
    votes: Number
  }],
  createdAt: Date,
  updatedAt: Date
}

Participant Schema

{
  name: String,                // Student name
  socketId: String,            // Socket connection ID
  isActive: Boolean,           // Currently connected
  isKicked: Boolean,           // Has been kicked
  createdAt: Date,
  updatedAt: Date
}

Vote Schema

{
  pollId: ObjectId,            // Reference to Poll
  studentName: String,         // Student's name
  optionIndex: Number,        // Selected option
  createdAt: Date
}

πŸ“„ License

This project is licensed under the MIT License - see the LICENSE file for details.

πŸ‘€ Author

Ujjwal Saini

πŸ™ Acknowledgments

  • Intervue for inspiration
  • Vercel for hosting
  • All contributors and users of Academic Ballot

Made with ❀️ by Ujjwal Saini

About

Academic-Ballot is a resilient real-time classroom polling platform built on the MERN stack. It delivers synchronized timers, secure one-vote enforcement, late-join recovery, and persistent state management. Teachers track live analytics while students engage instantly, ensuring reliable, scalable, and interactive academic decision-making. πŸ“ŠπŸš€

Topics

Resources

License

Stars

Watchers

Forks

Contributors