Inavora is a real-time interactive presentation platform similar to Mentimeter, built with React, Node.js, Socket.IO, and MongoDB. It enables presenters to create engaging presentations with various interactive slide types and collect real-time audience responses.
- Features
- Tech Stack
- Project Structure
- Prerequisites
- Installation
- Configuration
- Running the Application
- Interaction Types
- API Documentation
- Socket Events
- Database Schema
- Contributing
- License
- Real-time Interactions: Live updates using Socket.IO for instant feedback
- Multiple Interaction Types: 12+ different slide types for diverse engagement
- User Authentication: Secure authentication using Firebase Auth with JWT
- Presentation Management: Create, edit, delete, and organize presentations
- Live Presentation Mode: Present slides with real-time participant tracking
- Participant Join: Easy access via 6-digit codes
- Responsive Design: Works seamlessly on desktop and mobile devices
- Data Visualization: Beautiful charts and graphs for response analytics
- Multiple Choice - Traditional poll with multiple options
- Word Cloud - Visual representation of text responses
- Open-Ended - Free text responses with optional voting
- Scales - Rating scales with customizable ranges
- Ranking - Drag-and-drop item ranking
- Q&A - Live question and answer sessions
- Guess Number - Number guessing game with distribution
- 100 Points - Allocate points across options
- 2x2 Grid - Position items on a two-axis grid
- Pin on Image - Click locations on an image
- Quiz - Timed quiz with scoring and leaderboards
- Leaderboard - Display quiz results and rankings
- React 19.1.1 - UI library
- Vite 7.1.7 - Build tool and dev server
- React Router 7.9.3 - Client-side routing
- Socket.IO Client 4.8.1 - Real-time communication
- Axios 1.12.2 - HTTP client
- Tailwind CSS 4.1.13 - Utility-first CSS framework
- Framer Motion 12.23.22 - Animation library
- Chart.js 4.5.0 - Data visualization
- D3.js 7.9.0 - Advanced visualizations
- Lucide React - Icon library
- React Hot Toast - Toast notifications
- @dnd-kit - Drag and drop functionality
- Node.js - Runtime environment
- Express 5.1.0 - Web framework
- Socket.IO 4.8.1 - Real-time bidirectional communication
- MongoDB - NoSQL database
- Mongoose 8.18.3 - MongoDB ODM
- Firebase Admin 13.5.0 - Firebase authentication
- JWT (jsonwebtoken 9.0.2) - Token-based authentication
- Bcrypt.js 3.0.2 - Password hashing
- Cloudinary 2.7.0 - Image upload and management
- CORS 2.8.5 - Cross-origin resource sharing
Inavora/
βββ backend/
β βββ src/
β β βββ config/
β β β βββ database.js # MongoDB connection
β β β βββ firebase.js # Firebase Admin initialization
β β βββ controllers/
β β β βββ authController.js # Authentication logic
β β β βββ presentationController.js # Presentation CRUD
β β β βββ uploadController.js # Image upload handling
β β βββ interactions/
β β β βββ index.js # Interaction registry
β β β βββ multipleChoice.js # MCQ handler
β β β βββ wordCloud.js # Word cloud handler
β β β βββ openEnded.js # Open-ended handler
β β β βββ scales.js # Scales handler
β β β βββ ranking.js # Ranking handler
β β β βββ qna.js # Q&A handler
β β β βββ guessNumber.js # Guess number handler
β β β βββ hundredPoints.js # 100 points handler
β β β βββ twoByTwoGrid.js # 2x2 grid handler
β β β βββ pinOnImage.js # Pin on image handler
β β β βββ quiz.js # Quiz handler
β β βββ middleware/
β β β βββ auth.js # JWT authentication middleware
β β βββ models/
β β β βββ User.js # User schema
β β β βββ Presentation.js # Presentation schema
β β β βββ Slide.js # Slide schema
β β β βββ Response.js # Response schema
β β β βββ ParticipantScore.js # Quiz score schema
β β β βββ Image.js # Image metadata schema
β β βββ routes/
β β β βββ authRoutes.js # Auth endpoints
β β β βββ presentationRoutes.js # Presentation endpoints
β β β βββ uploadRoutes.js # Upload endpoints
β β βββ services/
β β β βββ cloudinaryService.js # Cloudinary integration
β β β βββ qnaSession.js # Q&A session management
β β β βββ guessNumberSession.js # Guess number session
β β β βββ quizSessionService.js # Quiz session management
β β β βββ quizScoringService.js # Quiz scoring logic
β β β βββ leaderboardService.js # Leaderboard generation
β β βββ socket/
β β β βββ socketHandlers.js # Main socket event handlers
β β β βββ quizHandlers.js # Quiz-specific handlers
β β β βββ openEnded.js # Open-ended handlers
β β βββ server.js # Express server setup
β βββ .env # Environment variables (not in git)
β βββ .env-example # Environment template
β βββ firebase.json # Firebase service account
β βββ package.json # Backend dependencies
β
βββ frontend/
β βββ src/
β β βββ components/
β β β βββ common/ # Reusable components
β β β βββ interactions/ # Interaction-specific components
β β β β βββ mcq/
β β β β βββ wordCloud/
β β β β βββ openEnded/
β β β β βββ scales/
β β β β βββ ranking/
β β β β βββ qna/
β β β β βββ guessNumber/
β β β β βββ hundredPoints/
β β β β βββ twoByTwoGrid/
β β β β βββ pinOnImage/
β β β β βββ quiz/
β β β β βββ leaderboard/
β β β βββ pages/
β β β β βββ Landing.jsx # Landing page
β β β β βββ Presentation.jsx # Presentation editor
β β β β βββ PresentMode.jsx # Live presentation view
β β β β βββ JoinPresentation.jsx # Participant view
β β β βββ presentation/ # Presentation components
β β β βββ Dashboard.jsx # User dashboard
β β β βββ Login.jsx # Login page
β β β βββ Register.jsx # Registration page
β β βββ config/
β β β βββ api.js # Axios configuration
β β β βββ firebase.js # Firebase client config
β β βββ context/
β β β βββ AuthContext.jsx # Authentication context
β β βββ services/
β β β βββ presentationService.js # API service layer
β β βββ App.jsx # Main app component
β β βββ main.jsx # App entry point
β β βββ index.css # Global styles
β βββ .env # Frontend environment variables
β βββ .env-example # Frontend env template
β βββ index.html # HTML template
β βββ vite.config.js # Vite configuration
β βββ package.json # Frontend dependencies
β
βββ README.md # This file
Before you begin, ensure you have the following installed:
- Node.js (v18.0.0 or higher)
- npm (v9.0.0 or higher) or yarn
- MongoDB (v6.0 or higher) - Local or Atlas
- Firebase Account - For authentication
- Cloudinary Account (Optional) - For image uploads
git clone https://github.com/ridham1906/inavora.git
cd inavoracd backend
npm installcd ../frontend
npm install- Create
.envfile in thebackenddirectory:
cd backend
cp .env-example .env- Configure environment variables in
backend/.env:
# Server Configuration
PORT=4000
# Database
MONGODB_URI=mongodb://localhost:27017/inavora
# Or use MongoDB Atlas:
# MONGODB_URI=mongodb+srv://username:password@cluster.mongodb.net/inavora
# JWT Configuration
JWT_SECRET=your_super_secret_jwt_key_change_this_in_production
JWT_EXPIRES_IN=7d
# Firebase Admin SDK
FIREBASE_PROJECT_ID=your-firebase-project-id
FIREBASE_CLIENT_EMAIL=your-firebase-client-email
FIREBASE_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----\nYour private key here\n-----END PRIVATE KEY-----\n"
# Cloudinary (Optional - for image uploads)
CLOUDINARY_CLOUD_NAME=your_cloud_name
CLOUDINARY_API_KEY=your_api_key
CLOUDINARY_API_SECRET=your_api_secret
# Frontend URL (for CORS)
FRONTEND_URL=http://localhost:5173- Firebase Service Account Setup:
- Go to Firebase Console
- Select your project
- Go to Project Settings > Service Accounts
- Click "Generate New Private Key"
- Save the JSON file as
firebase.jsonin thebackenddirectory
- Create
.envfile in thefrontenddirectory:
cd frontend
cp .env-example .env- Configure environment variables in
frontend/.env:
# Firebase Client Configuration
VITE_FIREBASE_API_KEY=your_firebase_api_key
VITE_FIREBASE_AUTH_DOMAIN=your-project.firebaseapp.com
VITE_FIREBASE_PROJECT_ID=your-firebase-project-id
VITE_FIREBASE_BUCKET=your-project.appspot.com
VITE_FIREBASE_MESSAGING_SENDER_ID=your_sender_id
VITE_FIREBASE_APP_ID=your_app_id
# Backend API URL
VITE_API_URL=http://localhost:4000- Firebase Client Setup:
- Go to Firebase Console > Project Settings > General
- Scroll to "Your apps" section
- Click "Web" icon to add a web app
- Copy the configuration values to your
.envfile
Local MongoDB:
mongodMongoDB Atlas:
- Ensure your connection string is correctly configured in
backend/.env
cd backend
npm run devThe backend server will start on http://localhost:4000
cd frontend
npm run devThe frontend will start on http://localhost:5173
cd backend
npm startcd frontend
npm run build
npm run preview- Description: Traditional poll with multiple options
- Use Cases: Surveys, voting, quick polls
- Features: Real-time vote counting, percentage display
- Description: Visual representation of text responses
- Use Cases: Brainstorming, feedback collection
- Features: Dynamic sizing based on frequency, multiple submissions per participant
- Description: Free text responses with optional voting
- Use Cases: Ideas, suggestions, feedback
- Features: Voting system, response moderation
- Description: Rating scales with customizable ranges
- Use Cases: Satisfaction surveys, ratings
- Features: Multiple statements, average calculation, distribution charts
- Description: Drag-and-drop item ranking
- Use Cases: Prioritization, preference ordering
- Features: Average rank calculation, visual ranking display
- Description: Live question and answer sessions
- Use Cases: Town halls, AMAs, lectures
- Features: Question moderation, mark as answered, active question highlighting
- Description: Number guessing game with distribution
- Use Cases: Estimation games, icebreakers
- Features: Configurable range, distribution visualization, correct answer reveal
- Description: Allocate 100 points across options
- Use Cases: Budget allocation, priority distribution
- Features: Point validation, average allocation display
- Description: Position items on a two-axis grid
- Use Cases: Prioritization matrices, positioning
- Features: Customizable axes, scatter plot visualization
- Description: Click locations on an image
- Use Cases: Location identification, hotspot analysis
- Features: Image upload, pin clustering, correct area definition
- Description: Timed quiz with scoring
- Use Cases: Knowledge testing, training
- Features: Time limits, points system, instant feedback, leaderboards
- Description: Display quiz results and rankings
- Use Cases: Competition tracking, gamification
- Features: Auto-generated after quiz slides, cumulative scoring
Exchange Firebase token for JWT
Request:
{
"firebaseToken": "string"
}
Response:
{
"token": "string",
"user": {
"id": "string",
"email": "string",
"displayName": "string"
}
}Get current user (requires JWT)
Response:
{
"user": {
"id": "string",
"email": "string",
"displayName": "string"
}
}Create a new presentation
Request:
{
"title": "string"
}
Response:
{
"message": "Presentation created successfully",
"presentation": {
"id": "string",
"title": "string",
"accessCode": "string",
"isLive": false,
"currentSlideIndex": 0
}
}Get all user presentations
Get presentation by ID with slides
Update presentation
Delete presentation and all related data
Create a new slide
Update a slide
Delete a slide
Upload image to Cloudinary
Start a presentation
socket.emit('start-presentation', {
presentationId: 'string',
userId: 'string',
startIndex: number
});Participant joins presentation
socket.emit('join-presentation', {
accessCode: 'string',
participantId: 'string'
});Submit a response
socket.emit('submit-response', {
presentationId: 'string',
slideId: 'string',
participantId: 'string',
participantName: 'string',
answer: any
});Change to a different slide
socket.emit('change-slide', {
presentationId: 'string',
slideIndex: number
});End the presentation
socket.emit('end-presentation', {
presentationId: 'string'
});Presentation has started
Successfully joined presentation
New response received
Slide has changed
New participant joined
Presentation has ended
Error occurred
{
firebaseUid: String (unique, required),
email: String (unique, required),
displayName: String,
createdAt: Date,
updatedAt: Date
}{
userId: ObjectId (ref: User),
title: String (required),
isLive: Boolean (default: false),
currentSlideIndex: Number (default: 0),
accessCode: String (unique, 6 digits),
showResults: Boolean (default: true),
createdAt: Date,
updatedAt: Date
}{
presentationId: ObjectId (ref: Presentation),
order: Number (required),
type: String (enum: interaction types),
question: String (required),
// Type-specific fields...
createdAt: Date,
updatedAt: Date
}{
presentationId: ObjectId (ref: Presentation),
slideId: ObjectId (ref: Slide),
participantId: String (required),
participantName: String,
answer: Mixed (required),
submissionCount: Number,
votes: Number,
isCorrect: Boolean,
responseTime: Number,
points: Number,
submittedAt: Date
}Contributions are welcome! Please follow these steps:
- Fork the repository
- Create a feature branch (
git checkout -b feature/AmazingFeature) - Commit your changes (
git commit -m 'Add some AmazingFeature') - Push to the branch (
git push origin feature/AmazingFeature) - Open a Pull Request
This project is licensed under the ISC License.
@Ridham
- Inspired by Mentimeter
- Built with modern web technologies
- Community contributions and feedback
For support, email your-email@example.com or open an issue in the repository.
Happy Presenting! π