Compare commits

..

1 Commits

Author SHA1 Message Date
Flatlogic Bot
7fb157b86c Auto commit: 2025-10-14T07:40:18.698Z 2025-10-14 07:40:18 +00:00
21 changed files with 1201 additions and 145 deletions

127
admin_competitions.php Normal file
View File

@ -0,0 +1,127 @@
<?php
require_once __DIR__ . '/db/config.php';
// Handle form submission
$message = '';
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$title = $_POST['title'] ?? '';
$description = $_POST['description'] ?? '';
$start_date = $_POST['start_date'] ?? '';
$end_date = $_POST['end_date'] ?? '';
if (!empty($title) && !empty($start_date) && !empty($end_date)) {
try {
$pdo = db();
$sql = "INSERT INTO competitions (title, description, start_date, end_date) VALUES (?, ?, ?, ?)";
$stmt = $pdo->prepare($sql);
$stmt->execute([$title, $description, $start_date, $end_date]);
$message = '<div class="alert alert-success">Competition created successfully!</div>';
} catch (PDOException $e) {
$message = '<div class="alert alert-danger">Error: ' . $e->getMessage() . '</div>';
}
} else {
$message = '<div class="alert alert-danger">Please fill in all required fields.</div>';
}
}
// Fetch all competitions
$competitions = [];
try {
$pdo = db();
$stmt = $pdo->query("SELECT id, title, description, start_date, end_date FROM competitions ORDER BY created_at DESC");
$competitions = $stmt->fetchAll();
} catch (PDOException $e) {
// Handle error if needed
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Admin: Manage Competitions</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="assets/css/custom.css">
</head>
<body>
<?php include 'includes/header.php'; ?>
<main class="container mt-5">
<div class="row">
<div class="col-md-12">
<h2>Manage Competitions</h2>
<hr>
</div>
</div>
<div class="row">
<!-- Create Competition Form -->
<div class="col-md-4">
<h3>Create New Competition</h3>
<?php echo $message; ?>
<form action="admin_competitions.php" method="POST">
<div class="mb-3">
<label for="title" class="form-label">Title</label>
<input type="text" class="form-control" id="title" name="title" required>
</div>
<div class="mb-3">
<label for="description" class="form-label">Description</label>
<textarea class="form-control" id="description" name="description" rows="3"></textarea>
</div>
<div class="mb-3">
<label for="start_date" class="form-label">Start Date</label>
<input type="datetime-local" class="form-control" id="start_date" name="start_date" required>
</div>
<div class="mb-3">
<label for="end_date" class="form-label">End Date</label>
<input type="datetime-local" class="form-control" id="end_date" name="end_date" required>
</div>
<button type="submit" class="btn btn-primary">Create Competition</button>
</form>
</div>
<!-- Competitions List -->
<div class="col-md-8">
<h3>Existing Competitions</h3>
<table class="table table-striped">
<thead>
<tr>
<th>ID</th>
<th>Title</th>
<th>Start Date</th>
<th>End Date</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<?php if (empty($competitions)): ?>
<tr>
<td colspan="5" class="text-center">No competitions found.</td>
</tr>
<?php else: ?>
<?php foreach ($competitions as $comp): ?>
<tr>
<td><?php echo htmlspecialchars($comp['id']); ?></td>
<td><?php echo htmlspecialchars($comp['title']); ?></td>
<td><?php echo htmlspecialchars($comp['start_date']); ?></td>
<td><?php echo htmlspecialchars($comp['end_date']); ?></td>
<td>
<a href="#" class="btn btn-sm btn-warning">Edit</a>
<a href="#" class="btn btn-sm btn-danger">Delete</a>
</td>
</tr>
<?php endforeach; ?>
<?php endif; ?>
</tbody>
</table>
</div>
</div>
</main>
<?php include 'includes/footer.php'; ?>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>

145
admin_submissions.php Normal file
View File

@ -0,0 +1,145 @@
<?php
session_start();
require_once 'includes/header.php';
require_once 'db/config.php';
// Check if user is logged in and is an admin (for simplicity, we'll just check if they are logged in)
if (!isset($_SESSION['user_id'])) {
header("Location: login.php");
exit;
}
$pdo = db();
// Handle status update
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['submission_id']) && isset($_POST['status'])) {
$submission_id = $_POST['submission_id'];
$status = $_POST['status'];
// Begin transaction
$pdo->beginTransaction();
try {
// Update submission status
$stmt = $pdo->prepare("UPDATE submissions SET status = ? WHERE id = ?");
$stmt->execute([$status, $submission_id]);
if ($status == 'approved') {
// Check if a certificate already exists
$stmt_check = $pdo->prepare("SELECT id FROM certificates WHERE submission_id = ?");
$stmt_check->execute([$submission_id]);
if ($stmt_check->rowCount() == 0) {
// Generate a unique certificate code
$certificate_code = uniqid('CERT-');
$stmt_insert = $pdo->prepare("INSERT INTO certificates (submission_id, certificate_code) VALUES (?, ?)");
$stmt_insert->execute([$submission_id, $certificate_code]);
}
} else {
// If status is not 'approved', delete any existing certificate
$stmt_delete = $pdo->prepare("DELETE FROM certificates WHERE submission_id = ?");
$stmt_delete->execute([$submission_id]);
}
// Commit transaction
$pdo->commit();
echo "<div class='alert alert-success'>Submission status updated successfully.</div>";
} catch (Exception $e) {
// Rollback transaction on error
$pdo->rollBack();
echo "<div class='alert alert-danger'>Failed to update submission status: " . $e->getMessage() . "</div>";
}
}
// Fetch all competitions
$stmt_competitions = $pdo->query("SELECT id, title FROM competitions ORDER BY start_date DESC");
$competitions = $stmt_competitions->fetchAll();
// Fetch all submissions with user and competition info
$stmt_submissions = $pdo->query("
SELECT
s.id,
s.file_path,
s.uploaded_at,
s.status,
u.name as user_name,
c.title as competition_title,
c.id as competition_id
FROM
submissions s
JOIN
users u ON s.user_id = u.id
JOIN
competitions c ON s.competition_id = c.id
ORDER BY
c.id, s.uploaded_at DESC
");
$submissions_by_competition = [];
while ($row = $stmt_submissions->fetch()) {
$submissions_by_competition[$row['competition_id']][] = $row;
}
?>
<div class="container mt-5">
<h1 class="mb-4">Competition Submissions</h1>
<?php if (empty($competitions)): ?>
<div class="alert alert-info">No competitions found.</div>
<?php else: ?>
<div class="accordion" id="competitionsAccordion">
<?php foreach ($competitions as $competition): ?>
<div class="accordion-item">
<h2 class="accordion-header" id="heading-<?php echo $competition['id']; ?>">
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#collapse-<?php echo $competition['id']; ?>" aria-expanded="false" aria-controls="collapse-<?php echo $competition['id']; ?>">
<?php echo htmlspecialchars($competition['title']); ?>
</button>
</h2>
<div id="collapse-<?php echo $competition['id']; ?>" class="accordion-collapse collapse" aria-labelledby="heading-<?php echo $competition['id']; ?>" data-bs-parent="#competitionsAccordion">
<div class="accordion-body">
<?php if (isset($submissions_by_competition[$competition['id']]) && !empty($submissions_by_competition[$competition['id']])) : ?>
<table class="table table-striped">
<thead>
<tr>
<th>User</th>
<th>File</th>
<th>Uploaded At</th>
<th>Status</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<?php foreach ($submissions_by_competition[$competition['id']] as $submission): ?>
<tr>
<td><?php echo htmlspecialchars($submission['user_name']); ?></td>
<td><a href="<?php echo htmlspecialchars($submission['file_path']); ?>" target="_blank">View Submission</a></td>
<td><?php echo date("F j, Y, g:i a", strtotime($submission['uploaded_at'])); ?></td>
<td><?php echo htmlspecialchars($submission['status']); ?></td>
<td>
<form action="admin_submissions.php" method="post">
<input type="hidden" name="submission_id" value="<?php echo $submission['id']; ?>">
<select name="status" class="form-select form-select-sm">
<option value="pending" <?php echo ($submission['status'] == 'pending') ? 'selected' : ''; ?>>Pending</option>
<option value="approved" <?php echo ($submission['status'] == 'approved') ? 'selected' : ''; ?>>Approved</option>
<option value="rejected" <?php echo ($submission['status'] == 'rejected') ? 'selected' : ''; ?>>Rejected</option>
</select>
<button type="submit" class="btn btn-primary btn-sm mt-1">Update</button>
</form>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<?php else: ?>
<p>No submissions for this competition yet.</p>
<?php endif; ?>
</div>
</div>
</div>
<?php endforeach; ?>
</div>
<?php endif; ?>
</div>
<?php require_once 'includes/footer.php'; ?>

57
admin_users.php Normal file
View File

@ -0,0 +1,57 @@
<?php
session_start();
require_once 'db/config.php';
require_once 'includes/header.php';
// Protect the page: redirect if user is not logged in
if (!isset($_SESSION['user_id'])) {
header('Location: login.php');
exit();
}
// Fetch all users from the database
$pdo = db();
$stmt = $pdo->query("SELECT id, name, email, created_at FROM users ORDER BY created_at DESC");
$users = $stmt->fetchAll(PDO::FETCH_ASSOC);
?>
<main class="container mt-5 pt-5">
<div class="card">
<div class="card-header">
<h1 class="h2">Registered Users</h1>
</div>
<div class="card-body">
<p>This table displays all users who have registered on the platform.</p>
<div class="table-responsive">
<table class="table table-striped table-hover">
<thead class="thead-dark">
<tr>
<th scope="col">ID</th>
<th scope="col">Name</th>
<th scope="col">Email</th>
<th scope="col">Registration Date</th>
</tr>
</thead>
<tbody>
<?php if (empty($users)): ?>
<tr>
<td colspan="4" class="text-center">No users found.</td>
</tr>
<?php else: ?>
<?php foreach ($users as $user): ?>
<tr>
<td><?php echo htmlspecialchars($user['id']); ?></td>
<td><?php echo htmlspecialchars($user['name']); ?></td>
<td><?php echo htmlspecialchars($user['email']); ?></td>
<td><?php echo htmlspecialchars(date('F j, Y, g:i a', strtotime($user['created_at']))); ?></td>
</tr>
<?php endforeach; ?>
<?php endif; ?>
</tbody>
</table>
</div>
</div>
</div>
</main>
<?php require_once 'includes/footer.php'; ?>

52
assets/css/custom.css Normal file
View File

@ -0,0 +1,52 @@
body {
padding-top: 56px; /* Adjust for fixed navbar */
font-family: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
}
#hero {
height: 80vh;
background: linear-gradient(45deg, rgba(13, 110, 253, 0.1), rgba(13, 202, 240, 0.1));
color: #333;
}
#hero h1 {
color: #000;
}
.btn-primary {
background-image: linear-gradient(45deg, #0D6EFD, #0DCAF0);
border: none;
transition: transform 0.2s;
}
.btn-primary:hover {
transform: translateY(-2px);
box-shadow: 0 4px 8px rgba(0,0,0,0.1);
}
section {
scroll-margin-top: 56px; /* Offset for navbar */
}
.card {
border: none;
box-shadow: 0 4px 12px rgba(0,0,0,0.08);
transition: transform 0.2s;
}
.card:hover {
transform: translateY(-5px);
}
#contactForm .form-control {
border-radius: 1rem;
}
#contactForm .form-control:focus {
box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25);
border-color: #0D6EFD;
}
#form-feedback .alert {
border-radius: 1rem;
}

