📄 Source: apply.php
<?php
require_once 'includes/config.php';
require_once 'includes/db.php';
require_once 'includes/auth.php';
require_once 'includes/functions.php';
$forumId = $_GET['id'] ?? '';
$forum = getForum($forumId);
if (!$forum) {
header('Location: index.php?error=Forum not found');
exit();
}
$user = getCurrentUser();
// Check if user is logged in
if (!$user) {
header('Location: login.php?redirect=' . urlencode('apply.php?id=' . $forumId));
exit();
}
// Check if already submitted
if (hasUserSubmitted($forumId, $user['id'])) {
header('Location: index.php?error=You already submitted an application to this forum');
exit();
}
$error = '';
$success = '';
$startTime = $_SESSION['apply_start_' . $forumId] ?? null;
$timeLimit = $forum['time_limit'] * 60; // Convert to seconds
// Check time limit
if ($startTime && time() - $startTime > $timeLimit) {
$error = 'Time limit exceeded. Please start a new application.';
unset($_SESSION['apply_start_' . $forumId]);
}
// Start timer if not started
if (!$startTime && $_SERVER['REQUEST_METHOD'] !== 'POST') {
$_SESSION['apply_start_' . $forumId] = time();
$startTime = time();
}
if ($_SERVER['REQUEST_METHOD'] === 'POST' && !$error) {
$answers = $_POST['answers'] ?? [];
$submissionData = [];
$allAnswered = true;
foreach ($forum['questions'] as $idx => $q) {
$answer = $answers[$idx] ?? '';
if ($q['required'] && empty($answer)) {
$allAnswered = false;
$error = 'Please answer all required questions';
break;
}
$submissionData[] = [
'question' => $q['text'],
'question_type' => $q['type'],
'answer' => is_array($answer) ? implode(', ', array_map('sanitize', $answer)) : sanitize($answer)
];
}
if ($allAnswered) {
$submission = [
'user_id' => $user['id'],
'username' => $user['username'],
'discord_id' => $user['discord_id'] ?? null,
'google_id' => $user['google_id'] ?? null,
'answers' => $submissionData,
'status' => 'pending',
'notes' => ''
];
if (addSubmission($forumId, $submission)) {
unset($_SESSION['apply_start_' . $forumId]);
$success = 'Application submitted successfully!';
header('Location: my-applications.php?success=submitted');
exit();
} else {
$error = 'Failed to submit application';
}
}
}
// Calculate remaining time
$remainingTime = 0;
if ($startTime && !$error) {
$remainingTime = max(0, $timeLimit - (time() - $startTime));
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Apply - <?php echo htmlspecialchars($forum['title']); ?></title>
<link href="https://fonts.googleapis.com/css2?family=Inter:opsz,wght@14..32,300;400;500;600;700;800&display=swap" rel="stylesheet">
<link rel="stylesheet" href="assets/style.css">
<style>
.timer-bar {
background: var(--bg-card);
padding: 1rem;
border-radius: 1rem;
margin-bottom: 1.5rem;
text-align: center;
border: 2px solid var(--border-color);
}
.timer-bar .time {
font-size: 2rem;
font-weight: 800;
font-family: monospace;
}
.timer-bar.warning .time {
color: var(--error);
}
.question-block {
background: var(--bg-card);
border-radius: 1rem;
padding: 1.5rem;
margin-bottom: 1.5rem;
border: 1px solid var(--border-color);
}
.question-block .q-label {
font-weight: 600;
margin-bottom: 0.5rem;
display: block;
}
.question-block .q-required {
color: var(--error);
font-weight: 400;
}
.question-block textarea {
width: 100%;
padding: 0.9rem;
border-radius: 1rem;
border: 2px solid var(--input-border);
background: var(--input-bg);
color: var(--input-text);
font-family: inherit;
resize: vertical;
}
.question-block textarea:focus {
outline: none;
border-color: var(--input-focus);
}
.question-block input[type="text"] {
width: 100%;
padding: 0.9rem;
border-radius: 1rem;
border: 2px solid var(--input-border);
background: var(--input-bg);
color: var(--input-text);
}
.question-block input[type="text"]:focus {
outline: none;
border-color: var(--input-focus);
}
.option-buttons {
display: flex;
flex-wrap: wrap;
gap: 0.5rem;
}
.option-btn {
background: var(--option-bg);
border: 2px solid var(--border-color);
border-radius: 2rem;
padding: 0.6rem 1.2rem;
cursor: pointer;
transition: all 0.2s;
color: var(--text-primary);
}
.option-btn:hover {
background: var(--info);
color: white;
}
.option-btn.selected {
background: var(--info);
color: white;
}
.checkbox-option {
display: flex;
align-items: center;
gap: 0.5rem;
padding: 0.5rem;
border-radius: 0.5rem;
cursor: pointer;
transition: background 0.2s;
}
.checkbox-option:hover {
background: var(--option-bg);
}
.checkbox-option input[type="checkbox"] {
width: 18px;
height: 18px;
cursor: pointer;
}
.char-counter {
font-size: 0.8rem;
color: var(--text-secondary);
text-align: right;
margin-top: 0.3rem;
}
.char-counter.warning {
color: var(--warning);
}
.char-counter.danger {
color: var(--error);
}
.platform-required {
background: var(--warning);
color: white;
padding: 0.5rem 1rem;
border-radius: 1rem;
margin-bottom: 1.5rem;
text-align: center;
}
</style>
</head>
<body>
<div class="theme-switcher">
<button class="theme-btn" data-theme="light" title="Light mode">☀️</button>
<button class="theme-btn" data-theme="dark" title="Dark mode">🌙</button>
</div>
<div class="container">
<header class="header">
<div class="header-top">
<h1>📝 <?php echo htmlspecialchars($forum['title']); ?></h1>
<a href="index.php" class="back-link">← Back</a>
</div>
<?php if (!empty($forum['description'])): ?>
<p class="subhead"><?php echo htmlspecialchars($forum['description']); ?></p>
<?php endif; ?>
</header>
<?php if ($forum['platform'] !== 'none'): ?>
<div class="platform-required">
🔐 You must be logged in with <?php echo getPlatformLabel($forum['platform']); ?> to apply
</div>
<?php endif; ?>
<?php if ($error): ?>
<div class="error-message">⚠️ <?php echo htmlspecialchars($error); ?></div>
<?php endif; ?>
<?php if (!$error && $remainingTime > 0): ?>
<div class="timer-bar" id="timerBar">
<div>⏱️ Time Remaining</div>
<div class="time" id="timerDisplay"><?php echo formatTime($remainingTime); ?></div>
</div>
<?php endif; ?>
<form method="POST" action="" id="applyForm">
<?php foreach ($forum['questions'] as $idx => $q): ?>
<div class="question-block">
<label class="q-label">
<?php echo htmlspecialchars($q['text']); ?>
<?php if ($q['required']): ?>
<span class="q-required">*</span>
<?php endif; ?>
</label>
<?php if ($q['type'] === 'text'): ?>
<input type="text" name="answers[<?php echo $idx; ?>]"
maxlength="<?php echo $q['max_chars']; ?>"
placeholder="Your answer..."
oninput="updateCounter(this, <?php echo $idx; ?>)">
<div class="char-counter" id="counter_<?php echo $idx; ?>">0 / <?php echo $q['max_chars']; ?></div>
<?php elseif ($q['type'] === 'textarea'): ?>
<textarea name="answers[<?php echo $idx; ?>]"
maxlength="<?php echo $q['max_chars']; ?>"
rows="4"
placeholder="Your answer..."
oninput="updateCounter(this, <?php echo $idx; ?>)"></textarea>
<div class="char-counter" id="counter_<?php echo $idx; ?>">0 / <?php echo $q['max_chars']; ?></div>
<?php elseif ($q['type'] === 'choice'): ?>
<div class="option-buttons">
<?php foreach ($q['options'] as $opt): ?>
<button type="button" class="option-btn" onclick="selectOption(this, <?php echo $idx; ?>, '<?php echo htmlspecialchars($opt); ?>')">
<?php echo htmlspecialchars($opt); ?>
</button>
<?php endforeach; ?>
</div>
<input type="hidden" name="answers[<?php echo $idx; ?>]" id="answer_<?php echo $idx; ?>">
<?php elseif ($q['type'] === 'checkbox'): ?>
<?php foreach ($q['options'] as $opt): ?>
<div class="checkbox-option">
<input type="checkbox" name="answers[<?php echo $idx; ?>][]" value="<?php echo htmlspecialchars($opt); ?>" onchange="updateCheckbox(<?php echo $idx; ?>)">
<label><?php echo htmlspecialchars($opt); ?></label>
</div>
<?php endforeach; ?>
<?php endif; ?>
</div>
<?php endforeach; ?>
<button type="submit" class="btn-primary" style="width: 100%; background: var(--btn-success);">
📤 Submit Application
</button>
</form>
<footer class="footer">
<p>⏱️ You have <?php echo $forum['time_limit']; ?> minutes to complete this application</p>
</footer>
</div>
<script>
let remainingTime = <?php echo $remainingTime; ?>;
let timerInterval = null;
function updateCounter(input, idx) {
const counter = document.getElementById(`counter_${idx}`);
if (counter) {
const max = input.maxLength;
const current = input.value.length;
counter.textContent = `${current} / ${max}`;
counter.className = 'char-counter' + (current > max * 0.9 ? ' warning' : '') + (current >= max ? ' danger' : '');
}
}
function selectOption(btn, idx, value) {
const container = btn.closest('.option-buttons');
container.querySelectorAll('.option-btn').forEach(b => b.classList.remove('selected'));
btn.classList.add('selected');
document.getElementById(`answer_${idx}`).value = value;
}
function updateCheckbox(idx) {
// The value is automatically handled by the form submission
}
// Timer
if (remainingTime > 0) {
timerInterval = setInterval(function() {
remainingTime--;
const minutes = Math.floor(remainingTime / 60);
const seconds = remainingTime % 60;
const display = document.getElementById('timerDisplay');
if (display) {
display.textContent = String(minutes).padStart(2, '0') + ':' + String(seconds).padStart(2, '0');
}
const timerBar = document.getElementById('timerBar');
if (timerBar && remainingTime < 60) {
timerBar.className = 'timer-bar warning';
}
if (remainingTime <= 0) {
clearInterval(timerInterval);
document.getElementById('applyForm').submit();
}
}, 1000);
}
// Prevent form submission if time is up
document.getElementById('applyForm').addEventListener('submit', function(e) {
if (remainingTime <= 0) {
e.preventDefault();
alert('Time limit exceeded!');
}
});
</script>
<script src="assets/script.js"></script>
</body>
</html>
← Back