A real-time collaborative voting application where team members can submit ideas, vote, and add comments. Built with React, Vite, Tailwind CSS, and Firebase Realtime Database.
- Real-time Synchronization: All changes (votes, suggestions, comments) sync instantly across all users
- Voting System: Upvote and downvote suggestions with live score updates
- Comments with Labels: Add comments labeled as Pro, Con, or Neutral
- Smart Sorting: Suggestions automatically sorted by score (upvotes - downvotes)
- User-Friendly: Simple display name entry, no complex authentication required
- Responsive Design: Works seamlessly on desktop, tablet, and mobile devices
- Modern UI: Clean, intuitive interface with smooth animations
- Frontend: React 19 with Vite
- Styling: Tailwind CSS 4
- Backend: Firebase Realtime Database
- Deployment: Vercel
- Node.js (v18 or higher)
- npm or yarn
- A Firebase account (free tier is sufficient)
- A GitHub account (for Vercel deployment)
- Go to Firebase Console
- Click "Add project" or "Create a project"
- Enter a project name (e.g., "team-voting")
- (Optional) Enable Google Analytics
- Click "Create project"
- In your Firebase project, navigate to Build → Realtime Database
- Click Create Database
- Choose a location close to your users
- Start in Test mode for development (you can update security rules later)
- Click Enable
- In the Firebase Console, click the gear icon ⚙️ next to "Project Overview"
- Select Project settings
- Scroll down to "Your apps" section
- Click the Web icon (
</>) to add a web app - Register your app with a nickname (e.g., "Voting Web App")
- Copy the
firebaseConfigobject values
For development, the test mode rules are fine. For production, update your Realtime Database rules:
- Go to Realtime Database → Rules
- Update to the following (or customize based on your needs):
{
"rules": {
"suggestions": {
".read": true,
".write": true,
"$suggestionId": {
".validate": "newData.hasChildren(['text', 'author', 'timestamp'])"
}
}
}
}Note: These rules allow anyone to read and write. For better security in production, implement proper authentication and more restrictive rules.
git clone https://github.com/your-username/voter-cc.git
cd voter-ccnpm install- Copy the
.env.examplefile to.env:
cp .env.example .env- Open
.envand add your Firebase configuration values from step 3 above:
VITE_FIREBASE_API_KEY=your_actual_api_key_here
VITE_FIREBASE_AUTH_DOMAIN=your-project.firebaseapp.com
VITE_FIREBASE_DATABASE_URL=https://your-project.firebaseio.com
VITE_FIREBASE_PROJECT_ID=your-project-id
VITE_FIREBASE_STORAGE_BUCKET=your-project.appspot.com
VITE_FIREBASE_MESSAGING_SENDER_ID=123456789
VITE_FIREBASE_APP_ID=1:123456789:web:abcdef123456npm run devThe app will be available at http://localhost:5173
npm run buildThe production-ready files will be in the dist directory.
npm run preview- Push your code to GitHub:
git add .
git commit -m "Initial commit"
git push origin main-
Connect to Vercel:
- Go to Vercel
- Sign in with your GitHub account
- Click "Add New Project"
- Import your GitHub repository
- Vercel will auto-detect Vite configuration
-
Add Environment Variables:
- In the Vercel project settings, go to "Environment Variables"
- Add each of your Firebase environment variables:
VITE_FIREBASE_API_KEYVITE_FIREBASE_AUTH_DOMAINVITE_FIREBASE_DATABASE_URLVITE_FIREBASE_PROJECT_IDVITE_FIREBASE_STORAGE_BUCKETVITE_FIREBASE_MESSAGING_SENDER_IDVITE_FIREBASE_APP_ID
-
Deploy:
- Click "Deploy"
- Vercel will build and deploy your app
- You'll get a URL like
https://your-app.vercel.app
-
Automatic Deployments:
- Every push to your
mainbranch will automatically trigger a new deployment - Pull requests will get preview deployments
- Every push to your
- Install Vercel CLI:
npm install -g vercel- Login to Vercel:
vercel login- Deploy:
vercelFollow the prompts, and make sure to add your environment variables when prompted.
vercel --env VITE_FIREBASE_API_KEY=your_value --env VITE_FIREBASE_AUTH_DOMAIN=your_value ...voter-cc/
├── src/
│ ├── components/
│ │ ├── UserLogin.jsx # Display name entry component
│ │ ├── SuggestionForm.jsx # Form to submit new suggestions
│ │ └── SuggestionCard.jsx # Individual suggestion with votes/comments
│ ├── hooks/
│ │ └── useSuggestions.js # Custom hook for Firebase real-time sync
│ ├── config/
│ │ └── firebase.js # Firebase configuration
│ ├── App.jsx # Main application component
│ ├── main.jsx # Application entry point
│ └── index.css # Global styles with Tailwind
├── public/ # Static assets
├── index.html # HTML template
├── vite.config.js # Vite configuration
├── tailwind.config.js # Tailwind CSS configuration
├── postcss.config.js # PostCSS configuration
├── .env.example # Environment variables template
├── .gitignore # Git ignore rules
├── package.json # Dependencies and scripts
└── README.md # This file
The app uses Firebase Realtime Database with the following structure:
/suggestions
/{suggestionId}
- id: string
- text: string
- author: string (display name)
- timestamp: number
- votes: {
{userId}: "up" | "down"
}
- comments: {
{commentId}: {
text: string
author: string
type: "pro" | "con" | "neutral"
timestamp: number
}
}
- Enter Your Name: When you first visit, enter your display name
- Submit Ideas: Type your suggestion in the input field and click "Add Suggestion"
- Vote: Click the up or down arrow on any suggestion to vote
- Change Vote: Click the same arrow again to remove your vote, or click the opposite arrow to change it
- Add Comments: Click the comment button to expand the comment section
- Label Comments: Choose Pro, Con, or Neutral when adding a comment
- Real-time Updates: Watch as other team members' votes and suggestions appear instantly
- Each user can upvote or downvote any suggestion
- Users can change their vote at any time
- Score is calculated as: upvotes - downvotes
- Suggestions are automatically sorted by score
- Three comment types: Pro (positive), Con (negative), Neutral
- Each comment shows the author and timestamp
- Comments are color-coded by type
- Newest comments appear first
- Uses Firebase Realtime Database for instant synchronization
- No need to refresh the page
- All changes propagate to all users within milliseconds
Problem: "Failed to connect to Firebase"
Solution:
- Verify all environment variables are correctly set in
.env - Ensure the Realtime Database is enabled in Firebase Console
- Check that your Firebase rules allow read/write access
Problem: "Module not found" errors
Solution:
rm -rf node_modules package-lock.json
npm installProblem: App works locally but not on Vercel
Solution:
- Verify all environment variables are added in Vercel project settings
- Check build logs in Vercel dashboard for specific errors
- Ensure your
.envfile is NOT committed to Git (it should be in.gitignore)
Problem: "Permission denied" when reading/writing data
Solution:
- Go to Firebase Console → Realtime Database → Rules
- Temporarily set rules to test mode (shown in Firebase Setup section)
- For production, implement proper authentication and security rules
Edit tailwind.config.js to customize colors:
theme: {
extend: {
colors: {
primary: '#your-color',
secondary: '#your-color',
}
}
}Edit src/hooks/useSuggestions.js to change how votes are handled.
Some ideas for enhancements:
- User avatars
- Suggestion categories/tags
- Search and filter
- Export results to CSV
- Voting deadlines
- Anonymous suggestions option
- Vote weight/priority system
- The app is optimized for teams of 10-20 users
- For larger teams (50+), consider implementing pagination
- Firebase Realtime Database is highly scalable
- Vercel's CDN ensures fast global delivery
- Implement Authentication: Use Firebase Authentication for verified users
- Restrict Database Rules: Only allow authenticated users to write
- Rate Limiting: Implement rate limits to prevent spam
- Input Validation: Add server-side validation for suggestions and comments
- Environment Variables: Never commit
.envfiles to version control
For issues or questions:
- Check the Firebase Documentation
- Review Vite Documentation
- Check Vercel Documentation
MIT License - feel free to use this for your team projects!
Contributions are welcome! Please feel free to submit a Pull Request.
Built with ❤️ using React, Vite, Tailwind CSS, and Firebase