A polished community gaming awards voting web app built with Next.js 14, Supabase, and TailwindCSS. Users can vote for their favorite games across multiple categories, with a clean wizard-style voting flow and real-time results.
- Authentication: Google and Twitch OAuth integration
- Voting Wizard: Step-by-step category voting with progress tracking
- Ballot Management: Draft votes with final submission
- Real-time Results: Live vote counting and winner displays
- Mobile-Friendly: Responsive design for all devices
- Row Level Security: Supabase RLS policies for data protection
- Role-Based Access: Admin vs. regular user permissions
- Vote Integrity: One vote per category per user
- Ballot Finalization: Prevents vote changes after submission
- Category Management: Create, edit, and organize award categories
- Nominee Management: Add and manage game nominees
- Voting Controls: Set voting start/end times
- Live Analytics: Real-time voting results and statistics
- Frontend: Next.js 14 (App Router), React 19, TypeScript
- Styling: TailwindCSS, shadcn/ui components
- Backend: Supabase (PostgreSQL + Auth + Real-time)
- Authentication: Supabase Auth with OAuth providers
- Database: PostgreSQL with Row Level Security
- Node.js 18+ and npm
- Supabase account and project
- Google OAuth app (optional)
- Twitch OAuth app (optional)
git clone <your-repo-url>
cd bobo-game-awards
npm install- Create a new Supabase project at supabase.com
- Go to Project Settings > API to get your keys
- Run the database migrations:
-- Copy and paste the contents of:
-- supabase/migrations/001_initial_schema.sql
-- supabase/migrations/002_rls_policies.sql
-- supabase/migrations/003_functions.sqlCreate a .env.local file:
# Supabase Configuration
NEXT_PUBLIC_SUPABASE_URL=your_supabase_project_url
NEXT_PUBLIC_SUPABASE_ANON_KEY=your_supabase_anon_key
SUPABASE_SERVICE_ROLE_KEY=your_supabase_service_role_key
# OAuth Providers (configure in Supabase Auth settings)
GOOGLE_CLIENT_ID=your_google_client_id
GOOGLE_CLIENT_SECRET=your_google_client_secret
TWITCH_CLIENT_ID=your_twitch_client_id
TWITCH_CLIENT_SECRET=your_twitch_client_secretIn your Supabase dashboard:
- Go to Authentication > Providers
- Enable Google and/or Twitch
- Add your OAuth app credentials
- Set redirect URL to:
https://your-domain.com/auth/callback
After signing up through the app:
-- In Supabase SQL Editor, make yourself an admin:
UPDATE public.users
SET is_admin = true
WHERE id = 'your-user-id';npm run devOpen http://localhost:3000 to see your app!
The app uses 5 main tables:
users: User profiles linked to Supabase authcategories: Award categories (Game of the Year, etc.)nominees: Games nominated in each categoryvotes: Individual user votes (one per category per user)ballots: Tracks user voting completion and finalization
- User signs in with Google/Twitch
- Browses categories on home page
- Enters voting wizard (
/vote/category/[slug]) - Votes are saved as drafts automatically
- User can review and finalize ballot
- After finalization, votes are locked
- Admin creates categories with slugs
- Adds nominees to each category
- Sets voting start/end times (optional)
- Monitors results in real-time
- Results become public after voting ends
- Live vote counts and percentages
- Winner highlighting with crown icons
- Category-by-category breakdown
- Public access only after voting ends (unless admin)
GET /api/categories- List all categoriesGET /api/categories/[slug]- Get category with nomineesPOST /api/votes- Cast or update a votePOST /api/ballot/finalize- Finalize user's ballotGET /api/results- Get voting results (with access control)
- Push your code to GitHub
- Connect your repo to Vercel
- Add environment variables in Vercel dashboard
- Deploy!
The app works on any platform that supports Next.js:
- Netlify
- Railway
- DigitalOcean App Platform
- AWS Amplify
- Fork the repository
- Create a feature branch
- Make your changes
- Test thoroughly
- Submit a pull request
MIT License - see LICENSE file for details
For issues and questions:
- Check the GitHub issues
- Create a new issue with details
- Include error messages and steps to reproduce
Built with ❤️ for the gaming community