A modern, full-stack polling application built with Next.js 15, TypeScript, and Supabase. Create, share, and analyze polls with real-time voting, comprehensive analytics, and a beautiful user interface.
- Poll Creation & Management: Create polls with multiple options, descriptions, categories, and expiration dates
- Real-time Voting: Instant vote counting with live result updates
- Poll Sharing: Share polls via social media, email, or direct links
- User Dashboard: Comprehensive analytics and poll management interface
- Authentication: Secure user registration and login with Supabase Auth
- Anonymous Voting: Privacy-focused voting with IP tracking for abuse prevention
- Multiple Vote Options: Allow users to select multiple choices per poll
- Poll Expiration: Set automatic poll closure dates
- Responsive Design: Mobile-first design that works on all devices
- Type-Safe: Complete TypeScript implementation with comprehensive type definitions
- Row Level Security (RLS): Database-level access control
- Middleware Authentication: Automatic session management and token refresh
- Optimistic UI Updates: Instant feedback with proper error handling
- Comprehensive Testing: Unit tests for all critical business logic
- Next.js 15 - React framework with App Router
- TypeScript - Type-safe JavaScript development
- Tailwind CSS - Utility-first CSS framework
- Shadcn/ui - Modern React component library
- Lucide Icons - Beautiful SVG icon library
- Date-fns - Modern date utility library
- Supabase - Backend-as-a-Service with PostgreSQL
- Supabase Auth - Authentication and user management
- Row Level Security - Database-level access control
- Real-time Subscriptions - Live data updates
- Jest - JavaScript testing framework
- React Testing Library - Component testing utilities
- ESLint - Code linting and formatting
- TypeScript - Static type checking
Before setting up the project, ensure you have:
- Node.js (v18 or higher)
- npm or yarn package manager
- Supabase Account (free tier available)
- Git for version control
git clone https://github.com/your-username/alx-poll.git
cd alx-pollnpm install
# or
yarn installCreate a .env.local file in the root directory:
# Supabase Configuration
NEXT_PUBLIC_SUPABASE_URL=your_supabase_project_url
NEXT_PUBLIC_SUPABASE_ANON_KEY=your_supabase_anon_key
# Optional: Analytics and Monitoring
NEXT_PUBLIC_APP_URL=http://localhost:3000- Go to Supabase and create a new project
- Wait for the database to be ready (usually 2-3 minutes)
- Get your project URL and anon key from Settings > API
Run the following SQL in your Supabase SQL Editor:
-- Enable Row Level Security
ALTER TABLE auth.users ENABLE ROW LEVEL SECURITY;
-- Create polls table
CREATE TABLE polls (
id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
title TEXT NOT NULL,
description TEXT,
category TEXT,
created_by UUID REFERENCES auth.users(id) ON DELETE CASCADE,
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW(),
expires_at TIMESTAMPTZ,
is_active BOOLEAN DEFAULT true,
is_anonymous BOOLEAN DEFAULT false,
allow_multiple_votes BOOLEAN DEFAULT false,
total_votes INTEGER DEFAULT 0,
image_url TEXT
);
-- Create poll_options table
CREATE TABLE poll_options (
id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
poll_id UUID REFERENCES polls(id) ON DELETE CASCADE,
option_text TEXT NOT NULL,
option_order INTEGER NOT NULL,
votes_count INTEGER DEFAULT 0,
created_at TIMESTAMPTZ DEFAULT NOW()
);
-- Create votes table
CREATE TABLE votes (
id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
poll_id UUID REFERENCES polls(id) ON DELETE CASCADE,
poll_option_id UUID REFERENCES poll_options(id) ON DELETE CASCADE,
user_id UUID REFERENCES auth.users(id) ON DELETE SET NULL,
voter_ip INET,
created_at TIMESTAMPTZ DEFAULT NOW()
);
-- Row Level Security Policies
-- Polls table policies
CREATE POLICY "Users can view active polls and their own polls" ON polls
FOR SELECT USING (
is_active = true OR created_by = auth.uid()
);
CREATE POLICY "Users can create polls" ON polls
FOR INSERT WITH CHECK (created_by = auth.uid());
CREATE POLICY "Users can update their own polls" ON polls
FOR UPDATE USING (created_by = auth.uid());
CREATE POLICY "Users can delete their own polls" ON polls
FOR DELETE USING (created_by = auth.uid());
-- Poll options table policies
CREATE POLICY "Users can view poll options" ON poll_options
FOR SELECT USING (
EXISTS (
SELECT 1 FROM polls
WHERE polls.id = poll_options.poll_id
AND (polls.is_active = true OR polls.created_by = auth.uid())
)
);
CREATE POLICY "Poll creators can manage options" ON poll_options
FOR ALL USING (
EXISTS (
SELECT 1 FROM polls
WHERE polls.id = poll_options.poll_id
AND polls.created_by = auth.uid()
)
);
-- Votes table policies
CREATE POLICY "Users can view vote statistics" ON votes
FOR SELECT USING (true);
CREATE POLICY "Users can vote on active polls" ON votes
FOR INSERT WITH CHECK (
EXISTS (
SELECT 1 FROM polls
WHERE polls.id = votes.poll_id
AND polls.is_active = true
AND (polls.expires_at IS NULL OR polls.expires_at > NOW())
)
);
-- Enable RLS on all tables
ALTER TABLE polls ENABLE ROW LEVEL SECURITY;
ALTER TABLE poll_options ENABLE ROW LEVEL SECURITY;
ALTER TABLE votes ENABLE ROW LEVEL SECURITY;
-- Create indexes for performance
CREATE INDEX idx_polls_created_by ON polls(created_by);
CREATE INDEX idx_polls_is_active ON polls(is_active);
CREATE INDEX idx_poll_options_poll_id ON poll_options(poll_id);
CREATE INDEX idx_votes_poll_id ON votes(poll_id);
CREATE INDEX idx_votes_user_id ON votes(user_id);
CREATE INDEX idx_votes_poll_option_id ON votes(poll_option_id);npm run dev
# or
yarn devOpen http://localhost:3000 in your browser.
- Sign up or log in to your account
- Navigate to Dashboard and click "Create Poll"
- Fill in poll details:
Title: "What's your favorite programming language?" Description: "Help us understand developer preferences" Category: "Technology" - Add poll options:
- JavaScript
- Python
- TypeScript
- Go
- Configure settings:
- โ Active (allow voting)
- โ Anonymous (show voter names)
- โ Multiple votes (one choice per user)
- Set expiration (optional): 7 days from now
- Click "Create Poll"
- Browse polls on the polls page
- Click on a poll to view details
- Select your choice(s) from available options
- Click "Submit Vote"
- View real-time results immediately
- Open any poll you've created or can vote on
- Click the "Share" button
- Choose sharing method:
- Copy direct link
- Share on Twitter
- Share on Facebook
- Share via WhatsApp
- Use native sharing (mobile)
- Go to your Dashboard
- View statistics:
- Total polls created
- Total votes received
- Active polls count
- Average response rate
- Manage individual polls:
- Edit poll details
- Add/remove options
- Toggle active status
- View detailed analytics
# Run all tests
npm test
# Run tests in watch mode
npm run test:watch
# Run tests with coverage
npm run test:coverageThe application includes comprehensive tests for:
- Poll editing utilities (100% coverage)
- Form validation logic
- Data transformation functions
- Error handling scenarios
alx-poll/
โโโ app/ # Next.js App Router pages
โ โโโ (auth)/ # Authentication routes
โ โ โโโ login/
โ โ โโโ register/
โ โโโ (dashboard)/ # Protected dashboard routes
โ โ โโโ dashboard/
โ โโโ polls/ # Poll-related pages
โ โ โโโ [id]/ # Individual poll pages
โ โ โโโ create/ # Poll creation page
โ โโโ api/ # API routes
โ โ โโโ polls/ # Poll API endpoints
โ โโโ globals.css # Global styles
โ โโโ layout.tsx # Root layout
โ โโโ page.tsx # Home page
โโโ components/ # Reusable components
โ โโโ ui/ # Shadcn/ui components
โ โโโ edit-poll-form.tsx # Poll editing form
โ โโโ share-poll.tsx # Poll sharing component
โโโ contexts/ # React contexts
โ โโโ auth-context.tsx # Authentication context
โโโ lib/ # Utility libraries
โ โโโ supabase/ # Supabase configuration
โ โโโ utils/ # Utility functions
โ โ โโโ poll-edit.ts # Poll editing utilities
โ โโโ types.ts # TypeScript type definitions
โโโ __tests__/ # Test files
โ โโโ poll-edit.test.ts # Poll utility tests
โโโ middleware.ts # Next.js middleware
โโโ jest.config.js # Jest configuration
โโโ jest.setup.js # Jest setup
โโโ README.md # Project documentation
All API endpoints require authentication except for viewing active polls.
Fetch all polls with optional filtering.
Query Parameters:
category- Filter by poll categoryis_active- Filter by active status (true/false)created_by- Filter by creator user IDsearch- Search in title and descriptionsort_by- Sort field (created_at, total_votes, etc.)sort_order- Sort direction (asc/desc)
Response:
{
"polls": [
{
"id": "uuid",
"title": "Poll Title",
"description": "Poll description",
"is_active": true,
"total_votes": 42,
"poll_options": [...],
"created_at": "2024-01-01T00:00:00Z"
}
]
}Create a new poll.
Request Body:
{
"title": "What's your favorite color?",
"description": "Optional description",
"category": "General",
"options": ["Red", "Blue", "Green"],
"isAnonymous": false,
"allowMultipleVotes": false,
"endDate": "2024-12-31T23:59:59Z"
}Fetch a specific poll by ID.
Response:
{
"poll": {
"id": "uuid",
"title": "Poll Title",
"poll_options": [...],
"total_votes": 42
},
"hasVoted": false
}Update a poll (creators only).
Submit a vote for a poll.
Request Body:
{
"optionIds": ["option-uuid-1", "option-uuid-2"]
}-
Push to GitHub:
git add . git commit -m "Initial commit" git push origin main
-
Deploy to Vercel:
- Go to Vercel
- Import your GitHub repository
- Add environment variables
- Deploy
-
Configure environment variables in Vercel:
NEXT_PUBLIC_SUPABASE_URLNEXT_PUBLIC_SUPABASE_ANON_KEY
The application can be deployed to any platform that supports Node.js:
- Netlify
- Railway
- DigitalOcean App Platform
- Heroku
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Make your changes
- Add tests for new functionality
- Ensure all tests pass (
npm test) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
- Use TypeScript for type safety
- Follow existing naming conventions
- Add JSDoc comments for functions
- Write tests for new features
- Use Prettier for code formatting
This project is licensed under the MIT License - see the LICENSE file for details.
If you have any questions or run into issues:
- Check the existing issues
- Create a new issue with detailed information
- Join our community discussions
- Advanced Analytics: Detailed voting analytics and charts
- Poll Templates: Pre-built poll templates for common use cases
- Team Collaboration: Multi-user poll management
- API Rate Limiting: Enhanced security and abuse prevention
- Mobile App: Native mobile applications
- Integration APIs: Webhook support for external integrations
- Advanced Sharing: Embed polls in external websites
Built with โค๏ธ using Next.js, TypeScript, and Supabase.
