Skip to content
Β 
Β 

Repository files navigation

<<<<<<< HEAD

🐧 Badger

A full-stack Next.js 16 web app for student clubs to manage season-based badges, member requests, profiles, and a leaderboard.

Stack: Next.js 16 Β· Firebase (Firestore + Auth) Β· NextAuth.js Β· Tailwind CSS Β· TypeScript Β· Vercel

🐧 Club Badge System

A full-stack Next.js 14 web app for student clubs to manage season-based badges, member requests, profiles, and a leaderboard.

Stack: Next.js 14 Β· Firebase (Firestore + Auth) Β· NextAuth.js Β· Tailwind CSS Β· TypeScript Β· Vercel

4c7b7cf (resolve conflict)


✨ Features

Feature Description
Google Login Members sign in with their Google account via NextAuth
Season Badges Admins create badge sets per season with custom points
Badge Requests Members submit requests with proof; admins approve/reject
Member Profiles Earned badges grouped by season + request history
Leaderboard Members ranked by total points with a podium for top 3
Admin Panel Dashboard, request review, season & badge management
Role Protection Middleware blocks non-admins from admin routes

πŸš€ Local Setup

1. Clone and install

git clone https://github.com/YOUR_USERNAME/club-badge-system
cd club-badge-system
npm install

2. Set up Firebase

  1. Go to Firebase Console β†’ Create a project
  2. Enable Firestore Database (start in production mode)
  3. Enable Authentication β†’ Sign-in method β†’ Google β†’ Enable it
  4. Go to Project Settings β†’ General β†’ scroll to "Your apps" β†’ Add web app
  5. Copy the firebaseConfig values β€” you'll need them for .env.local
  6. Go to Project Settings β†’ Service Accounts β†’ Generate new private key
  7. Download the JSON file β€” you'll need project_id, client_email, and private_key

3. Set up Google OAuth (for NextAuth)

  1. Go to Google Cloud Console
  2. Select your Firebase project β†’ APIs & Services β†’ Credentials
  3. Create Credentials β†’ OAuth 2.0 Client ID β†’ Web application
  4. Add Authorized redirect URIs:
    • http://localhost:3000/api/auth/callback/google (local)
    • https://YOUR_APP.vercel.app/api/auth/callback/google (production)
  5. Copy the Client ID and Client Secret

4. Create .env.local

cp .env.example .env.local

Fill in all values in .env.local:

# Firebase Client SDK
NEXT_PUBLIC_FIREBASE_API_KEY=...
NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN=your-project.firebaseapp.com
NEXT_PUBLIC_FIREBASE_PROJECT_ID=your-project-id
NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET=your-project.appspot.com
NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID=...
NEXT_PUBLIC_FIREBASE_APP_ID=...

# Firebase Admin SDK
FIREBASE_ADMIN_PROJECT_ID=your-project-id
FIREBASE_ADMIN_CLIENT_EMAIL=firebase-adminsdk-xxxx@your-project.iam.gserviceaccount.com
FIREBASE_ADMIN_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----\nYOUR KEY\n-----END PRIVATE KEY-----\n"

# NextAuth
NEXTAUTH_SECRET=run `openssl rand -base64 32` to generate this
NEXTAUTH_URL=http://localhost:3000

# Google OAuth
GOOGLE_CLIENT_ID=...
GOOGLE_CLIENT_SECRET=...

5. Set up Firestore security rules

In Firebase Console β†’ Firestore β†’ Rules, paste:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {

    // Anyone can read users and leaderboard
    match /users/{uid} {
      allow read: if true;
      allow write: if request.auth != null && request.auth.uid == uid;

      // Earned badges sub-collection
      match /earnedBadges/{badgeId} {
        allow read: if true;
        allow write: if false; // only server (admin SDK) writes
      }
    }

    // Seasons and badges are public read
    match /seasons/{id} {
      allow read: if true;
      allow write: if false; // server only
    }

    match /badges/{id} {
      allow read: if true;
      allow write: if false; // server only
    }

    // Badge requests
    match /badgeRequests/{id} {
      allow read: if request.auth != null;
      allow create: if request.auth != null;
      allow update: if false; // server only
    }
  }
}

6. Run locally

npm run dev

Open http://localhost:3000


πŸ‘‘ Making Yourself an Admin

<<<<<<< HEAD

