diff --git a/AUTHENTICATION_SETUP.md b/AUTHENTICATION_SETUP.md deleted file mode 100644 index 7252989..0000000 --- a/AUTHENTICATION_SETUP.md +++ /dev/null @@ -1,194 +0,0 @@ -# Authentication Setup Guide - -This polling app uses Supabase for user authentication with email verification. Follow these steps to set up authentication: - -## 1. Create a Supabase Project - -1. Go to [supabase.com](https://supabase.com) and create a new account or sign in -2. Create a new project -3. Wait for the project to be set up - -## 2. Get Your Supabase Credentials - -1. In your Supabase dashboard, go to **Settings** > **API** -2. Copy the following values: - - **Project URL** (starts with `https://`) - - **anon public** key (starts with `eyJ`) - -## 3. Set Up Environment Variables - -Create a `.env.local` file in the root of your project with the following content: - -```env -NEXT_PUBLIC_SUPABASE_URL=your_project_url_here -NEXT_PUBLIC_SUPABASE_ANON_KEY=your_anon_key_here -``` - -Replace `your_project_url_here` and `your_anon_key_here` with the actual values from your Supabase project. - -## 4. Configure Supabase Authentication - -1. In your Supabase dashboard, go to **Authentication** > **Settings** -2. Under **Site URL**, add your development URL (e.g., `http://localhost:3000`) -3. Under **Redirect URLs**, add: - - `http://localhost:3000/auth/callback` - - `http://localhost:3000/login` - - `http://localhost:3000/register` - - `http://localhost:3000/verify-email` - -## 5. Enable Email Verification - -1. Go to **Authentication** > **Settings** -2. Under **Email Auth**, make sure **Enable email confirmations** is checked -3. Configure email templates (optional but recommended) - -## 6. Email Templates (Recommended) - -1. Go to **Authentication** > **Email Templates** -2. Customize the email templates for: - - **Confirm signup**: Welcome users and provide clear verification instructions - - **Reset password**: Help users reset their password securely - - **Magic link**: For passwordless authentication (optional) - -### Sample Email Template Content: - -**Confirm signup template:** - -``` -Subject: Verify your email address - Polling App - -Hi there, - -Thanks for signing up for Polling App! Please click the link below to verify your email address: - -[Confirm your email address]({{ .ConfirmationURL }}) - -This link will expire in 24 hours. - -If you didn't create an account, you can safely ignore this email. - -Best regards, -The Polling App Team -``` - -## 7. Start the Development Server - -```bash -npm run dev -``` - -## Features - -- **User Registration**: Users can create accounts with email and password -- **Email Verification**: Automatic email verification with resend functionality -- **User Login**: Secure authentication with email and password -- **Protected Routes**: Automatic redirection for unauthenticated users -- **User Profile**: Display user information and logout functionality -- **Form Validation**: Client-side validation with Zod -- **Toast Notifications**: User feedback for authentication actions -- **Middleware Protection**: Server-side route protection -- **Email Verification Page**: Dedicated page for email verification - -## Authentication Flow - -1. **Registration**: Users sign up with email, password, and full name -2. **Email Verification**: Users receive a verification email with a link -3. **Email Confirmation**: Users click the link to verify their email -4. **Login**: Users sign in with email and password (only after verification) -5. **Session Management**: Automatic session handling with cookies -6. **Logout**: Users can sign out and are redirected to login page - -## Email Verification Flow - -1. **User registers** → Verification email sent automatically -2. **User clicks email link** → Redirected to `/auth/callback` -3. **Email verified** → User redirected to `/polls` -4. **Email not verified** → User redirected to `/login` with error message -5. **Resend verification** → Users can request new verification emails - -## Components - -- `AuthProvider`: Context provider for authentication state -- `LoginForm`: Form component for user login with email verification reminder -- `RegisterForm`: Form component for user registration with email verification flow -- `EmailVerificationForm`: Component for resending verification emails -- `UserProfile`: Component for displaying user info and logout -- `ProtectedRoute`: Wrapper for protecting routes - -## Routes - -- `/login` - User login page -- `/register` - User registration page -- `/verify-email` - Email verification page -- `/auth/callback` - Authentication callback handler -- `/polls` - Protected dashboard (requires authentication) - -## Middleware - -The app includes middleware that: - -- Redirects unauthenticated users to `/login` -- Redirects authenticated users away from public routes (`/login`, `/register`, `/verify-email`) -- Handles session refresh automatically -- Protects all routes except public ones - -## Security Features - -- Server-side authentication checks -- Secure cookie handling -- Form validation and sanitization -- Protected API routes -- Automatic session management -- Email verification requirement -- CSRF protection via Supabase - -## Testing the Setup - -1. **Register a new user**: - - - Go to `/register` - - Fill out the form - - Check your email for verification link - -2. **Verify email**: - - - Click the verification link in your email - - You should be redirected to `/polls` - -3. **Login**: - - - Go to `/login` - - Sign in with your credentials - - You should be redirected to `/polls` - -4. **Test protected routes**: - - - Try accessing `/polls` without being logged in - - You should be redirected to `/login` - -5. **Test email verification**: - - Go to `/verify-email` - - Request a new verification email - - Check your email for the new link - -## Troubleshooting - -### Email not received: - -- Check spam folder -- Verify email address is correct -- Check Supabase email settings -- Try resending from `/verify-email` - -### Verification link not working: - -- Check redirect URLs in Supabase settings -- Ensure environment variables are correct -- Check browser console for errors - -### Login issues: - -- Make sure email is verified -- Check password is correct -- Verify Supabase project is active -- Check network connectivity diff --git a/DATABASE_SETUP.md b/DATABASE_SETUP.md deleted file mode 100644 index f61066e..0000000 --- a/DATABASE_SETUP.md +++ /dev/null @@ -1,111 +0,0 @@ -# Database Setup Guide - -## Setting up Supabase Database Schema - -Follow these steps to create the required database tables and functions for the Polling App: - -### 1. Access Supabase SQL Editor - -1. Go to your [Supabase Dashboard](https://supabase.com/dashboard) -2. Select your project -3. Navigate to **SQL Editor** in the left sidebar -4. Click **New Query** - -### 2. Run the Schema Script - -1. Copy the entire contents of `supabase-schema.sql` -2. Paste it into the SQL Editor -3. Click **Run** to execute the script - -### 3. Verify Tables Creation - -After running the script, verify these tables were created: - -- `profiles` - User profile information -- `polls` - Main polls table -- `poll_options` - Poll voting options -- `poll_votes` - Individual votes cast by users - -### 4. Check Row Level Security (RLS) - -The script automatically enables RLS and creates policies for: -- Public read access to polls and options -- User-specific write permissions -- Vote tracking and validation - -### 5. Environment Variables - -Ensure your `.env.local` file contains: - -```env -NEXT_PUBLIC_SUPABASE_URL=your_supabase_project_url -NEXT_PUBLIC_SUPABASE_ANON_KEY=your_supabase_anon_key -SUPABASE_SECRET_KEY=your_supabase_service_role_key -NEXT_PUBLIC_SITE_URL=http://localhost:3000 -``` - -### 6. Test the Setup - -1. Start your development server: `npm run dev` -2. Register a new user account -3. Try creating a poll -4. Test voting functionality - -### Database Schema Overview - -#### Tables Structure: - -**profiles** -- `id` (UUID, references auth.users) -- `full_name` (TEXT) -- `avatar_url` (TEXT) -- `created_at`, `updated_at` (TIMESTAMP) - -**polls** -- `id` (UUID, primary key) -- `title`, `description` (TEXT) -- `category`, `status` (TEXT) -- `created_by` (UUID, references auth.users) -- `total_votes` (INTEGER) -- `allow_multiple_votes`, `anonymous_voting` (BOOLEAN) -- `created_at`, `updated_at`, `ends_at` (TIMESTAMP) - -**poll_options** -- `id` (UUID, primary key) -- `poll_id` (UUID, references polls) -- `text` (TEXT) -- `votes` (INTEGER) -- `order_index` (INTEGER) - -**poll_votes** -- `id` (UUID, primary key) -- `poll_id`, `option_id` (UUID, references) -- `user_id` (UUID, references auth.users) -- `ip_address` (INET) -- `created_at` (TIMESTAMP) - -### Automatic Features - -The schema includes: -- **Auto vote counting** - Triggers update vote counts automatically -- **Profile creation** - New user profiles created on signup -- **Timestamp updates** - `updated_at` fields auto-updated -- **Data integrity** - Foreign key constraints and unique constraints -- **Security** - RLS policies for data access control - -### Troubleshooting - -If you encounter issues: - -1. **Permission errors**: Check RLS policies are correctly applied -2. **Foreign key errors**: Ensure user is authenticated when creating polls -3. **Vote counting issues**: Verify triggers are active -4. **Connection errors**: Check environment variables - -Run this query to check if tables exist: -```sql -SELECT table_name -FROM information_schema.tables -WHERE table_schema = 'public' -AND table_name IN ('profiles', 'polls', 'poll_options', 'poll_votes'); -``` diff --git a/ENV_SETUP.md b/ENV_SETUP.md deleted file mode 100644 index 317e957..0000000 --- a/ENV_SETUP.md +++ /dev/null @@ -1,53 +0,0 @@ -# Environment Variables Setup - -To fix the runtime error and get the authentication system working, you need to set up your environment variables. - -## Quick Setup - -1. **Create a `.env.local` file** in the root of your project (same level as `package.json`) - -2. **Add the following content** to your `.env.local` file: - -```env -# Supabase Configuration -NEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co -NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-key-here -NEXT_PUBLIC_SITE_URL=http://localhost:3000 -``` - -3. **Replace the placeholder values** with your actual Supabase credentials: - - Get your project URL from Supabase Dashboard → Settings → API - - Get your anon key from Supabase Dashboard → Settings → API - -## Example `.env.local` file: - -```env -NEXT_PUBLIC_SUPABASE_URL=https://abcdefghijklmnop.supabase.co -NEXT_PUBLIC_SUPABASE_ANON_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImFiY2RlZmdoaWprbG1ub3AiLCJyb2xlIjoiYW5vbiIsImlhdCI6MTYzNjU2NzI5MCwiZXhwIjoxOTUyMTQzMjkwfQ.example -NEXT_PUBLIC_SITE_URL=http://localhost:3000 -``` - -## After Setup - -1. **Restart your development server**: - - ```bash - npm run dev - ``` - -2. **The runtime error should be resolved** and the authentication system will work properly. - -## Getting Supabase Credentials - -1. Go to [supabase.com](https://supabase.com) -2. Create a new project or select an existing one -3. Go to **Settings** → **API** -4. Copy the **Project URL** and **anon public** key -5. Paste them in your `.env.local` file - -## Troubleshooting - -- **Make sure the file is named exactly `.env.local`** (with the dot at the beginning) -- **Restart your development server** after creating the file -- **Check the browser console** for any remaining errors -- **Verify your Supabase project is active** and the credentials are correct diff --git a/README.md b/README.md index 56c6672..ee70895 100644 --- a/README.md +++ b/README.md @@ -52,7 +52,7 @@ pnpm install ### 3. Environment Variables -Create a `.env.local` file in the root directory: +Create a `.env.local` file in the root of your project with the following content. You can get the `SUPABASE_URL` and `SUPABASE_ANON_KEY` from your Supabase project's **Settings > API** page. ```env # Supabase Configuration @@ -64,12 +64,18 @@ SUPABASE_SECRET_KEY=your_supabase_secret_key NEXT_PUBLIC_SITE_URL=http://localhost:3000 ``` -### 4. Supabase Setup +### 4. Supabase Database Setup -1. Create a new project in [Supabase](https://supabase.com) -2. Run the database schema from `supabase-schema.sql` -3. Set up authentication providers (email/password is enabled by default) -4. Configure email templates for verification (optional) +1. Go to the **SQL Editor** in your Supabase dashboard. +2. Create a **New Query**. +3. Run the schema scripts from the `/migrations` directory in order. This will create the necessary tables (`profiles`, `polls`, `poll_options`, `poll_votes`), enable Row Level Security (RLS), and set up required policies. + +### 5. Supabase Authentication Setup + +1. In your Supabase dashboard, go to **Authentication > Settings**. +2. Under **Site URL**, add your development URL: `http://localhost:3000`. +3. Under **Redirect URLs**, add your callback URL: `http://localhost:3000/auth/callback`. +4. Enable **Email confirmations** under the **Email Auth** section. ### 5. Database Schema @@ -96,6 +102,36 @@ pnpm dev Open [http://localhost:3000](http://localhost:3000) to view the application. +### Environment & Supabase Setup + +1. Create `.env.local` with: + +```env +# Supabase Configuration +NEXT_PUBLIC_SUPABASE_URL=your_supabase_project_url +NEXT_PUBLIC_SUPABASE_ANON_KEY=your_supabase_anon_key +SUPABASE_SECRET_KEY=your_supabase_secret_key +NEXT_PUBLIC_SUPABASE_PUBLISHABLE_DEFAULT_KEY=${NEXT_PUBLIC_SUPABASE_ANON_KEY} + +# Site Configuration +NEXT_PUBLIC_SITE_URL=http://localhost:3000 + +# (Optional) Email Provider +# RESEND_API_KEY=your_resend_key +# SENDGRID_API_KEY=your_sendgrid_key +``` + +2. Apply database migrations in Supabase SQL Editor (or CLI): + +- `migrations/0002_add_user_roles.sql` (roles + RLS) +- `migrations/0003_add_email_to_profiles.sql` (email on profiles) +- `migrations/0004_create_poll_shares.sql` (share analytics + RLS) +- `migrations/0005_create_comments.sql` (comments + RLS) + +3. Configure Auth (Email/Password enabled) and set Redirect URL to `${NEXT_PUBLIC_SITE_URL}/auth/callback`. + +4. Optional: seed admin role using Supabase SQL (set `profiles.role = 'admin'`). + ### Production Build ```bash @@ -135,7 +171,7 @@ npm start - Copy the direct link - Share on social media (Twitter, Facebook, LinkedIn) - Generate QR code for mobile sharing -3. **Track Engagement**: Monitor vote counts and sharing statistics +3. **Track Engagement**: Monitor vote counts and sharing statistics (Shares today, Total shares) ### Managing Your Polls @@ -198,6 +234,16 @@ alx-polly/ - **Error Handling**: User-friendly error messages and fallbacks - **Accessibility**: WCAG compliant with proper ARIA labels +## 🤖 AI Usage (Tools and Context) + +- Development assistance leveraged AI for code generation and refactoring with context on: + - Next.js App Router best practices (Server Components, Server Actions) + - Supabase SSR client usage and RLS-safe queries + - Error handling and redirect patterns (handling `NEXT_REDIRECT` digest) + - QR code integration (`qrcode.react`) and analytics design +- Tools used in-editor: code search, lints, and automated edits; no secrets were hardcoded. +- All database keys are loaded via environment variables. + ## 🚀 Deployment ### Vercel (Recommended) @@ -206,6 +252,15 @@ alx-polly/ 2. Set environment variables in Vercel dashboard 3. Deploy automatically on every push to main branch +### Production Readiness Notes + +- Environment variables set in hosting provider (same as `.env.local`). +- Ensure middleware allows public access to `/polls` and `/auth/callback` for QR usage. +- Confirm DB migrations applied and RLS policies enabled. +- Confirm `poll_shares` and `comments` tables exist and policies applied. +- Set `NEXT_PUBLIC_SITE_URL` to production domain for correct email redirects and QR URLs. +- If enabling email notifications, set `RESEND_API_KEY` or `SENDGRID_API_KEY`. + ### Other Platforms The app can be deployed to any platform that supports Next.js: diff --git a/app/(auth)/login/page.tsx b/app/(auth)/login/page.tsx index c9f4882..dd8dfd3 100644 --- a/app/(auth)/login/page.tsx +++ b/app/(auth)/login/page.tsx @@ -1,6 +1,9 @@ import { Metadata } from "next" import Link from "next/link" import { LoginForm } from "@/components/auth/login-form" +import { AuthLayout } from "@/components/auth/auth-layout" +import { LoginSidePanel } from "@/components/auth/login-side-panel" +import { AuthGuard } from "@/components/auth/auth-guard" export const metadata: Metadata = { title: "Login | Polling App", @@ -9,41 +12,26 @@ export const metadata: Metadata = { export default function LoginPage() { return ( -
--- "Create polls, gather opinions, and make data-driven decisions with our intuitive polling platform." -
-
- Enter your credentials to access your account -
-
-
- Don't have an account? Sign up
-
+
+ Enter your credentials to access your account
+ Welcome back
+
+
+ + Don't have an account? Sign up + +
+ + ) } diff --git a/app/(auth)/register/page.tsx b/app/(auth)/register/page.tsx index eab6638..372119a 100644 --- a/app/(auth)/register/page.tsx +++ b/app/(auth)/register/page.tsx @@ -1,6 +1,9 @@ import { Metadata } from "next" import Link from "next/link" import { RegisterForm } from "@/components/auth/register-form" +import { AuthLayout } from "@/components/auth/auth-layout" +import { RegisterSidePanel } from "@/components/auth/register-side-panel" +import { AuthGuard } from "@/components/auth/auth-guard" export const metadata: Metadata = { title: "Register | Polling App", @@ -9,41 +12,26 @@ export const metadata: Metadata = { export default function RegisterPage() { return ( ---- "Join thousands of users who trust our platform for creating meaningful polls and gathering insights." -
-
- Enter your information below to create your account -
-
-
- Already have an account? Sign in
-
+
+ Enter your information below to create your account
+ Create an account
+
+
+ + Already have an account? Sign in + +
+ + ) } diff --git a/app/(dashboard)/admin-test/page.tsx b/app/(dashboard)/admin-test/page.tsx new file mode 100644 index 0000000..552d222 --- /dev/null +++ b/app/(dashboard)/admin-test/page.tsx @@ -0,0 +1,144 @@ +import { Metadata } from "next"; +import { createServerComponentClient } from "@/lib/supabase-server"; +import { redirect } from "next/navigation"; + +export const metadata: Metadata = { + title: "Admin Test | Polling App", + description: "Test admin access and role detection", +}; + +async function getUserProfile(userId: string) { + const supabase = await createServerComponentClient(); + + const { data: profile, error } = await supabase + .from("profiles") + .select("id, full_name, role") + .eq("id", userId) + .single(); + + return { profile, error }; +} + +export default async function AdminTestPage() { + const supabase = await createServerComponentClient(); + + // Check if user is authenticated + const { + data: { user }, + error: authError, + } = await supabase.auth.getUser(); + + if (authError || !user) { + redirect("/login"); + } + + // Get user profile and check if user has admin access + const { profile, error: profileError } = await getUserProfile(user.id); + + return ( ++ User ID: {user?.id} +
++ Email: {user?.email} +
++ Auth Error:{" "} + {authError ? String(authError) : "None"} +
++ Profile Error: {profileError.message} +
++ Error Code: {profileError.code} +
++ Error Details: {profileError.details} +
++ Profile ID: {profile.id} +
++ Full Name: {profile.full_name} +
++ Role:{" "} + + {profile.role} + +
++ Is Admin/Moderator:{" "} + {profile.role === "admin" || profile.role === "moderator" + ? "✅ YES" + : "❌ NO"} +
+Profile data is null
+ )} +❌ ADMIN ACCESS DENIED
++ Your role ({profile?.role || "unknown"}) does not have admin + privileges. +
+If you see a role above, the database query is working.
+If there's an error, check that:
+To make this user an admin, run this SQL in Supabase:
+
+ UPDATE public.profiles SET role = 'admin' WHERE id = '{user.id}';
+
+ - Polls you've created -
-- Across all your polls -
-- Currently accepting votes -
-- Per poll average -
-- Your latest polls and their current status -
-- Discover and participate in polls from the community -
-+ Total Polls +
+{totalPolls}
+ Active Polls +
+{activePolls}
++ Total Votes +
+{totalVotes.toLocaleString()}
++ Browse and vote on polls from the community +
++ You don't have permission to access this page. +
+Role: {userRole}
+Is Admin: {isAdmin ? "Yes" : "No"}
+Is Moderator: {isModerator ? "Yes" : "No"}
++ Can Access Admin Panel:{" "} + {hasPermission("canAccessAdminPanel") ? "Yes" : "No"} +
+Permissions: {JSON.stringify(permissions, null, 2)}
++ {isInitializing ? "Loading..." : "Redirecting..."} +
++ Please verify your email address to unlock all features and ensure your account security. + Check your inbox for a verification link from us. +
+