46
assets/js/main.js Normal file
View File

@ -0,0 +1,46 @@
document.addEventListener('DOMContentLoaded', function () {
// Smooth scrolling for anchor links
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
anchor.addEventListener('click', function (e) {
e.preventDefault();
document.querySelector(this.getAttribute('href')).scrollIntoView({
behavior: 'smooth'
});
});
});
// Contact form submission
const contactForm = document.getElementById('contactForm');
if (contactForm) {
contactForm.addEventListener('submit', function (e) {
e.preventDefault();
const name = document.getElementById('name').value;
const email = document.getElementById('email').value;
const message = document.getElementById('message').value;
const feedbackContainer = document.getElementById('form-feedback');
const formContainer = document.getElementById('contact-form-container');
const formData = new FormData();
formData.append('name', name);
formData.append('email', email);
formData.append('message', message);
fetch('contact.php', {
method: 'POST',
body: formData
})
.then(response => response.json())
.then(data => {
let alertClass = data.success ? 'alert-success' : 'alert-danger';
feedbackContainer.innerHTML = `<div class="alert ${alertClass}">${data.message}</div>`;
if (data.success) {
formContainer.style.display = 'none';
}
})
.catch(error => {
feedbackContainer.innerHTML = `<div class="alert alert-danger">An unexpected error occurred. Please try again.</div>`;
console.error('Error:', error);
});
});
}
});