After signing in for the first time:

  1. Go to Firebase Console β†’ Firestore β†’ users collection
  2. Find your user document (it was created automatically on first login)
  3. Change the role field from "member" to "admin"
  4. Refresh the site β€” you'll now see the ~/admin link in the navbar

🌐 Deploy to Vercel

Option A β€” Vercel CLI

npm install -g vercel
vercel login
vercel

Option B β€” GitHub + Vercel Dashboard

  1. Push your code to a GitHub repository
  2. Go to vercel.com β†’ New Project β†’ Import your repo
  3. Framework: Next.js (auto-detected)
  4. Add all environment variables from .env.local in the Vercel dashboard
  5. For NEXTAUTH_URL, set it to https://YOUR_APP.vercel.app
  6. For FIREBASE_ADMIN_PRIVATE_KEY, paste the full key including \n characters
  7. Click Deploy

After deploying

  • Go back to Google Cloud Console β†’ OAuth credentials β†’ add your Vercel URL to Authorized redirect URIs: https://YOUR_APP.vercel.app/api/auth/callback/google
  • Go to Firebase Console β†’ Authentication β†’ Authorized domains β†’ add your Vercel domain

πŸ“ Project Structure

club-badge-system/
β”œβ”€β”€ app/
β”‚   β”œβ”€β”€ page.tsx                    # Home / landing
β”‚   β”œβ”€β”€ login/page.tsx              # Google sign-in
β”‚   β”œβ”€β”€ badges/
β”‚   β”‚   β”œβ”€β”€ page.tsx                # Browse season badges
β”‚   β”‚   └── [id]/request/page.tsx  # Submit badge request
β”‚   β”œβ”€β”€ leaderboard/page.tsx        # Ranked members
β”‚   β”œβ”€β”€ profile/[uid]/page.tsx      # Member profile
β”‚   β”œβ”€β”€ admin/
β”‚   β”‚   β”œβ”€β”€ page.tsx                # Admin dashboard
β”‚   β”‚   β”œβ”€β”€ requests/page.tsx       # Approve / reject
β”‚   β”‚   └── seasons/page.tsx        # Create seasons & badges
β”‚   └── api/
β”‚       β”œβ”€β”€ auth/[...nextauth]/     # NextAuth handler
β”‚       β”œβ”€β”€ badges/route.ts         # Badge CRUD
β”‚       β”œβ”€β”€ requests/
β”‚       β”‚   β”œβ”€β”€ route.ts            # Submit / list requests
β”‚       β”‚   └── [id]/route.ts       # Approve / reject
β”‚       └── admin/seasons/route.ts  # Season management
β”œβ”€β”€ components/
β”‚   β”œβ”€β”€ layout/Navbar.tsx           # Top nav
β”‚   └── ui/index.tsx                # Shared components
β”œβ”€β”€ lib/
β”‚   β”œβ”€β”€ firebase.ts                 # Client SDK
β”‚   β”œβ”€β”€ firebase-admin.ts           # Admin SDK (server only)
β”‚   β”œβ”€β”€ auth.ts                     # NextAuth config
β”‚   └── db.ts                       # Firestore helpers
β”œβ”€β”€ types/
β”‚   β”œβ”€β”€ index.ts                    # All TypeScript types
β”‚   └── next-auth.d.ts              # Session augmentation
β”œβ”€β”€ middleware.ts                   # Route protection
β”œβ”€β”€ .env.example                    # Env var template
└── vercel.json                     # Vercel config

πŸ”„ Typical Admin Workflow

  1. Start a season β†’ Admin panel β†’ Seasons β†’ Create "Spring 2025" β†’ Set active
  2. Add badges β†’ Select the season β†’ Fill in name, icon, description, points, category
  3. Members sign in β†’ Browse badges β†’ Submit requests with proof
  4. Admins review β†’ Admin panel β†’ Requests β†’ Approve or Reject (with optional note)
  5. Points update automatically β†’ Leaderboard re-ranks instantly

πŸ› οΈ Customization

What to change Where
Club name / branding app/layout.tsx, components/layout/Navbar.tsx
Color theme tailwind.config.js and app/globals.css
Badge categories types/index.ts β†’ BadgeCategory + app/badges/page.tsx
Leaderboard size app/leaderboard/page.tsx β†’ change limit(50)
Admin emails Manually set role: "admin" in Firestore

=======

