📅 Project Introduction: Event Registration System
This project is a comprehensive Event Registration System designed for organizing workshops, conferences, seminars, or any type of events. It enables users to view upcoming events, register online, and allows administrators to manage the entire event lifecycle.
The Problem it Solves:
Managing event registrations manually using spreadsheets or paper forms is inefficient, error-prone, and lacks real-time updates. This digital system automates the registration process, provides instant confirmation, manages attendee capacity, and gives organizers powerful tools to track and manage participants.
Key Features:
- Public User Features:
- Browse upcoming events with details (date, time, venue, price)
- View event details and available seats
- Register for events with a simple form
- Receive confirmation email (optional)
- View registration history
- Cancel registration (if allowed)
- Admin Features:
- Dashboard with statistics (total events, registrations, revenue)
- Event management (create, edit, delete events)
- Registration management (view, approve, cancel)
- Attendee list export (CSV/PDF)
- Check-in system (QR code scanning)
- Email notifications to attendees
- Venue/capacity management
- Payment tracking (if integrated)
Technology Stack:
- Frontend: HTML5, CSS3, JavaScript (Fetch API, Chart.js for analytics)
- Backend: PHP (Object-Oriented PHP with PDO)
- Database: MySQL
- Additional Libraries:
- QR Code generation (phpqrcode)
- PDF generation (FPDF)
- CSV export
- PHPMailer (for email notifications)
📁 Project File Structure
event-registration-system/ │ ├── index.php # Homepage - Event listings ├── events.php # All events page ├── event-details.php # Single event details ├── register.php # Event registration form ├── registration-success.php # Registration confirmation ├── my-registrations.php # User's registration history ├── cancel-registration.php # Cancel registration ├── login.php # User login ├── register-user.php # User registration ├── logout.php # Logout script │ ├── admin/ # Admin Panel │ ├── index.php # Admin login │ ├── dashboard.php # Admin dashboard │ ├── events.php # Manage events │ ├── add-event.php # Add new event │ ├── edit-event.php # Edit event │ ├── delete-event.php # Delete event │ ├── registrations.php # View all registrations │ ├── attendees.php # Manage attendees │ ├── check-in.php # QR code check-in system │ ├── reports.php # Generate reports │ ├── export.php # Export data (CSV/PDF) │ ├── settings.php # System settings │ └── logout.php # Admin logout │ ├── includes/ # Backend logic │ ├── config.php # Database connection │ ├── functions.php # Helper functions │ ├── auth.php # Authentication functions │ ├── session.php # Session management │ └── mailer.php # Email sending functions │ ├── api/ # AJAX endpoints │ ├── check-availability.php # Check seat availability │ ├── get-events.php # Get events for calendar │ ├── process-registration.php # Process registration │ └── check-in.php # Process check-in │ ├── assets/ # Static assets │ ├── css/ │ │ ├── style.css # Main styles │ │ └── admin.css # Admin styles │ ├── js/ │ │ ├── main.js # Main JavaScript │ │ ├── calendar.js # Calendar functionality │ │ └── validation.js # Form validation │ ├── images/ │ │ ├── events/ # Event images │ │ └── default-event.jpg # Default event image │ └── qrcodes/ # Generated QR codes │ ├── vendor/ # Third-party libraries │ ├── phpqrcode/ # QR Code generator │ ├── fpdf/ # PDF generator │ └── phpmailer/ # Email library │ └── database/ └── event_system.sql # Database dump
🗄️ Database Setup (database/event_system.sql)
Create a database named event_system and run this SQL.
-- phpMyAdmin SQL Dump
-- Database: `event_system`
CREATE DATABASE IF NOT EXISTS `event_system`;
USE `event_system`;
-- --------------------------------------------------------
-- Table structure for table `users`
-- --------------------------------------------------------
CREATE TABLE `users` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(50) NOT NULL,
`email` varchar(100) NOT NULL,
`password` varchar(255) NOT NULL,
`full_name` varchar(100) NOT NULL,
`phone` varchar(20) DEFAULT NULL,
`role` enum('user','admin') DEFAULT 'user',
`created_at` timestamp NOT NULL DEFAULT current_timestamp(),
PRIMARY KEY (`id`),
UNIQUE KEY `username` (`username`),
UNIQUE KEY `email` (`email`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- Default admin account (password: admin123)
INSERT INTO `users` (`username`, `email`, `password`, `full_name`, `role`) VALUES
('admin', '[email protected]', '$2y$10$YourHashedPasswordHere', 'Administrator', 'admin');
-- Sample user (password: user123)
INSERT INTO `users` (`username`, `email`, `password`, `full_name`, `phone`, `role`) VALUES
('john.doe', '[email protected]', '$2y$10$YourHashedPasswordHere', 'John Doe', '1234567890', 'user');
-- --------------------------------------------------------
-- Table structure for table `events`
-- --------------------------------------------------------
CREATE TABLE `events` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`title` varchar(200) NOT NULL,
`description` text NOT NULL,
`short_description` varchar(500) DEFAULT NULL,
`category` varchar(50) DEFAULT NULL,
`event_type` enum('physical','online') DEFAULT 'physical',
`venue` varchar(255) DEFAULT NULL,
`online_link` varchar(255) DEFAULT NULL,
`start_date` datetime NOT NULL,
`end_date` datetime NOT NULL,
`registration_deadline` datetime DEFAULT NULL,
`max_attendees` int(11) DEFAULT 0 COMMENT '0 = unlimited',
`current_attendees` int(11) DEFAULT 0,
`price` decimal(10,2) DEFAULT 0.00,
`image` varchar(255) DEFAULT 'default-event.jpg',
`status` enum('draft','published','cancelled','completed') DEFAULT 'draft',
`created_by` int(11) NOT NULL,
`created_at` timestamp NOT NULL DEFAULT current_timestamp(),
PRIMARY KEY (`id`),
KEY `created_by` (`created_by`),
KEY `start_date` (`start_date`),
CONSTRAINT `events_ibfk_1` FOREIGN KEY (`created_by`) REFERENCES `users` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- Sample events
INSERT INTO `events` (`title`, `description`, `short_description`, `category`, `venue`, `start_date`, `end_date`, `registration_deadline`, `max_attendees`, `price`, `status`, `created_by`) VALUES
('Tech Conference 2024', 'Annual technology conference featuring industry experts discussing AI, Web Development, and Cloud Computing.', 'Annual tech conference with industry experts', 'Technology', 'Convention Center, New York', '2024-06-15 09:00:00', '2024-06-17 18:00:00', '2024-06-10 23:59:59', 500, 299.99, 'published', 1),
('Web Development Workshop', 'Hands-on workshop on modern web development techniques using React, Node.js, and MongoDB.', 'Learn modern web development', 'Workshop', 'Tech Hub, San Francisco', '2024-05-20 10:00:00', '2024-05-20 17:00:00', '2024-05-18 23:59:59', 50, 99.99, 'published', 1),
('Virtual Networking Event', 'Connect with professionals from around the world in this virtual networking session.', 'Global networking opportunity', 'Networking', NULL, '2024-05-25 15:00:00', '2024-05-25 17:00:00', '2024-05-24 23:59:59', 200, 0.00, 'published', 1);
-- --------------------------------------------------------
-- Table structure for table `registrations`
-- --------------------------------------------------------
CREATE TABLE `registrations` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`registration_code` varchar(50) NOT NULL,
`event_id` int(11) NOT NULL,
`user_id` int(11) DEFAULT NULL,
`full_name` varchar(100) NOT NULL,
`email` varchar(100) NOT NULL,
`phone` varchar(20) DEFAULT NULL,
`organization` varchar(200) DEFAULT NULL,
`ticket_type` varchar(50) DEFAULT 'regular',
`quantity` int(11) DEFAULT 1,
`total_amount` decimal(10,2) NOT NULL,
`payment_status` enum('pending','paid','failed','refunded') DEFAULT 'pending',
`payment_method` varchar(50) DEFAULT NULL,
`transaction_id` varchar(100) DEFAULT NULL,
`checked_in` tinyint(1) DEFAULT 0,
`checked_in_at` timestamp NULL DEFAULT NULL,
`qr_code_path` varchar(255) DEFAULT NULL,
`status` enum('confirmed','cancelled','waiting') DEFAULT 'confirmed',
`registered_at` timestamp NOT NULL DEFAULT current_timestamp(),
PRIMARY KEY (`id`),
UNIQUE KEY `registration_code` (`registration_code`),
KEY `event_id` (`event_id`),
KEY `user_id` (`user_id`),
KEY `email` (`email`),
CONSTRAINT `registrations_ibfk_1` FOREIGN KEY (`event_id`) REFERENCES `events` (`id`) ON DELETE CASCADE,
CONSTRAINT `registrations_ibfk_2` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE SET NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- Sample registration
INSERT INTO `registrations` (`registration_code`, `event_id`, `user_id`, `full_name`, `email`, `phone`, `total_amount`, `payment_status`, `status`) VALUES
('REG-20240501-001', 1, 2, 'John Doe', '[email protected]', '1234567890', 299.99, 'paid', 'confirmed');
-- --------------------------------------------------------
-- Table structure for table `event_categories`
-- --------------------------------------------------------
CREATE TABLE `event_categories` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(50) NOT NULL,
`description` text DEFAULT NULL,
`color` varchar(20) DEFAULT '#3498db',
PRIMARY KEY (`id`),
UNIQUE KEY `name` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
INSERT INTO `event_categories` (`name`, `description`, `color`) VALUES
('Technology', 'Tech conferences, workshops, and meetups', '#3498db'),
('Business', 'Business seminars and networking events', '#2ecc71'),
('Education', 'Educational workshops and training', '#f1c40f'),
('Arts', 'Art exhibitions and cultural events', '#9b59b6');
-- --------------------------------------------------------
-- Table structure for table `notifications`
-- --------------------------------------------------------
CREATE TABLE `notifications` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) DEFAULT NULL,
`type` varchar(50) NOT NULL,
`title` varchar(200) NOT NULL,
`message` text NOT NULL,
`is_read` tinyint(1) DEFAULT 0,
`created_at` timestamp NOT NULL DEFAULT current_timestamp(),
PRIMARY KEY (`id`),
KEY `user_id` (`user_id`),
CONSTRAINT `notifications_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- --------------------------------------------------------
-- Table structure for table `event_feedback`
-- --------------------------------------------------------
CREATE TABLE `event_feedback` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`event_id` int(11) NOT NULL,
`user_id` int(11) DEFAULT NULL,
`rating` int(1) DEFAULT NULL,
`feedback` text DEFAULT NULL,
`created_at` timestamp NOT NULL DEFAULT current_timestamp(),
PRIMARY KEY (`id`),
KEY `event_id` (`event_id`),
KEY `user_id` (`user_id`),
CONSTRAINT `event_feedback_ibfk_1` FOREIGN KEY (`event_id`) REFERENCES `events` (`id`) ON DELETE CASCADE,
CONSTRAINT `event_feedback_ibfk_2` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE SET NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
COMMIT;
💻 Core PHP Files
1. Database Configuration (includes/config.php)
<?php
// Database configuration
define('DB_HOST', 'localhost');
define('DB_NAME', 'event_system');
define('DB_USER', 'root');
define('DB_PASS', '');
try {
$pdo = new PDO(
"mysql:host=" . DB_HOST . ";dbname=" . DB_NAME . ";charset=utf8mb4",
DB_USER,
DB_PASS,
[
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_EMULATE_PREPARES => false
]
);
} catch (PDOException $e) {
die("Connection failed: " . $e->getMessage());
}
// Start session if not started
if (session_status() == PHP_SESSION_NONE) {
session_start();
}
// Site configuration
define('SITE_NAME', 'Event Registration System');
define('SITE_URL', 'http://localhost/event-registration-system/');
define('UPLOAD_PATH', __DIR__ . '/../assets/images/events/');
define('QR_CODE_PATH', __DIR__ . '/../assets/qrcodes/');
// Helper functions
function sanitize($data) {
$data = trim($data);
$data = stripslashes($data);
$data = htmlspecialchars($data);
return $data;
}
function redirect($url) {
header("Location: $url");
exit;
}
function isLoggedIn() {
return isset($_SESSION['user_id']);
}
function isAdmin() {
return isset($_SESSION['user_role']) && $_SESSION['user_role'] === 'admin';
}
function formatDate($date, $format = 'F j, Y g:i A') {
return date($format, strtotime($date));
}
function formatCurrency($amount) {
return '$' . number_format($amount, 2);
}
function generateRegistrationCode() {
return 'REG-' . date('Ymd') . '-' . strtoupper(uniqid());
}
function getEventStatus($event) {
$now = new DateTime();
$start = new DateTime($event['start_date']);
$end = new DateTime($event['end_date']);
if ($event['status'] == 'cancelled') {
return ['text' => 'Cancelled', 'class' => 'danger'];
} elseif ($now < $start) {
return ['text' => 'Upcoming', 'class' => 'info'];
} elseif ($now >= $start && $now <= $end) {
return ['text' => 'Ongoing', 'class' => 'success'];
} else {
return ['text' => 'Completed', 'class' => 'secondary'];
}
}
function sendEmail($to, $subject, $message) {
// Basic mail function - replace with PHPMailer for production
$headers = "MIME-Version: 1.0" . "\r\n";
$headers .= "Content-type:text/html;charset=UTF-8" . "\r\n";
$headers .= "From: " . SITE_NAME . " <noreply@" . $_SERVER['HTTP_HOST'] . ">\r\n";
return mail($to, $subject, $message, $headers);
}
?>
2. Authentication Functions (includes/auth.php)
<?php
require_once 'config.php';
class Auth {
public static function login($email, $password) {
global $pdo;
$stmt = $pdo->prepare("SELECT * FROM users WHERE email = ?");
$stmt->execute([$email]);
$user = $stmt->fetch();
if ($user && password_verify($password, $user['password'])) {
$_SESSION['user_id'] = $user['id'];
$_SESSION['user_name'] = $user['full_name'];
$_SESSION['user_email'] = $user['email'];
$_SESSION['user_role'] = $user['role'];
return true;
}
return false;
}
public static function register($data) {
global $pdo;
// Check if email exists
$stmt = $pdo->prepare("SELECT id FROM users WHERE email = ?");
$stmt->execute([$data['email']]);
if ($stmt->fetch()) {
return ['success' => false, 'message' => 'Email already registered'];
}
// Check if username exists
$stmt = $pdo->prepare("SELECT id FROM users WHERE username = ?");
$stmt->execute([$data['username']]);
if ($stmt->fetch()) {
return ['success' => false, 'message' => 'Username already taken'];
}
// Hash password
$hashedPassword = password_hash($data['password'], PASSWORD_DEFAULT);
// Insert user
$stmt = $pdo->prepare("
INSERT INTO users (username, email, password, full_name, phone)
VALUES (?, ?, ?, ?, ?)
");
$success = $stmt->execute([
$data['username'],
$data['email'],
$hashedPassword,
$data['full_name'],
$data['phone'] ?? null
]);
if ($success) {
return ['success' => true, 'message' => 'Registration successful! Please login.'];
}
return ['success' => false, 'message' => 'Registration failed. Please try again.'];
}
public static function logout() {
session_destroy();
redirect('login.php');
}
public static function checkLogin() {
if (!isset($_SESSION['user_id'])) {
redirect('login.php');
}
}
public static function checkAdmin() {
self::checkLogin();
if ($_SESSION['user_role'] !== 'admin') {
redirect('../index.php');
}
}
public static function getCurrentUser() {
global $pdo;
if (!isset($_SESSION['user_id'])) {
return null;
}
$stmt = $pdo->prepare("SELECT * FROM users WHERE id = ?");
$stmt->execute([$_SESSION['user_id']]);
return $stmt->fetch();
}
}
?>
3. Homepage - Event Listings (index.php)
<?php
require_once 'includes/config.php';
// Get upcoming events
$stmt = $pdo->prepare("
SELECT e.*,
(SELECT COUNT(*) FROM registrations WHERE event_id = e.id AND status = 'confirmed') as registered
FROM events e
WHERE e.status = 'published'
AND e.start_date >= NOW()
ORDER BY e.start_date ASC
LIMIT 6
");
$stmt->execute();
$upcoming_events = $stmt->fetchAll();
// Get featured events
$featured = $pdo->prepare("
SELECT e.*,
(SELECT COUNT(*) FROM registrations WHERE event_id = e.id AND status = 'confirmed') as registered
FROM events e
WHERE e.status = 'published'
ORDER BY e.created_at DESC
LIMIT 3
");
$featured->execute();
$featured_events = $featured->fetchAll();
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title><?php echo SITE_NAME; ?></title>
<link rel="stylesheet" href="assets/css/style.css">
</head>
<body>
<!-- Navigation -->
<nav class="navbar">
<div class="container">
<a href="index.php" class="logo">EventReg</a>
<ul class="nav-links">
<li><a href="index.php">Home</a></li>
<li><a href="events.php">Events</a></li>
<?php if (isLoggedIn()): ?>
<li><a href="my-registrations.php">My Registrations</a></li>
<?php if (isAdmin()): ?>
<li><a href="admin/dashboard.php">Admin Panel</a></li>
<?php endif; ?>
<li><a href="logout.php">Logout</a></li>
<?php else: ?>
<li><a href="login.php">Login</a></li>
<li><a href="register-user.php" class="btn-primary">Register</a></li>
<?php endif; ?>
</ul>
</div>
</nav>
<!-- Hero Section -->
<section class="hero">
<div class="container">
<h1>Discover & Join Amazing Events</h1>
<p>Find and register for conferences, workshops, and networking events</p>
<a href="events.php" class="btn btn-large">Browse Events</a>
</div>
</section>
<!-- Featured Events -->
<section class="featured-events">
<div class="container">
<h2>Featured Events</h2>
<div class="event-grid">
<?php foreach ($featured_events as $event):
$status = getEventStatus($event);
$available = $event['max_attendees'] > 0 ? $event['max_attendees'] - $event['registered'] : 'Unlimited';
?>
<div class="event-card">
<div class="event-image">
<img src="assets/images/events/<?php echo $event['image']; ?>"
alt="<?php echo $event['title']; ?>">
<span class="event-category"><?php echo $event['category']; ?></span>
</div>
<div class="event-details">
<h3><?php echo $event['title']; ?></h3>
<p class="event-date">📅 <?php echo formatDate($event['start_date'], 'M d, Y'); ?></p>
<p class="event-time">⏰ <?php echo formatDate($event['start_date'], 'g:i A'); ?></p>
<p class="event-venue">📍 <?php echo $event['venue'] ?: 'Online'; ?></p>
<p class="event-price">💰 <?php echo $event['price'] > 0 ? formatCurrency($event['price']) : 'Free'; ?></p>
<p class="event-seats">👥 <?php echo $available; ?> seats available</p>
<a href="event-details.php?id=<?php echo $event['id']; ?>" class="btn btn-primary">View Details</a>
</div>
</div>
<?php endforeach; ?>
</div>
</div>
</section>
<!-- Upcoming Events -->
<section class="upcoming-events">
<div class="container">
<h2>Upcoming Events</h2>
<div class="events-list">
<?php foreach ($upcoming_events as $event): ?>
<div class="event-item">
<div class="event-date-badge">
<span class="month"><?php echo date('M', strtotime($event['start_date'])); ?></span>
<span class="day"><?php echo date('d', strtotime($event['start_date'])); ?></span>
</div>
<div class="event-info">
<h3><?php echo $event['title']; ?></h3>
<p><?php echo $event['short_description']; ?></p>
<div class="event-meta">
<span>📍 <?php echo $event['venue'] ?: 'Online'; ?></span>
<span>💰 <?php echo $event['price'] > 0 ? formatCurrency($event['price']) : 'Free'; ?></span>
</div>
</div>
<a href="event-details.php?id=<?php echo $event['id']; ?>" class="btn">Learn More</a>
</div>
<?php endforeach; ?>
</div>
<div class="text-center">
<a href="events.php" class="btn btn-large">View All Events</a>
</div>
</div>
</section>
<!-- Footer -->
<footer>
<div class="container">
<p>© 2024 <?php echo SITE_NAME; ?>. All rights reserved.</p>
</div>
</footer>
<script src="assets/js/main.js"></script>
</body>
</html>
4. Event Details Page (event-details.php)
<?php
require_once 'includes/config.php';
$event_id = isset($_GET['id']) ? (int)$_GET['id'] : 0;
if (!$event_id) {
redirect('events.php');
}
// Get event details
$stmt = $pdo->prepare("
SELECT e.*, u.full_name as organizer_name,
(SELECT COUNT(*) FROM registrations WHERE event_id = e.id AND status = 'confirmed') as registered
FROM events e
LEFT JOIN users u ON e.created_by = u.id
WHERE e.id = ?
");
$stmt->execute([$event_id]);
$event = $stmt->fetch();
if (!$event || $event['status'] == 'draft') {
redirect('events.php');
}
// Check if user is already registered
$is_registered = false;
$user_registration = null;
if (isLoggedIn()) {
$stmt = $pdo->prepare("
SELECT * FROM registrations
WHERE event_id = ? AND user_id = ? AND status = 'confirmed'
");
$stmt->execute([$event_id, $_SESSION['user_id']]);
$user_registration = $stmt->fetch();
$is_registered = !empty($user_registration);
}
// Calculate available seats
$available_seats = $event['max_attendees'] > 0 ?
max(0, $event['max_attendees'] - $event['registered']) :
PHP_INT_MAX;
$status = getEventStatus($event);
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title><?php echo $event['title']; ?> - <?php echo SITE_NAME; ?></title>
<link rel="stylesheet" href="assets/css/style.css">
</head>
<body>
<!-- Navigation -->
<nav class="navbar">
<div class="container">
<a href="index.php" class="logo">EventReg</a>
<ul class="nav-links">
<li><a href="index.php">Home</a></li>
<li><a href="events.php">Events</a></li>
<?php if (isLoggedIn()): ?>
<li><a href="my-registrations.php">My Registrations</a></li>
<?php if (isAdmin()): ?>
<li><a href="admin/dashboard.php">Admin Panel</a></li>
<?php endif; ?>
<li><a href="logout.php">Logout</a></li>
<?php else: ?>
<li><a href="login.php">Login</a></li>
<li><a href="register-user.php">Register</a></li>
<?php endif; ?>
</ul>
</div>
</nav>
<!-- Event Details -->
<div class="container">
<div class="event-detail">
<div class="event-header">
<h1><?php echo $event['title']; ?></h1>
<span class="event-status status-<?php echo $status['class']; ?>">
<?php echo $status['text']; ?>
</span>
</div>
<div class="event-image-large">
<img src="assets/images/events/<?php echo $event['image']; ?>"
alt="<?php echo $event['title']; ?>">
</div>
<div class="event-info-grid">
<div class="info-card">
<h3>📅 Date & Time</h3>
<p><strong>Start:</strong> <?php echo formatDate($event['start_date']); ?></p>
<p><strong>End:</strong> <?php echo formatDate($event['end_date']); ?></p>
<?php if ($event['registration_deadline']): ?>
<p><strong>Registration Deadline:</strong> <?php echo formatDate($event['registration_deadline']); ?></p>
<?php endif; ?>
</div>
<div class="info-card">
<h3>📍 Location</h3>
<?php if ($event['event_type'] == 'physical'): ?>
<p><?php echo $event['venue']; ?></p>
<?php else: ?>
<p>Online Event</p>
<?php if ($event['online_link']): ?>
<p><a href="<?php echo $event['online_link']; ?>" target="_blank">Join Link</a></p>
<?php endif; ?>
<?php endif; ?>
</div>
<div class="info-card">
<h3>💰 Pricing</h3>
<p class="event-price-large">
<?php echo $event['price'] > 0 ? formatCurrency($event['price']) : 'Free'; ?>
</p>
</div>
<div class="info-card">
<h3>👥 Capacity</h3>
<p>
<?php if ($event['max_attendees'] > 0): ?>
<?php echo $event['registered']; ?> / <?php echo $event['max_attendees']; ?> registered
<br>
<?php echo $available_seats; ?> seats available
<?php else: ?>
<?php echo $event['registered']; ?> registered (Unlimited capacity)
<?php endif; ?>
</p>
</div>
</div>
<div class="event-description">
<h3>About This Event</h3>
<p><?php echo nl2br($event['description']); ?></p>
</div>
<?php if ($is_registered): ?>
<div class="registration-status">
<h3>You're Registered! 🎉</h3>
<p>Registration Code: <strong><?php echo $user_registration['registration_code']; ?></strong></p>
<p>Please save this code for check-in.</p>
<?php if ($user_registration['qr_code_path']): ?>
<div class="qr-code">
<img src="<?php echo $user_registration['qr_code_path']; ?>" alt="QR Code">
</div>
<?php endif; ?>
<a href="cancel-registration.php?id=<?php echo $user_registration['id']; ?>"
class="btn btn-danger"
onclick="return confirm('Are you sure you want to cancel your registration?')">
Cancel Registration
</a>
</div>
<?php elseif ($status['text'] == 'Upcoming' && $available_seats > 0): ?>
<div class="registration-actions">
<a href="register.php?event_id=<?php echo $event['id']; ?>" class="btn btn-large btn-success">
Register for this Event
</a>
</div>
<?php elseif ($available_seats <= 0): ?>
<div class="alert alert-warning">
<h3>Sold Out!</h3>
<p>Sorry, this event has reached maximum capacity.</p>
</div>
<?php elseif ($status['text'] != 'Upcoming'): ?>
<div class="alert alert-info">
<p>Registration is <?php echo strtolower($status['text']); ?> for this event.</p>
</div>
<?php endif; ?>
</div>
</div>
<!-- Footer -->
<footer>
<div class="container">
<p>© 2024 <?php echo SITE_NAME; ?>. All rights reserved.</p>
</div>
</footer>
</body>
</html>
5. Registration Form (register.php)
<?php
require_once 'includes/config.php';
require_once 'includes/auth.php';
$event_id = isset($_GET['event_id']) ? (int)$_GET['event_id'] : 0;
if (!$event_id) {
redirect('events.php');
}
// Get event details
$stmt = $pdo->prepare("
SELECT * FROM events
WHERE id = ? AND status = 'published' AND start_date > NOW()
");
$stmt->execute([$event_id]);
$event = $stmt->fetch();
if (!$event) {
$_SESSION['error'] = 'Event not found or registration closed';
redirect('events.php');
}
// Check capacity
$registered = $pdo->prepare("
SELECT COUNT(*) FROM registrations
WHERE event_id = ? AND status = 'confirmed'
");
$registered->execute([$event_id]);
$current_attendees = $registered->fetchColumn();
if ($event['max_attendees'] > 0 && $current_attendees >= $event['max_attendees']) {
$_SESSION['error'] = 'Sorry, this event is full';
redirect('event-details.php?id=' . $event_id);
}
// If user is logged in, pre-fill form
$user = null;
if (isLoggedIn()) {
$user = Auth::getCurrentUser();
// Check if already registered
$check = $pdo->prepare("
SELECT id FROM registrations
WHERE event_id = ? AND user_id = ? AND status = 'confirmed'
");
$check->execute([$event_id, $user['id']]);
if ($check->fetch()) {
$_SESSION['info'] = 'You are already registered for this event';
redirect('event-details.php?id=' . $event_id);
}
}
$errors = [];
$form_data = [
'full_name' => $user['full_name'] ?? '',
'email' => $user['email'] ?? '',
'phone' => $user['phone'] ?? '',
'organization' => '',
'ticket_quantity' => 1
];
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
// Sanitize input
$form_data['full_name'] = sanitize($_POST['full_name']);
$form_data['email'] = sanitize($_POST['email']);
$form_data['phone'] = sanitize($_POST['phone']);
$form_data['organization'] = sanitize($_POST['organization']);
$form_data['ticket_quantity'] = (int)$_POST['ticket_quantity'];
// Validate
if (empty($form_data['full_name'])) {
$errors['full_name'] = 'Full name is required';
}
if (empty($form_data['email'])) {
$errors['email'] = 'Email is required';
} elseif (!filter_var($form_data['email'], FILTER_VALIDATE_EMAIL)) {
$errors['email'] = 'Invalid email format';
}
if (empty($form_data['phone'])) {
$errors['phone'] = 'Phone number is required';
}
if ($form_data['ticket_quantity'] < 1) {
$errors['ticket_quantity'] = 'Quantity must be at least 1';
}
// Check capacity for multiple tickets
if ($event['max_attendees'] > 0) {
$new_total = $current_attendees + $form_data['ticket_quantity'];
if ($new_total > $event['max_attendees']) {
$available = $event['max_attendees'] - $current_attendees;
$errors['ticket_quantity'] = "Only $available ticket(s) available";
}
}
if (empty($errors)) {
// Calculate total amount
$total_amount = $event['price'] * $form_data['ticket_quantity'];
$registration_code = generateRegistrationCode();
try {
$pdo->beginTransaction();
// Insert registration
$stmt = $pdo->prepare("
INSERT INTO registrations (
registration_code, event_id, user_id, full_name, email,
phone, organization, quantity, total_amount, payment_status, status
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
");
$stmt->execute([
$registration_code,
$event_id,
$user['id'] ?? null,
$form_data['full_name'],
$form_data['email'],
$form_data['phone'],
$form_data['organization'],
$form_data['ticket_quantity'],
$total_amount,
$event['price'] > 0 ? 'pending' : 'paid', // Auto-paid if free
'confirmed'
]);
$registration_id = $pdo->lastInsertId();
// Generate QR code (if using phpqrcode library)
if (file_exists('vendor/phpqrcode/qrlib.php')) {
require_once 'vendor/phpqrcode/qrlib.php';
$qr_file = QR_CODE_PATH . $registration_code . '.png';
QRcode::png(SITE_URL . 'check-in.php?code=' . $registration_code, $qr_file, QR_ECLEVEL_L, 10);
$pdo->prepare("UPDATE registrations SET qr_code_path = ? WHERE id = ?")
->execute(['assets/qrcodes/' . $registration_code . '.png', $registration_id]);
}
// Update event attendee count
$pdo->prepare("
UPDATE events SET current_attendees = current_attendees + ?
WHERE id = ?
")->execute([$form_data['ticket_quantity'], $event_id]);
$pdo->commit();
// Send confirmation email
$subject = "Registration Confirmed: " . $event['title'];
$message = "
<h1>Registration Confirmed!</h1>
<p>Dear {$form_data['full_name']},</p>
<p>Your registration for <strong>{$event['title']}</strong> has been confirmed.</p>
<p><strong>Registration Code:</strong> {$registration_code}</p>
<p><strong>Event Date:</strong> " . formatDate($event['start_date']) . "</p>
<p><strong>Venue:</strong> " . ($event['venue'] ?: 'Online') . "</p>
<p>Please save this email and bring your registration code to the event.</p>
<p>View your registration: <a href='" . SITE_URL . "registration-success.php?code={$registration_code}'>Click Here</a></p>
";
sendEmail($form_data['email'], $subject, $message);
// Redirect to success page
redirect('registration-success.php?code=' . $registration_code);
} catch (Exception $e) {
$pdo->rollBack();
$errors['general'] = 'Registration failed. Please try again.';
}
}
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Register for <?php echo $event['title']; ?></title>
<link rel="stylesheet" href="assets/css/style.css">
</head>
<body>
<!-- Navigation -->
<nav class="navbar">
<div class="container">
<a href="index.php" class="logo">EventReg</a>
<ul class="nav-links">
<li><a href="index.php">Home</a></li>
<li><a href="events.php">Events</a></li>
<?php if (isLoggedIn()): ?>
<li><a href="my-registrations.php">My Registrations</a></li>
<li><a href="logout.php">Logout</a></li>
<?php else: ?>
<li><a href="login.php">Login</a></li>
<?php endif; ?>
</ul>
</div>
</nav>
<div class="container">
<div class="registration-form-container">
<h1>Register for Event</h1>
<div class="event-summary">
<h2><?php echo $event['title']; ?></h2>
<p><strong>Date:</strong> <?php echo formatDate($event['start_date']); ?></p>
<p><strong>Price:</strong> <?php echo $event['price'] > 0 ? formatCurrency($event['price']) . ' per ticket' : 'Free'; ?></p>
<p><strong>Available Seats:</strong>
<?php
$available = $event['max_attendees'] > 0 ?
$event['max_attendees'] - $current_attendees :
'Unlimited';
echo $available;
?>
</p>
</div>
<?php if (!empty($errors['general'])): ?>
<div class="alert alert-error"><?php echo $errors['general']; ?></div>
<?php endif; ?>
<form method="POST" action="" class="registration-form">
<div class="form-group">
<label for="full_name">Full Name *</label>
<input type="text" id="full_name" name="full_name"
value="<?php echo htmlspecialchars($form_data['full_name']); ?>" required>
<?php if (isset($errors['full_name'])): ?>
<span class="error"><?php echo $errors['full_name']; ?></span>
<?php endif; ?>
</div>
<div class="form-group">
<label for="email">Email *</label>
<input type="email" id="email" name="email"
value="<?php echo htmlspecialchars($form_data['email']); ?>" required>
<?php if (isset($errors['email'])): ?>
<span class="error"><?php echo $errors['email']; ?></span>
<?php endif; ?>
</div>
<div class="form-group">
<label for="phone">Phone Number *</label>
<input type="tel" id="phone" name="phone"
value="<?php echo htmlspecialchars($form_data['phone']); ?>" required>
<?php if (isset($errors['phone'])): ?>
<span class="error"><?php echo $errors['phone']; ?></span>
<?php endif; ?>
</div>
<div class="form-group">
<label for="organization">Organization/Company</label>
<input type="text" id="organization" name="organization"
value="<?php echo htmlspecialchars($form_data['organization']); ?>">
</div>
<div class="form-group">
<label for="ticket_quantity">Number of Tickets *</label>
<input type="number" id="ticket_quantity" name="ticket_quantity"
value="<?php echo $form_data['ticket_quantity']; ?>"
min="1" max="10" required>
<?php if (isset($errors['ticket_quantity'])): ?>
<span class="error"><?php echo $errors['ticket_quantity']; ?></span>
<?php endif; ?>
</div>
<?php if ($event['price'] > 0): ?>
<div class="payment-summary">
<h3>Total: <?php echo formatCurrency($event['price'] * $form_data['ticket_quantity']); ?></h3>
<p class="note">* Payment will be collected at the venue or via invoice</p>
</div>
<?php endif; ?>
<div class="form-actions">
<button type="submit" class="btn btn-large btn-success">Complete Registration</button>
<a href="event-details.php?id=<?php echo $event_id; ?>" class="btn btn-large">Cancel</a>
</div>
</form>
</div>
</div>
<!-- Footer -->
<footer>
<div class="container">
<p>© 2024 <?php echo SITE_NAME; ?>. All rights reserved.</p>
</div>
</footer>
</body>
</html>
6. Registration Success Page (registration-success.php)
<?php
require_once 'includes/config.php';
$code = $_GET['code'] ?? '';
if (!$code) {
redirect('events.php');
}
// Get registration details
$stmt = $pdo->prepare("
SELECT r.*, e.title as event_title, e.start_date, e.venue, e.event_type
FROM registrations r
JOIN events e ON r.event_id = e.id
WHERE r.registration_code = ?
");
$stmt->execute([$code]);
$registration = $stmt->fetch();
if (!$registration) {
redirect('events.php');
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Registration Successful - <?php echo SITE_NAME; ?></title>
<link rel="stylesheet" href="assets/css/style.css">
</head>
<body>
<!-- Navigation -->
<nav class="navbar">
<div class="container">
<a href="index.php" class="logo">EventReg</a>
<ul class="nav-links">
<li><a href="index.php">Home</a></li>
<li><a href="events.php">Events</a></li>
<li><a href="my-registrations.php">My Registrations</a></li>
<li><a href="logout.php">Logout</a></li>
</ul>
</div>
</nav>
<div class="container">
<div class="success-container">
<div class="success-icon">✓</div>
<h1>Registration Successful!</h1>
<p>Thank you for registering for <strong><?php echo $registration['event_title']; ?></strong></p>
<div class="registration-details">
<h2>Registration Details</h2>
<p><strong>Registration Code:</strong> <?php echo $registration['registration_code']; ?></p>
<p><strong>Name:</strong> <?php echo $registration['full_name']; ?></p>
<p><strong>Email:</strong> <?php echo $registration['email']; ?></p>
<p><strong>Event Date:</strong> <?php echo formatDate($registration['start_date']); ?></p>
<p><strong>Venue:</strong> <?php echo $registration['venue'] ?: 'Online'; ?></p>
<p><strong>Tickets:</strong> <?php echo $registration['quantity']; ?></p>
<?php if ($registration['total_amount'] > 0): ?>
<p><strong>Total Paid:</strong> <?php echo formatCurrency($registration['total_amount']); ?></p>
<?php endif; ?>
</div>
<?php if ($registration['qr_code_path']): ?>
<div class="qr-code-section">
<h3>Your QR Code</h3>
<p>Please show this QR code at the event check-in</p>
<img src="<?php echo $registration['qr_code_path']; ?>" alt="QR Code" class="qr-code-image">
</div>
<?php endif; ?>
<div class="success-actions">
<a href="my-registrations.php" class="btn btn-primary">View My Registrations</a>
<a href="events.php" class="btn">Browse More Events</a>
</div>
<p class="email-note">A confirmation email has been sent to <?php echo $registration['email']; ?></p>
</div>
</div>
<!-- Footer -->
<footer>
<div class="container">
<p>© 2024 <?php echo SITE_NAME; ?>. All rights reserved.</p>
</div>
</footer>
</body>
</html>
7. Admin Dashboard (admin/dashboard.php)
<?php
require_once '../includes/config.php';
require_once '../includes/auth.php';
Auth::checkAdmin();
// Get statistics
$totalEvents = $pdo->query("SELECT COUNT(*) FROM events")->fetchColumn();
$publishedEvents = $pdo->query("SELECT COUNT(*) FROM events WHERE status = 'published'")->fetchColumn();
$totalRegistrations = $pdo->query("SELECT COUNT(*) FROM registrations")->fetchColumn();
$confirmedRegistrations = $pdo->query("SELECT COUNT(*) FROM registrations WHERE status = 'confirmed'")->fetchColumn();
$totalRevenue = $pdo->query("SELECT SUM(total_amount) FROM registrations WHERE payment_status = 'paid'")->fetchColumn();
$totalUsers = $pdo->query("SELECT COUNT(*) FROM users WHERE role = 'user'")->fetchColumn();
// Upcoming events
$upcomingEvents = $pdo->query("
SELECT e.*,
(SELECT COUNT(*) FROM registrations WHERE event_id = e.id AND status = 'confirmed') as registered
FROM events e
WHERE e.start_date > NOW() AND e.status = 'published'
ORDER BY e.start_date ASC
LIMIT 5
")->fetchAll();
// Recent registrations
$recentRegistrations = $pdo->query("
SELECT r.*, e.title as event_title
FROM registrations r
JOIN events e ON r.event_id = e.id
ORDER BY r.registered_at DESC
LIMIT 10
")->fetchAll();
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Admin Dashboard - <?php echo SITE_NAME; ?></title>
<link rel="stylesheet" href="../assets/css/admin.css">
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
</head>
<body>
<div class="admin-wrapper">
<!-- Sidebar -->
<aside class="sidebar">
<div class="sidebar-header">
<h2>Event Admin</h2>
<p>Welcome, <?php echo $_SESSION['user_name']; ?></p>
</div>
<nav class="sidebar-nav">
<ul>
<li><a href="dashboard.php" class="active">Dashboard</a></li>
<li><a href="events.php">Manage Events</a></li>
<li><a href="registrations.php">Registrations</a></li>
<li><a href="attendees.php">Attendees</a></li>
<li><a href="check-in.php">Check-In</a></li>
<li><a href="reports.php">Reports</a></li>
<li><a href="settings.php">Settings</a></li>
<li><a href="logout.php">Logout</a></li>
</ul>
</nav>
</aside>
<!-- Main Content -->
<main class="admin-main">
<div class="container">
<h1>Dashboard</h1>
<!-- Stats Cards -->
<div class="stats-grid">
<div class="stat-card">
<div class="stat-icon">📅</div>
<div class="stat-details">
<h3><?php echo $totalEvents; ?></h3>
<p>Total Events</p>
<small><?php echo $publishedEvents; ?> published</small>
</div>
</div>
<div class="stat-card">
<div class="stat-icon">👥</div>
<div class="stat-details">
<h3><?php echo $totalRegistrations; ?></h3>
<p>Total Registrations</p>
<small><?php echo $confirmedRegistrations; ?> confirmed</small>
</div>
</div>
<div class="stat-card">
<div class="stat-icon">💰</div>
<div class="stat-details">
<h3><?php echo formatCurrency($totalRevenue ?: 0); ?></h3>
<p>Total Revenue</p>
</div>
</div>
<div class="stat-card">
<div class="stat-icon">👤</div>
<div class="stat-details">
<h3><?php echo $totalUsers; ?></h3>
<p>Registered Users</p>
</div>
</div>
</div>
<!-- Upcoming Events -->
<div class="card">
<div class="card-header">
<h3>Upcoming Events</h3>
<a href="events.php" class="btn btn-sm">View All</a>
</div>
<div class="card-body">
<table class="data-table">
<thead>
<tr>
<th>Event</th>
<th>Date</th>
<th>Venue</th>
<th>Registered</th>
<th>Capacity</th>
<th>Status</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<?php foreach ($upcomingEvents as $event):
$status = getEventStatus($event);
?>
<tr>
<td><?php echo $event['title']; ?></td>
<td><?php echo formatDate($event['start_date'], 'M d, Y'); ?></td>
<td><?php echo $event['venue'] ?: 'Online'; ?></td>
<td><?php echo $event['registered']; ?></td>
<td><?php echo $event['max_attendees'] ?: '∞'; ?></td>
<td>
<span class="badge badge-<?php echo $status['class']; ?>">
<?php echo $status['text']; ?>
</span>
</td>
<td>
<a href="edit-event.php?id=<?php echo $event['id']; ?>" class="btn-small">Edit</a>
<a href="registrations.php?event=<?php echo $event['id']; ?>" class="btn-small">View</a>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
</div>
<!-- Recent Registrations -->
<div class="card">
<div class="card-header">
<h3>Recent Registrations</h3>
<a href="registrations.php" class="btn btn-sm">View All</a>
</div>
<div class="card-body">
<table class="data-table">
<thead>
<tr>
<th>Code</th>
<th>Name</th>
<th>Event</th>
<th>Email</th>
<th>Date</th>
<th>Status</th>
<th>Check-In</th>
</tr>
</thead>
<tbody>
<?php foreach ($recentRegistrations as $reg): ?>
<tr>
<td><?php echo $reg['registration_code']; ?></td>
<td><?php echo $reg['full_name']; ?></td>
<td><?php echo $reg['event_title']; ?></td>
<td><?php echo $reg['email']; ?></td>
<td><?php echo formatDate($reg['registered_at'], 'M d'); ?></td>
<td>
<span class="badge badge-<?php echo $reg['status']; ?>">
<?php echo $reg['status']; ?>
</span>
</td>
<td>
<?php if ($reg['checked_in']): ?>
<span class="badge badge-success">Checked In</span>
<?php else: ?>
<span class="badge badge-secondary">Pending</span>
<?php endif; ?>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
</div>
</div>
</main>
</div>
<script src="../assets/js/admin.js"></script>
</body>
</html>
8. Admin - Manage Events (admin/events.php)
<?php
require_once '../includes/config.php';
require_once '../includes/auth.php';
Auth::checkAdmin();
// Handle event deletion
if (isset($_GET['delete'])) {
$id = (int)$_GET['delete'];
// Check if event has registrations
$check = $pdo->prepare("SELECT COUNT(*) FROM registrations WHERE event_id = ?");
$check->execute([$id]);
$count = $check->fetchColumn();
if ($count > 0) {
$_SESSION['error'] = 'Cannot delete event with existing registrations';
} else {
$stmt = $pdo->prepare("DELETE FROM events WHERE id = ?");
$stmt->execute([$id]);
$_SESSION['success'] = 'Event deleted successfully';
}
redirect('events.php');
}
// Get all events
$events = $pdo->query("
SELECT e.*,
(SELECT COUNT(*) FROM registrations WHERE event_id = e.id) as total_registrations,
u.full_name as organizer
FROM events e
LEFT JOIN users u ON e.created_by = u.id
ORDER BY e.created_at DESC
")->fetchAll();
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Manage Events - <?php echo SITE_NAME; ?></title>
<link rel="stylesheet" href="../assets/css/admin.css">
</head>
<body>
<div class="admin-wrapper">
<!-- Sidebar -->
<aside class="sidebar">
<div class="sidebar-header">
<h2>Event Admin</h2>
<p>Welcome, <?php echo $_SESSION['user_name']; ?></p>
</div>
<nav class="sidebar-nav">
<ul>
<li><a href="dashboard.php">Dashboard</a></li>
<li><a href="events.php" class="active">Manage Events</a></li>
<li><a href="registrations.php">Registrations</a></li>
<li><a href="attendees.php">Attendees</a></li>
<li><a href="check-in.php">Check-In</a></li>
<li><a href="reports.php">Reports</a></li>
<li><a href="settings.php">Settings</a></li>
<li><a href="logout.php">Logout</a></li>
</ul>
</nav>
</aside>
<!-- Main Content -->
<main class="admin-main">
<div class="container">
<div class="page-header">
<h1>Manage Events</h1>
<a href="add-event.php" class="btn btn-primary">+ Add New Event</a>
</div>
<?php if (isset($_SESSION['success'])): ?>
<div class="alert alert-success"><?php echo $_SESSION['success']; unset($_SESSION['success']); ?></div>
<?php endif; ?>
<?php if (isset($_SESSION['error'])): ?>
<div class="alert alert-error"><?php echo $_SESSION['error']; unset($_SESSION['error']); ?></div>
<?php endif; ?>
<div class="card">
<div class="card-body">
<table class="data-table">
<thead>
<tr>
<th>ID</th>
<th>Image</th>
<th>Title</th>
<th>Category</th>
<th>Date</th>
<th>Venue</th>
<th>Price</th>
<th>Registrations</th>
<th>Status</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<?php foreach ($events as $event):
$status = getEventStatus($event);
?>
<tr>
<td>#<?php echo $event['id']; ?></td>
<td>
<img src="../assets/images/events/<?php echo $event['image']; ?>"
alt="<?php echo $event['title']; ?>"
style="width: 50px; height: 50px; object-fit: cover;">
</td>
<td><?php echo $event['title']; ?></td>
<td><?php echo $event['category']; ?></td>
<td><?php echo formatDate($event['start_date'], 'M d, Y'); ?></td>
<td><?php echo $event['venue'] ?: 'Online'; ?></td>
<td><?php echo $event['price'] > 0 ? formatCurrency($event['price']) : 'Free'; ?></td>
<td><?php echo $event['total_registrations']; ?></td>
<td>
<span class="badge badge-<?php echo $event['status']; ?>">
<?php echo $event['status']; ?>
</span>
<br>
<small><?php echo $status['text']; ?></small>
</td>
<td class="actions">
<a href="edit-event.php?id=<?php echo $event['id']; ?>" class="btn-small">Edit</a>
<a href="registrations.php?event=<?php echo $event['id']; ?>" class="btn-small">View</a>
<a href="?delete=<?php echo $event['id']; ?>"
class="btn-small btn-danger"
onclick="return confirm('Are you sure?')">Delete</a>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
</div>
</div>
</main>
</div>
</body>
</html>
9. Admin - Add Event (admin/add-event.php)
```php
<?php
require_once '../includes/config.php';
require_once '../includes/auth.php';
Auth::checkAdmin();
$categories = $pdo->query("SELECT * FROM event_categories ORDER BY name")->fetchAll();
$errors = [];
$form_data = [
'title' => '',
'short_description' => '',
'description' => '',
'category' => '',
'event_type' => 'physical',
'venue' => '',
'online_link' => '',
'start_date' => '',
'end_date' => '',
'registration_deadline' => '',
'max_attendees' => '',
'price' => '',
'status' => 'draft'
];
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
// Sanitize input
$form_data['title'] = sanitize($_POST['title']);
$form_data['short_description'] = sanitize($_POST['short_description']);
$form_data['description'] = $_POST['description']; // Allow HTML for description
$form_data['category'] = sanitize($_POST['category']);
$form_data['event_type'] = $_POST['event_type'];
$form_data['venue'] = sanitize($_POST['venue']);
$form_data['online_link'] = sanitize($_POST['online_link']);
$form_data['start_date'] = $_POST['start_date'];
$form_data['end_date'] = $_POST['end_date'];
$form_data['registration_deadline'] = $_POST['registration_deadline'] ?: null;
$form_data['max_attendees'] = $_POST['max_attendees'] ? (int)$_POST['max_attendees'] : 0;
$form_data['price'] = (float)$_POST['price'];
$form_data['status'] = $_POST['status'];
// Validate
if (empty($form_data['title'])) {
$errors['title'] = 'Title is required';
}
if (empty($form_data['description'])) {
$errors['description'] = 'Description is required';
}
if (empty($form_data['start_date'])) {
$errors['start_date'] = 'Start date is required';
}
if (empty($form_data['end_date'])) {
$errors['end_date'] = 'End date is required';
}
if ($form_data['event_type'] == 'physical' && empty($form_data['venue'])) {
$errors['venue'] = 'Venue is required for physical events';
}
if ($form_data['event_type'] == 'online' && empty($form_data['online_link'])) {
$errors['online_link'] = 'Online link is required for online events';
}
// Handle image upload
$image_name = 'default-event.jpg';
if (isset($_FILES['image']) && $_FILES['image']['error'] == 0) {
$allowed = ['image/jpeg', 'image/png', 'image/gif'];
if (in_array($_FILES['image']['type'], $allowed)) {
$extension = pathinfo($_FILES['image']['name'], PATHINFO_EXTENSION);
$image_name = uniqid() . '.'