87
competition_details.php Normal file
View File

@ -0,0 +1,87 @@
<?php
session_start();
require_once 'includes/header.php';
require_once 'db/config.php';
$competition_id = $_GET['id'] ?? null;
if (!$competition_id) {
echo "<div class='alert alert-danger'>Competition ID is missing.</div>";
require_once 'includes/footer.php';
exit;
}
$pdo = db();
$stmt = $pdo->prepare("SELECT * FROM competitions WHERE id = ?");
$stmt->execute([$competition_id]);
$competition = $stmt->fetch();
if (!$competition) {
echo "<div class='alert alert-danger'>Competition not found.</div>";
require_once 'includes/footer.php';
exit;
}
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['submission_file'])) {
if (!isset($_SESSION['user_id'])) {
echo "<div class='alert alert-danger'>You must be logged in to make a submission.</div>";
} else {
$user_id = $_SESSION['user_id'];
$file = $_FILES['submission_file'];
// File validation
if ($file['error'] === UPLOAD_ERR_OK) {
$upload_dir = 'uploads/';
$file_name = uniqid() . '-' . basename($file['name']);
$target_path = $upload_dir . $file_name;
if (move_uploaded_file($file['tmp_name'], $target_path)) {
$stmt = $pdo->prepare("INSERT INTO submissions (competition_id, user_id, file_path) VALUES (?, ?, ?)");
if ($stmt->execute([$competition_id, $user_id, $target_path])) {
echo "<div class='alert alert-success'>Submission uploaded successfully.</div>";
} else {
echo "<div class='alert alert-danger'>Failed to save submission to the database.</div>";
}
} else {
echo "<div class='alert alert-danger'>Failed to move uploaded file.</div>";
}
} else {
echo "<div class='alert alert-danger'>Error uploading file.</div>";
}
}
}
?>
<div class="container">
<h1 class="mt-5"><?php echo htmlspecialchars($competition['title']); ?></h1>
<p class="lead">
<strong>Start Date:</strong> <?php echo date("F j, Y, g:i a", strtotime($competition['start_date'])); ?><br>
<strong>End Date:</strong> <?php echo date("F j, Y, g:i a", strtotime($competition['end_date'])); ?>
</p>
<p><?php echo nl2br(htmlspecialchars($competition['description'])); ?></p>
<hr>
<?php if (isset($_SESSION['user_id'])): ?>
<div class="card">
<div class="card-header">
<h3>Submit Your Entry</h3>
</div>
<div class="card-body">
<form action="competition_details.php?id=<?php echo $competition_id; ?>" method="post" enctype="multipart/form-data">
<div class="form-group">
<label for="submission_file">Select file to upload:</label>
<input type="file" class="form-control-file" id="submission_file" name="submission_file" required>
</div>
<button type="submit" class="btn btn-primary mt-3">Upload Submission</button>
</form>
</div>
</div>
<?php else: ?>
<div class="alert alert-info">
Please <a href="login.php?return_url=<?php echo urlencode($_SERVER['REQUEST_URI']); ?>">login</a> to submit your entry for this competition.
</div>
<?php endif; ?>
</div>
<?php require_once 'includes/footer.php'; ?>