After signing in for the first time:

  1. Go to Firebase Console β†’ Firestore β†’ users collection
  2. Find your user document (it was created automatically on first login)
  3. Change the role field from "member" to "admin"
  4. Refresh the site β€” you'll now see the ~/admin link in the navbar

🌐 Deploy to Vercel

Option A β€” Vercel CLI

npm install -g vercel
vercel login
vercel

Option B β€” GitHub + Vercel Dashboard

  1. Push your code to a GitHub repository
  2. Go to vercel.com β†’ New Project β†’ Import your repo
  3. Framework: Next.js (auto-detected)
  4. Add all environment variables from .env.local in the Vercel dashboard
  5. For NEXTAUTH_URL, set it to https://YOUR_APP.vercel.app
  6. For FIREBASE_ADMIN_PRIVATE_KEY, paste the full key including \n characters
  7. Click Deploy

After deploying

  • Go back to Google Cloud Console β†’ OAuth credentials β†’ add your Vercel URL to Authorized redirect URIs: https://YOUR_APP.vercel.app/api/auth/callback/google
  • Go to Firebase Console β†’ Authentication β†’ Authorized domains β†’ add your Vercel domain

πŸ“ Project Structure

club-badge-system/
β”œβ”€β”€ app/
β”‚   β”œβ”€β”€ page.tsx                    # Home / landing
β”‚   β”œβ”€β”€ login/page.tsx              # Google sign-in
β”‚   β”œβ”€β”€ badges/
β”‚   β”‚   β”œβ”€β”€ page.tsx                # Browse season badges
β”‚   β”‚   └── [id]/request/page.tsx  # Submit badge request
β”‚   β”œβ”€β”€ leaderboard/page.tsx        # Ranked members
β”‚   β”œβ”€β”€ profile/[uid]/page.tsx      # Member profile
β”‚   β”œβ”€β”€ admin/
β”‚   β”‚   β”œβ”€β”€ page.tsx                # Admin dashboard
β”‚   β”‚   β”œβ”€β”€ requests/page.tsx       # Approve / reject
β”‚   β”‚   └── seasons/page.tsx        # Create seasons & badges
β”‚   └── api/
β”‚       β”œβ”€β”€ auth/[...nextauth]/     # NextAuth handler
β”‚       β”œβ”€β”€ badges/route.ts         # Badge CRUD
β”‚       β”œβ”€β”€ requests/
β”‚       β”‚   β”œβ”€β”€ route.ts            # Submit / list requests
β”‚       β”‚   └── [id]/route.ts       # Approve / reject
β”‚       └── admin/seasons/route.ts  # Season management
β”œβ”€β”€ components/
β”‚   β”œβ”€β”€ layout/Navbar.tsx           # Top nav
β”‚   └── ui/index.tsx                # Shared components
β”œβ”€β”€ lib/
β”‚   β”œβ”€β”€ firebase.ts                 # Client SDK
β”‚   β”œβ”€β”€ firebase-admin.ts           # Admin SDK (server only)
β”‚   β”œβ”€β”€ auth.ts                     # NextAuth config
β”‚   └── db.ts                       # Firestore helpers
β”œβ”€β”€ types/
β”‚   β”œβ”€β”€ index.ts                    # All TypeScript types
β”‚   └── next-auth.d.ts              # Session augmentation
β”œβ”€β”€ middleware.ts                   # Route protection
β”œβ”€β”€ .env.example                    # Env var template
└── vercel.json                     # Vercel config

πŸ”„ Typical Admin Workflow

  1. Start a season β†’ Admin panel β†’ Seasons β†’ Create "Spring 2025" β†’ Set active
  2. Add badges β†’ Select the season β†’ Fill in name, icon, description, points, category
  3. Members sign in β†’ Browse badges β†’ Submit requests with proof
  4. Admins review β†’ Admin panel β†’ Requests β†’ Approve or Reject (with optional note)
  5. Points update automatically β†’ Leaderboard re-ranks instantly

πŸ› οΈ Customization

What to change Where
Club name / branding app/layout.tsx, components/layout/Navbar.tsx
Color theme tailwind.config.js and app/globals.css
Badge categories types/index.ts β†’ BadgeCategory + app/badges/page.tsx
Leaderboard size app/leaderboard/page.tsx β†’ change limit(50)
Admin emails Manually set role: "admin" in Firestore

4c7b7cf (resolve conflict)

Releases

Packages

Contributors

Languages