A live talent show competition platform. Audiences vote, judges score, and one judge per act is kept secret until the final reveal.
- Homepage listing upcoming, active, and past competitions
- Contest page with confirmed acts, social links, and live judge scores
- Colour-coded score table (cold blue → hot red gradient) per act
- Thumbs voting (1–3) per act during live contests, fingerprint-deduplicated
- Leaderboard podium for finished contests with mystery judge reveal
- Self-registration with act type, stage name, description, and social links
- Email confirmation flow (admin approves → contestant clicks link)
- One contestant can register multiple acts per contest with different types
- Dedicated judge panel showing active contest and currently performing act
- Score submission (0–10) per act via modal
- Link to the public contest page and vice versa
- Dashboard with stats linking to filtered views (active contests, pending acts, etc.)
- User management with multi-role assignment
- Contest CRUD with date/time, filterable by status
- Acts management across all contests (filterable by status)
- Per-contest: approve/reject acts, send confirmation emails, assign/remove judges
- Act types managed from the admin panel (name, badge colour, sort order)
- Live control: set which act is currently performing
- Hidden judge: one random judge assigned per act each time it goes live
- Finalize: locks scores, reveals mystery judge publicly
Homepage — Live Now / Upcoming / Past Competitions

Active contest — LIVE act highlighted, judge scores with gradient, thumbs voting, mystery judge masked

Finished contest — leaderboard podium, all judge scores revealed including mystery judge

Admin dashboard — stat cards linking to filtered views

Judge panel — active act highlighted, score button per act

| Layer | Choice |
|---|---|
| Backend | PHP 8.x, no framework |
| Database | MySQL / MariaDB |
| Frontend | Bootstrap 5 + Bootstrap Icons (CDN) |
| Auth | PHP sessions + bcrypt |
| PHPMailer via SMTP |
JudgeRay/
├── config/
│ └── config.php ← DB credentials, BASE_URL, SMTP settings
├── includes/
│ ├── db.php ← PDO singleton
│ ├── auth.php ← session helpers, role guards
│ ├── functions.php ← flash, helpers, score colour, act types (DB-driven)
│ ├── mail.php ← PHPMailer wrapper + confirmation template
│ ├── layout.php ← shared Bootstrap nav/head/foot
│ └── admin_layout.php ← admin sidebar wrapper
├── lib/
│ └── PHPMailer/ ← PHPMailer.php, SMTP.php, Exception.php
├── public/ ← web root (point doc root here)
│ ├── index.php ← homepage
│ ├── contest.php ← contest detail, scores, voting
│ ├── register.php ← contestant registration
│ ├── confirm.php ← email confirmation token landing
│ ├── login.php
│ ├── logout.php
│ ├── vote.php ← AJAX thumbs vote endpoint
│ ├── admin/
│ │ ├── index.php ← dashboard
│ │ ├── users.php ← user + role management
│ │ ├── contests.php ← contest CRUD + status filter
│ │ ├── acts.php ← acts across all contests + status filter
│ │ ├── act_types.php ← act type management
│ │ ├── contest_detail.php ← approve acts, assign judges, live control
│ │ ├── contest_activate.php
│ │ └── finalize.php
│ └── judge/
│ ├── index.php ← judge dashboard
│ └── score.php ← score submission endpoint
├── SQL/
│ ├── schema.sql ← full DB schema (run once on fresh install)
│ ├── seed.sql ← sample data (optional)
│ ├── cleanup.sql ← wipe all data, keep structure
│ ├── reset.sql ← drop + recreate all tables
│ └── migrate_act_types_table.sql ← migration: add act_types table
├── .htaccess ← error logging config
├── deploy.md ← deployment guide
└── plan.md ← original architecture notes
Run SQL/schema.sql in phpMyAdmin or via CLI:
mysql -u root -p < SQL/schema.sqlEdit config/config.php:
define('DB_HOST', 'localhost');
define('DB_NAME', 'judgeray');
define('DB_USER', 'your_db_user');
define('DB_PASS', 'your_db_password');
define('BASE_URL', 'https://yourdomain.com'); // no trailing slash — points to public/ web root
define('MAIL_FROM_NAME', 'JudgeRay');
// SMTP
define('SMTP_HOST', 'mail.yourdomain.com');
define('SMTP_PORT', 587);
define('SMTP_USER', 'your@email.com');
define('SMTP_PASS', 'your_smtp_password');
define('SMTP_SECURE', 'tls'); // 'tls' for 587, 'ssl' for 465Point the document root at the public/ directory. admin/ and judge/ live inside public/ and are accessible normally.
php -r "echo password_hash('yourpassword', PASSWORD_DEFAULT) . PHP_EOL;"Then in MySQL:
INSERT INTO users (name, email, password_hash) VALUES ('Admin', 'you@example.com', 'HASH');
INSERT INTO user_roles (user_id, role) VALUES (LAST_INSERT_ID(), 'admin'), (LAST_INSERT_ID(), 'contest_manager');Run SQL/cleanup.sql then SQL/seed.sql in phpMyAdmin for sample contests, acts, judges and scores. All seed passwords: judgeray.
| Role | Can do |
|---|---|
| admin | Everything — users, contests, act types, full management |
| contest_manager | Manage contests and acts (no user/type admin) |
| judge | Score acts in assigned contests |
| contestant | Register acts, confirm participation |
A user can hold multiple roles simultaneously.
Managed in Admin → Act Types. Defaults: Singer / Vocal · Band / Musical Act · Dance · Comedy · Magic / Illusion · Acrobatics / Circus · DJ / Electronic · Spoken Word · Other
Instagram · TikTok · YouTube · Twitter/X · Facebook · Spotify · Website