An elegant, minimalist system for managing high-value goodie bag distribution at exclusive events.
- Authentication: Secure login/signup with Supabase Auth
- Event Management: Create and manage multiple events with optional PIN protection
- CSV Guest Upload: Import guest lists with name, email, and tier
- QR Code Generation: Download individual or bulk QR codes for guests
- π§ Auto-Email Sending: Send beautiful QR invitations automatically via Resend
- Mobile Scanner: Camera-based QR code scanning with PIN protection
- Real-time Verification: Instant green/red/yellow feedback screens
- β‘ Real-Time Dashboard: Watch status update live as guests scan
- Guest Tracking: See claimed vs. unclaimed status in real-time
- π¨ Professional Email Templates: Beautiful, mobile-responsive invitations
- Beautiful UI: Clean, professional interface using Tailwind CSS
Everything is production-ready. No missing functionality!
- Node.js 18+ installed
- A Supabase account (free tier works perfectly)
- A modern web browser with camera access
- Go to supabase.com and create a new project
- Once your project is ready, go to SQL Editor
- Copy the entire contents of
supabase-schema.sqland run it - Go to Settings β API and copy:
- Project URL
anonpublic key
-
Copy
.env.local.exampleto.env.local:cp .env.local.example .env.local
-
Fill in your Supabase credentials:
NEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-key NEXT_PUBLIC_APP_URL=http://localhost:3000 -
(Optional) Add Resend API key for email sending:
- Sign up at resend.com (free for 3,000 emails/month)
- Get your API key from the dashboard
- Add to
.env.local:
RESEND_API_KEY=re_your_api_key_here
# Install dependencies
npm install
# Run development server
npm run devOpen http://localhost:3000 in your browser.
- Navigate to the signup page
- Create an account with your email
- You'll be automatically logged in
- Click "Create New Event"
- Enter event name (e.g., "Spring Collection Launch")
- Choose a date
- Click "Create Event"
- Open your event
- Use the sample CSV file provided (
sample-guests.csv) - Click "Upload CSV File" and select the file
- You should see 10 guests imported
- You can download individual QR codes by clicking "Download" next to each guest
- Or click "Download All QR Codes" to get all at once
- Save these QR codes (in a real scenario, these would be emailed automatically)
- Click "Open Scanner" in the top right
- Allow camera access when prompted
- Open one of the downloaded QR codes on another device (or print it)
- Point your camera at the QR code
- Watch the magic happen! π
- Green screen = Successfully claimed
- Red screen = Already claimed (try scanning the same code twice!)
- Orange screen = Invalid code
- Go back to the event page and refresh to see the status updated
Your CSV file must have exactly three columns:
name,email,tier
Ana Horvat,ana.horvat@example.com,VIP
Marco Rossi,marco.rossi@example.com,Press
Sophie Laurent,sophie.laurent@example.com,StandardTiers can be anything you want:
- VIP
- Press
- Standard
- Influencer
- Client
- etc.
This MVP uses public policies for the scanner to work without authentication. This is fine for testing but you'll want to tighten security for production:
- Implement scanner PIN protection
- Add rate limiting on the verification API
- Use timed access tokens instead of direct guest IDs
- Add IP whitelisting for scanner endpoints
The scanner works best on mobile devices. To test on your phone:
- Make sure your computer and phone are on the same network
- Find your computer's IP address:
- Mac: System Settings β Network
- Windows:
ipconfigin command prompt
- Update
.env.localwith your IP:NEXT_PUBLIC_APP_URL=http://192.168.1.xxx:3000 - Restart the dev server
- Open
http://192.168.1.xxx:3000on your phone
Edit app/scan/[eventId]/page.tsx to change result screen colors:
- Success:
bg-green-500 - Already Claimed:
bg-red-500 - Invalid:
bg-orange-500
You can use any tier names you want. The system doesn't enforce specific tiers.
When you're ready to implement auto-emailing, you'll integrate Resend in the event detail page where the "Download All QR Codes" button currently is.
- Push your code to GitHub
- Go to vercel.com
- Import your repository
- Add your environment variables:
NEXT_PUBLIC_SUPABASE_URLNEXT_PUBLIC_SUPABASE_ANON_KEYNEXT_PUBLIC_APP_URL(will be your Vercel URL)
- Deploy!
Your scanner will work on any device with a camera and internet connection.
- Make sure you're using HTTPS (required for camera access)
- Check browser permissions
- Try a different browser
- Ensure the QR code is well-lit
- Hold the phone steady
- Make sure the entire QR code is visible in the frame
- Check that the QR code URL matches your deployed domain
- Verify the guest exists in the database
- Verify your RLS policies are correctly applied
- Check that the SQL schema was run completely
- Ensure your Supabase project is active
To complete the remaining 20%:
-
Email Integration:
- Sign up for Resend
- Install:
npm install resend - Create API route to send emails with QR codes
- Add "Send Invitations" button to event page
-
Real-time Updates:
- Implement Supabase Realtime subscriptions
- Update guest list automatically when scans happen
-
Scanner Protection:
- Add PIN/password to scanner access
- Store in event table
- Require entry before showing scanner
-
Polish:
- Add loading states
- Improve error handling
- Add animations
- Custom email templates
- Pre-Event: Upload your guest list 2-3 days before
- QR Distribution: Either email automatically or print and include with invitations
- Scanner Setup: Open scanner on 2-3 tablets/phones at the exit
- Backup: Always have printed guest lists as backup
- Training: Show hostesses the three result screens before the event
- Post-Event: Export unclaimed guests list for follow-up courier deliveries
This is an MVP for testing. Issues are expected! When you find one:
- Check the browser console for errors
- Check the Supabase logs
- Verify your environment variables
- Make sure all SQL schema was applied
Built with β€οΈ for Bub and Bubble
Making every guest feel like a VIP, one scan at a time.