67
competitions.php Normal file
View File

@ -0,0 +1,67 @@
<?php
require_once __DIR__ . '/db/config.php';
// Fetch all competitions
$competitions = [];
try {
$pdo = db();
$stmt = $pdo->query("SELECT id, title, description, start_date, end_date FROM competitions WHERE end_date > NOW() ORDER BY start_date ASC");
$competitions = $stmt->fetchAll();
} catch (PDOException $e) {
// In a real app, you'd log this error.
$error_message = "Sorry, we couldn't load competitions at this time.";
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Competitions - READY BUDDY</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="assets/css/custom.css">
</head>
<body>
<?php include 'includes/header.php'; ?>
<main class="container mt-5">
<div class="row">
<div class="col-md-12">
<h2 class="fw-bold">Available Competitions</h2>
<p>Join a competition and show your skills!</p>
<hr>
</div>
</div>
<div class="row">
<?php if (isset($error_message)): ?>
<div class="alert alert-danger"><?php echo $error_message; ?></div>
<?php elseif (empty($competitions)): ?>
<div class="col-12">
<div class="alert alert-info">No upcoming competitions right now. Please check back later!</div>
</div>
<?php else: ?>
<?php foreach ($competitions as $comp): ?>
<div class="col-md-4 mb-4">
<div class="card h-100">
<div class="card-body d-flex flex-column">
<h5 class="card-title fw-bold"><?php echo htmlspecialchars($comp['title']); ?></h5>
<p class="card-text flex-grow-1"><?php echo nl2br(htmlspecialchars($comp['description'])); ?></p>
<p class="card-text"><small class="text-muted">Starts: <?php echo date('F j, Y, g:i a', strtotime($comp['start_date'])); ?></small></p>
<p class="card-text"><small class="text-muted">Ends: <?php echo date('F j, Y, g:i a', strtotime($comp['end_date'])); ?></small></p>
<a href="competition_details.php?id=<?php echo $comp['id']; ?>" class="btn btn-primary mt-auto">View Details</a>
</div>
</div>
</div>
<?php endforeach; ?>
<?php endif; ?>
</div>
</main>
<?php include 'includes/footer.php'; ?>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>

38
contact.php Normal file
View File

@ -0,0 +1,38 @@
<?php
header('Content-Type: application/json');
require_once __DIR__ . '/mail/MailService.php';
$response = [
'success' => false,
'message' => 'An error occurred.'
];
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$name = trim($_POST['name'] ?? '');
$email = trim($_POST['email'] ?? '');
$message = trim($_POST['message'] ?? '');
if (empty($name) || empty($email) || empty($message)) {
$response['message'] = 'Please fill out all fields.';
} elseif (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
$response['message'] = 'Please provide a valid email address.';
} else {
$to = getenv('MAIL_TO') ?: null; // Use environment variable or default in MailService
$subject = 'New Contact Form Submission from READY BUDDY';
$mailResult = MailService::sendContactMessage($name, $email, $message, $to, $subject);
if (!empty($mailResult['success'])) {
$response['success'] = true;
$response['message'] = 'Thank you for your message! We will get back to you shortly.';
} else {
// In a real app, you would log the detailed error: error_log($mailResult['error']);
$response['message'] = 'Sorry, there was an issue sending your message. Please try again later.';
}
}
} else {
$response['message'] = 'Invalid request method.';
}
echo json_encode($response);

View File

@ -0,0 +1,19 @@
<?php
require_once __DIR__ . '/../config.php';
try {
$pdo = db();
$sql = "
CREATE TABLE IF NOT EXISTS competitions (
id INT AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(255) NOT NULL,
description TEXT,
start_date DATETIME,
end_date DATETIME,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);";
$pdo->exec($sql);
echo "Table 'competitions' created successfully (if it didn't exist)." . PHP_EOL;
} catch (PDOException $e) {
die("DB ERROR: " . $e->getMessage());
}

View File

@ -0,0 +1,23 @@
<?php
require_once __DIR__ . '/../../db/config.php';
try {
$pdo = db();
// Check if the table already exists
$stmt = $pdo->query("SHOW TABLES LIKE 'users'");
if ($stmt->rowCount() == 0) {
$sql = "CREATE TABLE users (
id INT(11) UNSIGNED AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255) NOT NULL,
email VARCHAR(255) NOT NULL UNIQUE,
password VARCHAR(255) NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)";
$pdo->exec($sql);
echo "Table 'users' created successfully." . PHP_EOL;
} else {
echo "Table 'users' already exists." . PHP_EOL;
}
} catch (PDOException $e) {
die("Could not connect to the database or create table: " . $e->getMessage());
}

View File

