Skip to content

Latest commit

 

History

17 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Club QR

Ad-free QR code generator for university clubs.

Why this exists

Clubs typically use generic QR/link-shortener tools to point students at a Google Form for event signups. Those tools display ads before the redirect, which looks unprofessional and causes students to drop off before they ever reach the form.

Club QR replaces the ad-revenue model with a promotional interstitial: scanning the code takes the student to a page that highlights the club's other upcoming events, then sends them on to the actual signup form. No ads, anywhere in the flow.

How it works

  1. A student scans a QR code and hits /r/<code>
  2. The short code is looked up and the scan is logged
  3. If that code is marked "skip promo," the student is redirected straight to the target Google Form
  4. Otherwise, they see an interstitial with the club's upcoming events and a "Continue to sign-up" button
  5. Clicking through sends them to the target form

Features

  • Google-only admin login — no passwords to manage, self-serve club creation on first sign-in
  • Multi-admin clubs, with email invites for teammates
  • QR code generation with per-club or per-code branding (colors + logo)
  • Event management with a past/upcoming distinction
  • Postgres-backed rate limiting on login and redirect routes
  • Cached promo pages for fast redirect-page loads, invalidated instantly on branding/event changes

Tech stack

  • Framework: Next.js (App Router), TypeScript, Tailwind CSS
  • Database: PostgreSQL on Supabase, via Prisma ORM (@prisma/adapter-pg, pooled/pgbouncer connection)
  • Auth: NextAuth.js v5 (Auth.js) with Google OAuth, JWT sessions
  • QR generation: qrcode (server-side PNG), sharp for optional center-logo compositing
  • Email: nodemailer for admin-invite emails
  • Short codes: nanoid

Getting started

Prerequisites: Node.js, a Supabase Postgres instance, and a Google OAuth client (Google Cloud Console).

npm install

Create a .env file in the project root with:

DATABASE_URL=              # Supabase pooled (pgbouncer) connection string
AUTH_GOOGLE_ID=            # Google OAuth client ID
AUTH_GOOGLE_SECRET=        # Google OAuth client secret
AUTH_SECRET=               # generate with: npx auth secret
NEXT_PUBLIC_BASE_URL=      # base URL used for short-code links and OAuth callback
OWNER_EMAIL=               # email allowed to view /dashboard/feedback

# SMTP, for admin-invite emails
SMTP_HOST=
SMTP_PORT=587
SMTP_USER=
SMTP_PASSWORD=
MAIL_FROM=                 # optional, defaults to SMTP_USER

Then set up the database and start the dev server:

npm run prisma:migrate
npm run dev

Available scripts

  • npm run dev — start the dev server
  • npm run build / npm start — production build / run
  • npm run lint — ESLint
  • npm run prisma:migrate — create/apply a migration
  • npm run prisma:studio — browse the database

Project structure

src/app/dashboard/    admin dashboard — QR codes, events, branding, admins, feedback
src/app/r/[code]/     public redirect + promo interstitial
src/app/api/auth/     NextAuth route handlers
src/lib/              Prisma client, session helpers, rate limiting, mail, promo cache
prisma/               schema + migrations

Deployment

Targets Vercel. Because Vercel functions are serverless, use a connection-pooling-friendly Postgres URL (e.g. Supabase's pgbouncer connection string) rather than a raw long-lived connection.

About

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages