A beautiful, multi-tenant SaaS application for displaying team birthdays on digital signage using SignPresenter. Built with React and Supabase.
Live Demo: bdaypresenter.com
This is a serverless web application with the following components:
- Frontend: React SPA hosted on Vercel (auto-deploys from GitHub)
- Backend: Supabase (managed PostgreSQL database, authentication, and file storage)
- Domain: bdaypresenter.com (GoDaddy DNS β Vercel)
- Version Control: GitHub (mbyrdLCS/bdaypresenter)
- User Signs Up β Creates account in Supabase Auth
- Profile Created β Automatic trigger creates user profile with unique display URL slug
- Add Team Members β Stored in Supabase database with photos in Supabase Storage
- Display Page β Public URL at
/display/{slug}shows birthdays in real-time - SignPresenter β Points to the display URL, auto-updates when data changes (no re-configuration needed!)
The beauty of this system: Set it once in SignPresenter, and changes auto-update!
- User adds/edits/deletes birthdays in dashboard
- Changes are saved to Supabase database
- Display page fetches fresh data on each load
- SignPresenter shows updated content automatically
- No need to re-add URLs or refresh anything in SignPresenter
- π Multi-tenant Authentication - Each organization has their own account
- π₯ Team Management - Add, edit, and delete team members
- πΈ Photo Uploads - Upload profile photos for each team member
- π¨ Seasonal Themes - Automatically changing themes for each month
- π Monthly View - Shows all birthdays for the current month
- π Daily Spotlight - Full-screen celebration on actual birthdays
- π Auto-rotation - Cycles through multiple birthdays on the same day
- π Unique Display URLs - Each organization gets their own display URL
- πΊ SignPresenter Ready - Optimized for digital signage
- Frontend: React + Vite
- Styling: Tailwind CSS
- Backend: Supabase (PostgreSQL + Auth + Storage)
- Routing: React Router
- Deployment: Vercel (recommended)
- Node.js 20.x or higher
- npm or yarn
- A Supabase account (free tier works great)
cd birthday-celebration-app
npm install- Go to https://supabase.com
- Click "Start your project"
- Create a new project (note: it may take 2-3 minutes to set up)
- In your Supabase dashboard, go to the SQL Editor
- Copy the contents of
database-schema.sql - Paste and run the SQL script
- This will create:
profilestableteam_memberstable- Row Level Security policies
- Automatic profile creation trigger
- In your Supabase dashboard, go to Storage
- Click "New bucket"
- Create a bucket named
profile-photos - Make it public
- Add the following policy for uploads:
- Policy name: "Authenticated users can upload"
- Allowed operation: INSERT
- Target roles: authenticated
- Policy definition:
(bucket_id = 'profile-photos')
- In your Supabase dashboard, go to Project Settings β API
- Copy your Project URL (looks like
https://xxxxx.supabase.co) - Copy your anon/public key (starts with
eyJ...)
Create a .env file in the root directory:
cp .env.example .envEdit .env and add your Supabase credentials:
VITE_SUPABASE_URL=your-supabase-project-url
VITE_SUPABASE_ANON_KEY=your-supabase-anon-keynpm run devThe app will be available at http://localhost:5173
- Sign Up: Create an account with your organization name
- Add Team Members: Go to the dashboard and add team members with:
- Name
- Birthday (month and day)
- Photo (optional)
- Get Your Display URL: Copy the unique URL from your dashboard
- Set Up SignPresenter:
- Add a new website element in SignPresenter
- Paste your display URL
- Set the duration as desired (recommended: 30-60 seconds)
- SignPresenter Website Guide
- Monthly View: Shows all birthdays for the current month in a grid layout
- Birthday Spotlight: On someone's actual birthday, shows a full-screen celebration with their photo
- Multiple Birthdays: If multiple people share a birthday, it rotates between them every 10 seconds
- Seasonal Themes: Each month has a unique color scheme and emoji theme
| Month | Theme | Colors | Emoji |
|---|---|---|---|
| January | Winter Wonderland | Blue & White | βοΈ |
| February | Love & Hearts | Pink & Red | π |
| March | Spring Awakening | Green & Lime | π· |
| April | Spring Blossoms | Pink & Purple | πΈ |
| May | Sunshine Days | Yellow & Orange | π» |
| June | Summer Vibes | Cyan & Blue | βοΈ |
| July | Summer Fun | Red & Orange | π |
| August | Beach Days | Teal & Cyan | ποΈ |
| September | Autumn Begins | Amber & Orange | π |
| October | Fall Harvest | Orange & Red | π |
| November | Cozy Season | Brown & Amber | π |
| December | Winter Holidays | Red & Green | π |
Live URLs:
- Production: https://bdaypresenter.com
- Vercel URL: https://bdaypresenter.vercel.app
- GitHub Repo: https://github.com/mbyrdLCS/bdaypresenter
Infrastructure:
- Hosting: Vercel (Free tier - auto-deploys from GitHub main branch)
- Database: Supabase (Free tier - hosted PostgreSQL)
- Domain: GoDaddy (bdaypresenter.com)
- DNS: Points to Vercel via A record to 216.198.79.1
Environment Variables in Vercel:
VITE_SUPABASE_URL: Your Supabase project URLVITE_SUPABASE_ANON_KEY: Your Supabase anonymous key
The app uses continuous deployment - it's fully automated!
- Make your changes locally
- Test locally with
npm run dev - Commit and push to GitHub:
git add . git commit -m "Description of changes" git push origin main
- That's it! Vercel automatically:
- Detects the push to main branch
- Runs the build (
npm run build) - Deploys to production
- Updates https://bdaypresenter.com
- Usually takes 1-2 minutes
You can watch the deployment progress at: https://vercel.com/dashboard
This section is for reference - the app is already deployed!
- β
Created GitHub repository at
mbyrdLCS/bdaypresenter - β Connected Vercel to GitHub
- β Configured environment variables in Vercel
- β Set up custom domain bdaypresenter.com
- β
Configured DNS in GoDaddy:
- A record: @ β 216.198.79.1
- CNAME: www β cname.vercel-dns.com
- β
Updated Supabase redirect URLs to include:
- http://localhost:5173/**
- https://bdaypresenter.com/**
- https://*.vercel.app/**
- Fork this repo or create your own
- Set up Supabase project and run
database-schema.sql - Go to vercel.com and import your repo
- Add environment variables in Vercel
- Deploy
- (Optional) Add custom domain in Vercel settings
birthday-celebration-app/
βββ src/
β βββ components/ # Reusable React components
β βββ contexts/ # React contexts (Auth)
β βββ pages/ # Page components
β β βββ Home.jsx # Landing page
β β βββ Login.jsx # Login page
β β βββ Signup.jsx # Signup page
β β βββ Dashboard.jsx # Admin dashboard
β β βββ Display.jsx # Public birthday display
β βββ services/ # External services
β β βββ supabase.js # Supabase client
β βββ utils/ # Utility functions
β βββ App.jsx # Main app component with routing
β βββ main.jsx # App entry point
β βββ index.css # Global styles with Tailwind
βββ database-schema.sql # Supabase database schema
βββ .env.example # Example environment variables
βββ README.md # This file
- Row Level Security (RLS): Enabled on all tables
- User Isolation: Each user can only access their own data
- Public Display URLs: Display pages are publicly accessible (read-only)
- Authenticated Uploads: Only authenticated users can upload photos
- Secure Storage: Photos stored in Supabase Storage with proper policies
- Create a new branch:
git checkout -b feature/your-feature-name
- Make your changes
- Test locally
- Commit and push:
git add . git commit -m "Add: your feature description" git push origin feature/your-feature-name
- Merge to main when ready (or create PR on GitHub)
- Main styles:
src/index.css(Tailwind utilities and custom classes) - Component styles: Tailwind classes in JSX files
- Color scheme: Edit gradient colors in component files
- Seasonal themes:
src/pages/Display.jsx(line ~100-200)
- Make changes in Supabase dashboard SQL editor
- Update
database-schema.sqlfile to keep it in sync - Document changes in this README
Local development:
- Edit
.envfile - Restart dev server
Production (Vercel):
- Go to Vercel dashboard
- Select bdaypresenter project
- Settings β Environment Variables
- Add/Edit variables
- Redeploy (or push to trigger auto-deploy)
- Make sure your
.envfile exists and has the correct variables - Restart your development server after creating/updating
.env
- Verify you created the
profile-photosbucket in Supabase Storage - Ensure the bucket is set to public
- Check that upload policies are configured correctly
- Verify the database schema was run successfully
- Check that team members were added through the dashboard
- Ensure the correct user ID is in the URL
- Make sure
tailwind.config.jsandpostcss.config.jsexist - Verify
@import "tailwindcss"is insrc/index.css - Try deleting
node_modulesand runningnpm installagain
- Check DNS settings in GoDaddy
- Verify A record points to 216.198.79.1
- Check Vercel domain configuration
- DNS changes can take up to 48 hours (usually 5-30 minutes)
- Check build logs in Vercel dashboard
- Ensure environment variables are set
- Verify
package.jsonscripts are correct - Check for TypeScript/ESLint errors
See database-schema.sql for the complete schema with:
- User profiles with organization names
- Team members with birthdays
- Row Level Security policies
- Automatic triggers
- Storage bucket configuration
This project is licensed under a Non-Commercial License with Attribution Requirement.
Key Points:
- β Free to use for organizations and non-profits
- β Can modify and adapt for your needs
- β Must keep SignPresenter.com references
- β Cannot sell or use commercially
- β Cannot remove attribution
See LICENSE file for full details.
For commercial licensing inquiries, contact: mike@signpresenter.com
Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
- Fork the repository
- Create your feature branch (
git checkout -b feature/AmazingFeature) - Test your changes thoroughly
- Commit your changes (
git commit -m 'Add some AmazingFeature') - Push to the branch (
git push origin feature/AmazingFeature) - Open a Pull Request
- Issues: GitHub Issues
- Email: mike@signpresenter.com
- Live Demo: bdaypresenter.com
- SignPresenter Docs: support.signpresenter.com
- Built with β€οΈ for organizations celebrating their teams
- Powered by SignPresenter for digital signage displays
- Thanks to all contributors and organizations using this system
- Custom theme builder
- Work anniversary tracking
- Team milestones and achievements
- Photo slideshow mode
- Multiple team support per organization
- Birthday reminder notifications
Made with β€οΈ for the SignPresenter community