@ -0,0 +1,21 @@
<?php
require_once __DIR__ . '/../../db/config.php';
try {
$pdo = db();
$sql = "
CREATE TABLE IF NOT EXISTS submissions (
id INT AUTO_INCREMENT PRIMARY KEY,
competition_id INT NOT NULL,
user_id INT(11) UNSIGNED NOT NULL,
file_path VARCHAR(255) NOT NULL,
uploaded_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (competition_id) REFERENCES competitions(id) ON DELETE CASCADE,
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
);
";
$pdo->exec($sql);
echo "Migration 003_create_submissions_table executed successfully." . PHP_EOL;
} catch (PDOException $e) {
die("Could not connect to the database: " . $e->getMessage());
}

View File

@ -0,0 +1,11 @@
<?php
require_once __DIR__ . '/../../db/config.php';
try {
$pdo = db();
$sql = "ALTER TABLE submissions ADD COLUMN status VARCHAR(50) DEFAULT 'pending' NOT NULL";
$pdo->exec($sql);
echo "Migration 004_add_status_to_submissions executed successfully." . PHP_EOL;
} catch (PDOException $e) {
die("Could not connect to the database: " . $e->getMessage());
}

View File

@ -0,0 +1,19 @@
<?php
require_once __DIR__ . '/../../db/config.php';
try {
$pdo = db();
$sql = "
CREATE TABLE IF NOT EXISTS certificates (
id INT AUTO_INCREMENT PRIMARY KEY,
submission_id INT NOT NULL,
certificate_code VARCHAR(255) NOT NULL UNIQUE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (submission_id) REFERENCES submissions(id) ON DELETE CASCADE
);
";
$pdo->exec($sql);
echo "Migration 005_create_certificates_table executed successfully." . PHP_EOL;
} catch (PDOException $e) {
die("Could not connect to the database: " . $e->getMessage());
}

91
generate_certificate.php Normal file
View File

