109 lines
3.8 KiB
PHP
109 lines
3.8 KiB
PHP
<?php
|
|
require_once __DIR__ . '/includes/app.php';
|
|
ensure_tables();
|
|
|
|
$pageTitle = 'Forums';
|
|
$active = 'forums';
|
|
$pdo = db();
|
|
|
|
$filters = [
|
|
'search' => trim($_GET['search'] ?? ''),
|
|
'game' => trim($_GET['game'] ?? ''),
|
|
'tag' => trim($_GET['tag'] ?? ''),
|
|
];
|
|
|
|
$sql = "SELECT id, title, game, tag, author, created_at FROM forum_threads WHERE 1=1";
|
|
$params = [];
|
|
|
|
if ($filters['search']) {
|
|
$sql .= " AND (title LIKE :search OR body LIKE :search)";
|
|
$params[':search'] = '%' . $filters['search'] . '%';
|
|
}
|
|
if ($filters['game']) {
|
|
$sql .= " AND game = :game";
|
|
$params[':game'] = $filters['game'];
|
|
}
|
|
if ($filters['tag']) {
|
|
$sql .= " AND tag = :tag";
|
|
$params[':tag'] = $filters['tag'];
|
|
}
|
|
|
|
$sql .= " ORDER BY created_at DESC";
|
|
$stmt = $pdo->prepare($sql);
|
|
$stmt->execute($params);
|
|
$threads = $stmt->fetchAll();
|
|
|
|
$games = $pdo->query("SELECT DISTINCT game FROM forum_threads ORDER BY game")->fetchAll(PDO::FETCH_COLUMN);
|
|
$tags = $pdo->query("SELECT DISTINCT tag FROM forum_threads WHERE tag IS NOT NULL AND tag != '' ORDER BY tag")->fetchAll(PDO::FETCH_COLUMN);
|
|
|
|
include __DIR__ . '/includes/header.php';
|
|
?>
|
|
|
|
<div class="d-flex flex-wrap justify-content-between align-items-center mb-4 gap-2">
|
|
<div>
|
|
<h1 class="h3 mb-1">Community Forums</h1>
|
|
<p class="muted mb-0">Patch reaction, class strategy, and loot discussions.</p>
|
|
</div>
|
|
<a class="btn btn-primary" href="create_thread.php">Start thread</a>
|
|
</div>
|
|
|
|
<form class="app-card mb-4" method="get">
|
|
<div class="row g-3 align-items-end">
|
|
<div class="col-lg-6">
|
|
<label class="form-label">Search threads</label>
|
|
<input class="form-control" type="text" name="search" placeholder="Title or body" value="<?= h($filters['search']) ?>">
|
|
</div>
|
|
<div class="col-sm-6 col-lg-3">
|
|
<label class="form-label">Game</label>
|
|
<select class="form-select" name="game">
|
|
<option value="">All</option>
|
|
<?php foreach ($games as $game): ?>
|
|
<option value="<?= h($game) ?>" <?= $filters['game'] === $game ? 'selected' : '' ?>><?= h($game) ?></option>
|
|
<?php endforeach; ?>
|
|
</select>
|
|
</div>
|
|
<div class="col-sm-6 col-lg-3">
|
|
<label class="form-label">Tag</label>
|
|
<select class="form-select" name="tag">
|
|
<option value="">All</option>
|
|
<?php foreach ($tags as $tag): ?>
|
|
<option value="<?= h($tag) ?>" <?= $filters['tag'] === $tag ? 'selected' : '' ?>><?= h($tag) ?></option>
|
|
<?php endforeach; ?>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
<div class="mt-3 d-flex justify-content-end">
|
|
<button class="btn btn-outline-light" type="submit">Apply filters</button>
|
|
</div>
|
|
</form>
|
|
|
|
<div class="row g-3">
|
|
<?php if (!$threads): ?>
|
|
<div class="col-12">
|
|
<div class="app-card">
|
|
<h2 class="h5">No threads yet</h2>
|
|
<p class="muted">Start a discussion about the latest patch or class strategy.</p>
|
|
<a class="btn btn-outline-light" href="create_thread.php">Start thread</a>
|
|
</div>
|
|
</div>
|
|
<?php else: ?>
|
|
<?php foreach ($threads as $thread): ?>
|
|
<div class="col-md-6">
|
|
<div class="app-card h-100">
|
|
<div class="d-flex justify-content-between align-items-start mb-2">
|
|
<span class="badge badge-soft"><?= h($thread['game']) ?></span>
|
|
<?php if (!empty($thread['tag'])): ?>
|
|
<span class="badge badge-soft"><?= h($thread['tag']) ?></span>
|
|
<?php endif; ?>
|
|
</div>
|
|
<h2 class="h5"><?= h($thread['title']) ?></h2>
|
|
<p class="muted mb-3">By <?= h($thread['author']) ?> · <?= h(format_date($thread['created_at'])) ?></p>
|
|
<a class="btn btn-sm btn-outline-light" href="thread.php?id=<?= h((string)$thread['id']) ?>">Open thread</a>
|
|
</div>
|
|
</div>
|
|
<?php endforeach; ?>
|
|
<?php endif; ?>
|
|
</div>
|
|
|
|
<?php include __DIR__ . '/includes/footer.php'; ?>
|