2022

World Cup Voting App

A full-stack MERN application that allows users to vote for match winners and leave real-time comments with rate limiting and persistent storage.

World Cup Voting App

World Cup Voting App



A real-time voting platform built with a MERN stack architecture that allows users to vote for match outcomes and participate through a live comment system.

The project focuses on state consistency, API design, and user interaction constraints, while keeping the UI simple and responsive.


📸 UI Preview

Voting UI

🧠 Concept

The application simulates a live voting environment during a football tournament, where users can:

  • Vote for a winning team
  • View total votes instantly
  • Leave comments
  • Browse comments with pagination

It includes client-side protections to prevent abuse and ensures backend consistency with atomic updates.


⚙️ Tech Stack

  • Frontend: React, React Bootstrap, React Paginate
  • Backend: Node.js, Express
  • Database: MongoDB (Mongoose)
  • State Management: useReducer (custom logic)
  • Notifications: React Toastify

🚀 Key Features

🗳️ Voting System

  • Users can vote for teams (France / Argentina)
  • Voting is rate-limited (1 vote per hour) using localStorage
  • Backend uses atomic updates ($inc) to ensure consistency

💬 Comment System

  • Users can submit comments with username
  • Rate-limited to 1 comment per 2 minutes
  • New comments are inserted instantly without full reload

📊 Live Vote Counts

  • Aggregated vote counts stored in MongoDB
  • Loaded via /api/win
  • Updated after each vote without refreshing the page

📄 Pagination

  • Comments are paginated client-side
  • Efficient rendering for large datasets

🧩 Backend Design

The backend exposes simple REST endpoints:

  • GET /api/win → fetch vote counts
  • POST /api/win/add/:team → increment vote
  • GET /api/users → fetch comments
  • POST /api/users/add → add comment

Vote updates are handled atomically using MongoDB increment operations to avoid conflicts.


⚠️ Challenges & Fixes

❌ Repeated API Calls

Calling async functions inside JSX caused repeated requests.

Fix:
Moved all API logic into useEffect.


❌ State Mutation Bug

State was mutated directly instead of using the reducer.

Fix:
Replaced with proper dispatch-based updates.


❌ Vote Updates Not Refreshing

Votes did not reflect immediately after clicking.

Fix:
Re-fetch /api/win after each vote and separate reducer actions.


💡 What This Project Shows

  • Full-stack data flow from UI to database
  • Handling real-time-like updates without sockets
  • Preventing abuse with client-side rate limiting
  • Safe backend updates using MongoDB
  • Managing complex UI state with useReducer

Explore more projects