@ -0,0 +1,91 @@
<?php
session_start();
require_once 'db/config.php';
if (!isset($_GET['code'])) {
die("Certificate code is missing.");
}
$certificate_code = $_GET['code'];
$pdo = db();
$stmt = $pdo->prepare("
SELECT
c.certificate_code,
u.name as user_name,
comp.title as competition_title,
s.uploaded_at
FROM certificates c
JOIN submissions s ON c.submission_id = s.id
JOIN users u ON s.user_id = u.id
JOIN competitions comp ON s.competition_id = comp.id
WHERE c.certificate_code = ?
");
$stmt->execute([$certificate_code]);
$certificate = $stmt->fetch();
if (!$certificate) {
die("Invalid certificate code.");
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Certificate of Achievement</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
<style>
body {
background-color: #f0f2f5;
}
.certificate-container {
max-width: 800px;
margin: 50px auto;
border: 10px solid #ddd;
padding: 50px;
background: #fff;
text-align: center;
font-family: 'Times New Roman', Times, serif;
}
.certificate-title {
font-size: 50px;
font-weight: bold;
color: #333;
}
.certificate-subtitle {
font-size: 25px;
color: #555;
}
.user-name {
font-size: 40px;
font-style: italic;
color: #007bff;
margin: 40px 0;
}
.competition-title {
font-size: 30px;
color: #333;
}
.date {
font-size: 20px;
color: #777;
margin-top: 40px;
}
</style>
</head>
<body>
<div class="certificate-container">
<div class="certificate-title">Certificate of Achievement</div>
<div class="certificate-subtitle">This is to certify that</div>
<div class="user-name"><?php echo htmlspecialchars($certificate['user_name']); ?></div>
<div class="certificate-subtitle">has successfully participated in the</div>
<div class="competition-title"><?php echo htmlspecialchars($certificate['competition_title']); ?></div>
<div class="date">Date: <?php echo date("F j, Y", strtotime($certificate['uploaded_at'])); ?></div>
<div class="mt-5">
<small>Certificate Code: <?php echo htmlspecialchars($certificate['certificate_code']); ?></small>
</div>
</div>
</body>
</html>

6
includes/footer.php Normal file
View File

@ -0,0 +1,6 @@
<footer class="footer bg-dark text-white text-center py-3 mt-auto">
<div class="container">
<p>&copy; <?php echo date("Y"); ?> READY BUDDY. All Rights Reserved.</p>
<p><a href="admin_competitions.php" class="text-white-50">Admin Panel</a></p>
</div>
</footer>

53
includes/header.php Normal file
View File

@ -0,0 +1,53 @@
<?php
if (session_status() == PHP_SESSION_NONE) {
session_start();
}
?>
<header class="header fixed-top">
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<div class="container">
<a class="navbar-brand" href="index.php">READY BUDDY</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarNav">
<ul class="navbar-nav ms-auto">
<li class="nav-item">
<a class="nav-link" href="index.php#home">Home</a>
</li>
<li class="nav-item">
<a class="nav-link" href="index.php#about">About</a>
</li>
<li class="nav-item">
<a class="nav-link" href="competitions.php">Competitions</a>
</li>
<li class="nav-item">
<a class="nav-link" href="index.php#contact">Contact</a>
</li>
<?php if (isset($_SESSION['user_id'])): ?>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-bs-toggle="dropdown" aria-expanded="false">
Profile
</a>
<ul class="dropdown-menu" aria-labelledby="navbarDropdown">
<li><a class="dropdown-item" href="admin_competitions.php">Competitions</a></li>
<li><a class="dropdown-item" href="admin_users.php">Users</a></li>
<li><a class="dropdown-item" href="admin_submissions.php">Submissions</a></li>
<li><a class="dropdown-item" href="my_certificates.php">My Certificates</a></li>
<li><hr class="dropdown-divider"></li>
<li><a class="dropdown-item" href="logout.php">Logout</a></li>
</ul>
</li>
<?php else: ?>
<li class="nav-item">
<a class="nav-link" href="login.php">Login</a>
</li>
<li class="nav-item">
<a class="btn btn-primary" href="register.php">Register</a>
</li>
<?php endif; ?>
</ul>
</div>
</div>
</nav>
</header>

244
index.php
View File

@ -1,150 +1,106 @@
<?php <!DOCTYPE html>
declare(strict_types=1);
@ini_set('display_errors', '1');
@error_reporting(E_ALL);
@date_default_timezone_set('UTC');
$phpVersion = PHP_VERSION;
$now = date('Y-m-d H:i:s');
?>
<!doctype html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="utf-8" /> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1" /> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>New Style</title> <title>READY BUDDY</title>
<?php <meta name="description" content="Join competitions, showcase your skills, and win prizes with READY BUDDY.">
// Read project preview data from environment <meta name="keywords" content="competitions, contests, prizes, challenges, skills, community, Built with Flatlogic Generator">
$projectDescription = $_SERVER['PROJECT_DESCRIPTION'] ?? ''; <meta property="og:title" content="READY BUDDY">
$projectImageUrl = $_SERVER['PROJECT_IMAGE_URL'] ?? ''; <meta property="og:description" content="The ultimate platform for online competitions and challenges.">
?> <meta property="og:image" content="">
<?php if ($projectDescription): ?> <meta name="twitter:card" content="summary_large_image">
<!-- Meta description --> <meta name="twitter:image" content="">
<meta name="description" content='<?= htmlspecialchars($projectDescription) ?>' />
<!-- Open Graph meta tags --> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
<meta property="og:description" content="<?= htmlspecialchars($projectDescription) ?>" /> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css">
<!-- Twitter meta tags --> <link rel="stylesheet" href="assets/css/custom.css?v=<?php echo time(); ?>">
<meta property="twitter:description" content="<?= htmlspecialchars($projectDescription) ?>" />
<?php endif; ?>
<?php if ($projectImageUrl): ?>
<!-- Open Graph image -->
<meta property="og:image" content="<?= htmlspecialchars($projectImageUrl) ?>" />
<!-- Twitter image -->
<meta property="twitter:image" content="<?= htmlspecialchars($projectImageUrl) ?>" />
<?php endif; ?>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;700&display=swap" rel="stylesheet">
<style>
:root {
--bg-color-start: #6a11cb;
--bg-color-end: #2575fc;
--text-color: #ffffff;
--card-bg-color: rgba(255, 255, 255, 0.01);
--card-border-color: rgba(255, 255, 255, 0.1);
}
body {
margin: 0;
font-family: 'Inter', sans-serif;
background: linear-gradient(45deg, var(--bg-color-start), var(--bg-color-end));
color: var(--text-color);
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
text-align: center;
overflow: hidden;
position: relative;
}
body::before {
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" viewBox="0 0 100 100"><path d="M-10 10L110 10M10 -10L10 110" stroke-width="1" stroke="rgba(255,255,255,0.05)"/></svg>');
animation: bg-pan 20s linear infinite;
z-index: -1;
}
@keyframes bg-pan {
0% { background-position: 0% 0%; }
100% { background-position: 100% 100%; }
}
main {
padding: 2rem;
}
.card {
background: var(--card-bg-color);
border: 1px solid var(--card-border-color);
border-radius: 16px;
padding: 2rem;
backdrop-filter: blur(20px);
-webkit-backdrop-filter: blur(20px);
box-shadow: 0 8px 32px 0 rgba(0, 0, 0, 0.1);
}
.loader {
margin: 1.25rem auto 1.25rem;
width: 48px;
height: 48px;
border: 3px solid rgba(255, 255, 255, 0.25);
border-top-color: #fff;
border-radius: 50%;
animation: spin 1s linear infinite;
}
@keyframes spin {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
.hint {
opacity: 0.9;
}
.sr-only {
position: absolute;
width: 1px; height: 1px;
padding: 0; margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap; border: 0;
}
h1 {
font-size: 3rem;
font-weight: 700;
margin: 0 0 1rem;
letter-spacing: -1px;
}
p {
margin: 0.5rem 0;
font-size: 1.1rem;
}
code {
background: rgba(0,0,0,0.2);
padding: 2px 6px;
border-radius: 4px;
font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}
footer {
position: absolute;
bottom: 1rem;
font-size: 0.8rem;
opacity: 0.7;
}
</style>
</head> </head>
<body> <body>
<main>
<div class="card"> <?php include 'includes/header.php'; ?>
<h1>Analyzing your requirements and generating your website…</h1>
<div class="loader" role="status" aria-live="polite" aria-label="Applying initial changes"> <main>
<span class="sr-only">Loading…</span> <section id="hero" class="d-flex align-items-center text-center">
</div> <div class="container">
<p class="hint"><?= ($_SERVER['HTTP_HOST'] ?? '') === 'appwizzy.com' ? 'AppWizzy' : 'Flatlogic' ?> AI is collecting your requirements and applying the first changes.</p> <h1 class="display-3 fw-bold">Welcome to READY BUDDY</h1>
<p class="hint">This page will update automatically as the plan is implemented.</p> <p class="lead col-lg-6 mx-auto">The ultimate platform to challenge yourself, compete with others, and win amazing prizes. Your journey to greatness starts here.</p>
<p>Runtime: PHP <code><?= htmlspecialchars($phpVersion) ?></code> — UTC <code><?= htmlspecialchars($now) ?></code></p> <a href="#contact" class="btn btn-primary btn-lg rounded-pill">Get Started</a>
</div> </div>
</main> </section>
<footer>
Page updated: <?= htmlspecialchars($now) ?> (UTC) <section id="about" class="py-5">
</footer> <div class="container">
<div class="row align-items-center">
<div class="col-lg-6">
<h2 class="fw-bold">About Us</h2>
<p>READY BUDDY is a vibrant community and competition platform designed to bring out the best in you. We believe in the power of healthy competition to foster growth, learning, and connection. Whether you're a student, a professional, or a hobbyist, our platform provides the stage for you to shine.</p>
<p>We host a variety of competitions, from coding challenges and design contests to quizzes and creative showcases. Join us to test your skills, win prizes, and become part of a supportive community.</p>
</div>
<div class="col-lg-6 text-center">
<i class="bi bi-trophy-fill display-1 text-primary"></i>
</div>
</div>
</div>
</section>
<section id="portfolio" class="py-5 bg-light">
<div class="container text-center">
<h2 class="fw-bold">Portfolio</h2>
<p class="text-muted mb-5">Check out some of our past competitions and winner showcases.</p>
<div class="row">
<div class="col-md-4 mb-4"><div class="card h-100"><div class="card-body"><h5 class="card-title">CodeFest 2025</h5><p class="card-text">An intense coding marathon.</p></div></div></div>
<div class="col-md-4 mb-4"><div class="card h-100"><div class="card-body"><h5 class="card-title">Design Masters</h5><p class="card-text">A creative design challenge.</p></div></div></div>
<div class="col-md-4 mb-4"><div class="card h-100"><div class="card-body"><h5 class="card-title">Quiz Bowl</h5><p class="card-text">A battle of wits and knowledge.</p></div></div></div>
</div>
</div>
</section>
<section id="testimonials" class="py-5">
<div class="container text-center">
<h2 class="fw-bold">What Our Users Say</h2>
<div id="testimonialCarousel" class="carousel slide" data-bs-ride="carousel">
<div class="carousel-inner">
<div class="carousel-item active"><p class="lead fst-italic col-lg-8 mx-auto">"A fantastic platform! I won the CodeFest and it was a great experience."</p><p class="fw-bold">- Alex Doe</p></div>
<div class="carousel-item"><p class="lead fst-italic col-lg-8 mx-auto">"The community is so supportive. I learned a lot."</p><p class="fw-bold">- Jane Smith</p></div>
</div>
</div>
</div>
</section>
<section id="contact" class="py-5 bg-light">
<div class="container">
<div class="row">
<div class="col-lg-8 mx-auto text-center">
<h2 class="fw-bold">Contact Us</h2>
<p class="text-muted mb-4">Have questions? We'd love to hear from you.</p>
<div id="contact-form-container">
<form id="contactForm">
<div class="form-floating mb-3">
<input type="text" class="form-control" id="name" placeholder="Your Name" required>
<label for="name">Your Name</label>
</div>
<div class="form-floating mb-3">
<input type="email" class="form-control" id="email" placeholder="name@example.com" required>
<label for="email">Email address</label>
</div>
<div class="form-floating mb-3">
<textarea class="form-control" id="message" placeholder="Your Message" style="height: 150px" required></textarea>
<label for="message">Your Message</label>
</div>
<button type="submit" class="btn btn-primary btn-lg rounded-pill">Send Message</button>
</form>
</div>
<div id="form-feedback"></div>
</div>
</div>
</div>
</section>
</main>
<?php include 'includes/footer.php'; ?>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
<script src="assets/js/main.js?v=<?php echo time(); ?>"></script>
</body> </body>
</html> </html>

91
login.php Normal file
View File

@ -0,0 +1,91 @@
<?php
session_start();
require_once 'db/config.php';
$error = '';
$return_url = $_REQUEST['return_url'] ?? 'index.php';
if (isset($_SESSION['user_id'])) {
header("Location: " . $return_url);
exit;
}
if ($_SERVER["REQUEST_METHOD"] == "POST") {
$email = trim($_POST['email']);
$password = trim($_POST['password']);
if (empty($email) || empty($password)) {
$error = 'Email and password are required.';
} else {
try {
$pdo = db();
$stmt = $pdo->prepare("SELECT id, password, name 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['name'];
header("Location: " . $return_url);
exit;
} else {
$error = 'Invalid email or password.';
}
} catch (PDOException $e) {
$error = "Database error: " . $e->getMessage();
}
}
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Login - READY BUDDY</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="assets/css/custom.css">
</head>
<body>
<?php include 'includes/header.php'; ?>
<main class="container mt-5 pt-5">
<div class="row justify-content-center">
<div class="col-md-6">
<div class="card">
<div class="card-body">
<h2 class="card-title text-center">Login</h2>
<?php if ($error): ?>
<div class="alert alert-danger"><?php echo $error; ?></div>
<?php endif; ?>
<form action="login.php" method="post">
<input type="hidden" name="return_url" value="<?php echo htmlspecialchars($return_url); ?>">
<div class="mb-3">
<label for="email" class="form-label">Email address</label>
<input type="email" class="form-control" id="email" name="email" required>
</div>
<div class="mb-3">
<label for="password" class="form-label">Password</label>
<input type="password" class="form-control" id="password" name="password" required>
</div>
<div class="d-grid">
<button type="submit" class="btn btn-primary">Login</button>
</div>
</form>
<div class="text-center mt-3">
<p>Don't have an account? <a href="register.php">Register here</a>.</p>
</div>
</div>
</div>
</div>
</div>
</main>
<?php include 'includes/footer.php'; ?>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
<script src="assets/js/main.js"></script>
</body>
</html>

6
logout.php Normal file
View File

@ -0,0 +1,6 @@
<?php
session_start();
session_unset();
session_destroy();
header("Location: index.php");
exit;

45
my_certificates.php Normal file
View File

@ -0,0 +1,45 @@
<?php
session_start();
require_once 'includes/header.php';
require_once 'db/config.php';
if (!isset($_SESSION['user_id'])) {
header("Location: login.php");
exit;
}
$user_id = $_SESSION['user_id'];
$pdo = db();
$stmt = $pdo->prepare("
SELECT
c.certificate_code,
comp.title as competition_title
FROM certificates c
JOIN submissions s ON c.submission_id = s.id
JOIN competitions comp ON s.competition_id = comp.id
WHERE s.user_id = ?
");
$stmt->execute([$user_id]);
$certificates = $stmt->fetchAll();
?>
<div class="container mt-5">
<h1 class="mb-4">My Certificates</h1>
<?php if (empty($certificates)): ?>
<div class="alert alert-info">You have not earned any certificates yet.</div>
<?php else: ?>
<ul class="list-group">
<?php foreach ($certificates as $certificate): ?>
<li class="list-group-item d-flex justify-content-between align-items-center">
<?php echo htmlspecialchars($certificate['competition_title']); ?>
<a href="generate_certificate.php?code=<?php echo htmlspecialchars($certificate['certificate_code']); ?>" class="btn btn-primary" target="_blank">View Certificate</a>
</li>
<?php endforeach; ?>
</ul>
<?php endif; ?>
</div>
<?php require_once 'includes/footer.php'; ?>

96
register.php Normal file
View File

@ -0,0 +1,96 @@
<?php
session_start();
require_once 'db/config.php';
$error = '';
$success = '';
if ($_SERVER["REQUEST_METHOD"] == "POST") {
$name = trim($_POST['name']);
$email = trim($_POST['email']);
$password = trim($_POST['password']);
if (empty($name) || empty($email) || empty($password)) {
$error = 'All fields are required.';
} elseif (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
$error = 'Invalid email format.';
} else {
try {
$pdo = db();
$stmt = $pdo->prepare("SELECT id FROM users WHERE email = ?");
$stmt->execute([$email]);
if ($stmt->fetch()) {
$error = 'Email already exists.';
} else {
$hashed_password = password_hash($password, PASSWORD_DEFAULT);
$stmt = $pdo->prepare("INSERT INTO users (name, email, password) VALUES (?, ?, ?)");
if ($stmt->execute([$name, $email, $hashed_password])) {
$success = 'Registration successful! You can now <a href="login.php">login</a>.';
} else {
$error = 'Something went wrong. Please try again.';
}
}
} catch (PDOException $e) {
$error = "Database error: " . $e->getMessage();
}
}
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Register - READY BUDDY</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="assets/css/custom.css">
</head>
<body>
<?php include 'includes/header.php'; ?>
<main class="container mt-5 pt-5">
<div class="row justify-content-center">
<div class="col-md-6">
<div class="card">
<div class="card-body">
<h2 class="card-title text-center">Create Account</h2>
<?php if ($error): ?>
<div class="alert alert-danger"><?php echo $error; ?></div>
<?php endif; ?>
<?php if ($success): ?>
<div class="alert alert-success"><?php echo $success; ?></div>
<?php else: ?>
<form action="register.php" method="post">
<div class="mb-3">
<label for="name" class="form-label">Full Name</label>
<input type="text" class="form-control" id="name" name="name" required>
</div>
<div class="mb-3">
<label for="email" class="form-label">Email address</label>
<input type="email" class="form-control" id="email" name="email" required>
</div>
<div class="mb-3">
<label for="password" class="form-label">Password</label>
<input type="password" class="form-control" id="password" name="password" required>
</div>
<div class="d-grid">
<button type="submit" class="btn btn-primary">Register</button>
</div>
</form>
<?php endif; ?>
<div class="text-center mt-3">
<p>Already have an account? <a href="login.php">Login here</a>.</p>
</div>
</div>
</div>
</div>
</div>
</main>
<?php include 'includes/footer.php'; ?>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
<script src="assets/js/main.js"></script>
</body>
</html>