Skip to content

Latest commit

Β 

History

35 Commits

Folders and files

NameName
Last commit message
Last commit date
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Live Polls For Feedback

Create polls, collect feedback, and analyze results in real time.

React TypeScript Express.js MongoDB Socket.io Tailwind CSS Framer Motion


πŸ“– Overview

Live Polls For Feedback is a comprehensive full-stack platform designed for real-time engagement and feedback collection. Creators can build complex polls with multiple question types, share them via secure or anonymous links, and monitor results live through a dynamic analytics dashboard. The platform ensures data integrity with atomic vote updates and provides a polished, animated user experience across all devices.


✨ Features

πŸ” Authentication

  • Secure Registration: Register with email and password with mandatory verification.
  • Email Verification: Token-based verification system via Resend.
  • Social Login: Seamless Google OAuth integration via Passport.js.
  • Session Management: JWT-based authentication using secure httpOnly cookies.
  • Password Recovery: Robust forgot/reset password flow with hashed tokens.
  • Session Rehydration: Automatic session recovery on page refresh via /auth/me.

πŸ“Š Poll Management

  • Intuitive Creation: 3-step form with drag-and-drop question reordering.
  • Flexible Configuration: Title, description, optional expiry, and privacy modes.
  • Question Customization: Required/optional toggles with a minimum of 2 options per question.
  • Privacy Control: Support for ANONYMOUS (public) and AUTHENTICATED (verified users) modes.
  • Lifecycle Management: Polls transition through ACTIVE β†’ CLOSED β†’ PUBLISHED states.

πŸ—³οΈ Response Collection

  • Smart Voting: Atomically increments votes and decrements previous choices to ensure accuracy.
  • Duplicate Prevention: Restricted to one response per user (authenticated) or per IP (anonymous).
  • Global Reach: Captures respondent metadata including User-Agent and hashed IP.
  • Automatic Enforcement: Responses are blocked if the poll is expired or closed.

πŸ“ˆ Analytics & Real-time

  • Live Dashboard: Real-time stats for total responses and total views.
  • Dynamic Charts: Visual breakdown of results using Recharts.
  • Socket.io Integration: Instant UI updates when votes are castβ€”no refresh required.
  • Result Publishing: Snapshots final results into a dedicated collection for permanent, immutable viewing.

πŸ› οΈ Tech Stack

Backend

  • Framework: Express.js + TypeScript
  • Database: MongoDB with Mongoose ODM
  • Authentication: Passport.js (Google Strategy) + JWT
  • Communication: Socket.io (Real-time events)
  • Validation: Zod (Schema-based validation)
  • Email: Resend API
  • Security: Bcryptjs (12 rounds), Helmet.js, express-rate-limit

Frontend

  • Framework: React 18 + TypeScript + Vite
  • Routing: React Router v6
  • Data Fetching: TanStack Query v5
  • Forms: React Hook Form + Zod
  • Animations: Framer Motion + GSAP (ScrollTrigger)
  • UI Components: Tailwind CSS + Shadcn/ui + Lucide React
  • Notifications: Sonner

πŸ—οΈ Architecture

Service Layer Pattern

The backend follows a strict Controller β†’ Service β†’ DB architecture to separate concerns:

  • Controllers: Handle HTTP request/response logic and input parsing.
  • Services: Contain business logic, database interactions, and real-time event triggers.
  • Models: Define Mongoose schemas and database-level middleware.

Auth Flow

[Register/Login] --> [Service Layer] --> [JWT Generation]
      |                    |                   |
      v                    v                   v
[Resend Email]      [Hash Password]     [Set httpOnly Cookie]

Poll Lifecycle

ACTIVE (Accepting votes) β†’ CLOSED (Votes frozen) β†’ PUBLISHED (Immutable snapshot created)


πŸš€ API Reference

Auth Endpoints

Method Path Auth Description
POST /api/auth/register No Register new user (displayName, email, password)
POST /api/auth/login No Login with email/password
POST /api/auth/logout Yes Clear auth cookies
GET /api/auth/me Yes Get current user profile
GET /api/auth/verify-email No Verify email via ?token=
POST /api/auth/forgot-password No Request password reset email
POST /api/auth/reset-password No Reset password using token
GET /api/auth/google No Start Google OAuth flow
GET /api/auth/google/callback No Google OAuth callback handler

Polls Endpoints

Method Path Auth Description
POST /api/polls Yes Create a new poll
GET /api/polls Yes List all polls created by user
GET /api/polls/:id No* Get poll details (increments views)
PUT /api/polls/:id Yes Update poll (ACTIVE status only)
DELETE /api/polls/:id Yes Cascade delete poll and data
POST /api/polls/:id/response Opt Submit answers (answers: [{ questionId, selectedOptionId }])
GET /api/polls/:id/responses Yes Get raw response list
PATCH /api/polls/:id/close Yes Change status to CLOSED
PATCH /api/polls/:id/publish Yes Snapshot and change status to PUBLISHED
GET /api/polls/:id/result No Get published result snapshot

* Authenticated if privacyMode is AUTHENTICATED


πŸ’Ύ Database Schema

User

  • email (String, Unique)
  • passwordHash (String, select: false)
  • displayName (String)
  • avatarUrl (String)
  • isEmailVerified (Boolean)
  • oauthProviders (Array: { provider, providerId })
  • passwordResetToken / Expires
  • emailVerificationToken / Expires

Poll

  • creatorId (ObjectId, Ref: User)
  • title (String)
  • description (String)
  • status (Enum: ACTIVE, CLOSED, PUBLISHED)
  • privacyMode (Enum: ANONYMOUS, AUTHENTICATED)
  • expiresAt (Date, Optional)
  • questions (Array: { text, required, options: [{ text, votesCount }] })
  • totalResponses (Number)
  • totalViews (Number)

Response

  • pollId (ObjectId, Ref: Poll)
  • respondentId (ObjectId, Optional)
  • answers (Array: { questionId, selectedOptionId })
  • ipHash (String)
  • userAgent (String)
  • country (String)
  • submittedAt (Date)

Publish

  • pollId (ObjectId)
  • publishedAt (Date)
  • totalResponses (Number)
  • questions (Array: Snapshot of poll questions and final counts)

βš™οΈ Setup & Installation

Prerequisites

  • Node.js (v18+)
  • MongoDB (Local or Atlas)
  • Redis (for Rate Limiting)
  • Resend API Key

1. Clone the repository

git clone https://github.com/Asutosh-1234/Live-Polls-For-Feedback.git
cd Live-Polls-For-Feedback

2. Backend Setup

cd Backend
npm install
# Create .env based on the Environment Variables section below
npm run dev

3. Frontend Setup

cd ../Frontend
npm install
# Create .env based on the Environment Variables section below
npm run dev

πŸ”‘ Environment Variables

Backend (/Backend/.env)

Variable Description Example
PORT Server port 5000
NODE_ENV Environment mode development
DATABASE_URL MongoDB connection URI mongodb://localhost:27017/livepoll
JWT_SECRET Secret for signing tokens super-secret-key
JWT_EXPIRES_IN Token lifespan 7d
GOOGLE_CLIENT_ID Google OAuth Client ID your-id.apps.googleusercontent.com
GOOGLE_CLIENT_SECRET Google OAuth Secret GOCSPX-...
BASE_URL Backend base URL http://localhost:5000
FRONTEND_URL Frontend base URL http://localhost:5173
RESEND_API_KEY Resend email service key re_123...
SESSION_SECRET Express session secret session-secret

Frontend (/Frontend/.env)

Variable Description Example
VITE_API_URL Backend API root http://localhost:5000/api
VITE_SOCKET_URL Socket.io server URL http://localhost:5000

πŸ›‘οΈ Security Measures

  • HttpOnly Cookies: All JWT tokens are stored in httpOnly, secure, and sameSite cookies to prevent XSS.
  • Token Hashing: Reset and verification tokens are hashed with SHA-256 before being stored in the database.
  • Sensitive Data Protection: passwordHash is excluded from all API responses via Mongoose select: false.
  • Strong Hashing: Passwords use bcryptjs with 12 salt rounds.
  • Security Headers: Helmet.js implementation for protection against common web vulnerabilities.
  • Rate Limiting: Applied to authentication routes to prevent brute-force attacks.
  • CORS Policy: Restricted to the specific frontend origin only.
  • Auth Privacy: Password login is blocked for users who registered via Google OAuth.

🌐 Real-time Events (Socket.io)

Room: poll:{pollId}

Clients join this room when viewing a specific poll page.

Event: poll:response:update

Emitted by the server on every successful vote submission. Payload Shape:

{
  "totalResponses": 42,
  "questions": [
    {
      "questionId": "65b...",
      "options": [
        { "optionId": "65c...", "votesCount": 12 }
      ]
    }
  ]
}

πŸ“‚ Project Structure

Live-Polls-For-Feedback/
β”œβ”€β”€ Backend/
β”‚   β”œβ”€β”€ src/
β”‚   β”‚   β”œβ”€β”€ controllers/    # Route handlers
β”‚   β”‚   β”œβ”€β”€ services/       # Business logic
β”‚   β”‚   β”œβ”€β”€ schemas/        # Mongoose models
β”‚   β”‚   β”œβ”€β”€ routers/        # Express routes
β”‚   β”‚   β”œβ”€β”€ middlewares/    # Auth & Rate limiting
β”‚   β”‚   β”œβ”€β”€ utility/        # Helpers & Configs
β”‚   β”‚   └── types/          # TypeScript definitions
β”‚   └── package.json
└── Frontend/
    β”œβ”€β”€ src/
    β”‚   β”œβ”€β”€ @/              # UI components & Shadcn
    β”‚   β”œβ”€β”€ components/     # Layout & Shared components
    β”‚   β”œβ”€β”€ pages/          # View components
    β”‚   β”œβ”€β”€ services/       # API integration
    β”‚   β”œβ”€β”€ hooks/          # Custom React hooks
    β”‚   └── App.tsx         # Routing & Main logic
    └── package.json

About

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages