<?php
require_once __DIR__ . '/config.php';
if (!IS_INSTALLED) { header('Location: setup.php'); exit; }
require_once ROOT_PATH . '/includes/db.php';
require_once ROOT_PATH . '/includes/functions.php';
require_once ROOT_PATH . '/includes/auth.php';
require_once ROOT_PATH . '/includes/markdown.php';
$topics = get_topics(); // top-level only, for the topic grid
$allTopics = get_topics(null, true); // all topics, for filter dropdown
// Apply admin-configured root topic: show sub-topics of chosen topic instead of full root list
$_rootTopicId = (int)get_setting('topic_index_start_id', '0');
if ($_rootTopicId > 0) {
$_children = get_subtopics($_rootTopicId);
if (!empty($_children)) $topics = $_children;
}
unset($_rootTopicId, $_children);
$allTags = audience_tags_enabled() ? get_tags() : [];
// Filters from query string
$filterTopic = (int)($_GET['topic'] ?? 0);
$filterTag = audience_tags_enabled() ? (int)($_GET['tag'] ?? 0) : 0;
$filterQ = trim($_GET['q'] ?? '');
// Build documents query with all active filters
$where = ["d.status = 'published'"];
$params = [];
if ($filterTopic) { $where[] = 'd.topic_id = ?'; $params[] = $filterTopic; }
if ($filterQ) {
if (fts5_available()) {
$where[] = "d.id IN (SELECT document_id FROM search_index WHERE search_index MATCH ? AND status = 'published')";
$params[] = fts5_query($filterQ);
} else {
$where[] = "(d.title LIKE ? OR d.meta_description LIKE ?)";
$params[] = "%$filterQ%";
$params[] = "%$filterQ%";
}
}
if ($filterTag) { $where[] = 'd.id IN (SELECT document_id FROM document_tags WHERE tag_id = ?)'; $params[] = $filterTag; }
$sql = "SELECT d.*, t.slug AS topic_slug, t.title AS topic_title
FROM documents d JOIN topics t ON d.topic_id = t.id
WHERE " . implode(' AND ', $where) . "
ORDER BY d.updated_at DESC LIMIT 120";
$stmt = db()->prepare($sql);
$stmt->execute($params);
$recent = $stmt->fetchAll();
$meta = build_meta();
include ROOT_PATH . '/includes/header.php';
?>
<?php
$landingPage = get_page('landing');
if ($landingPage && ($landingPage['enabled'] || has_role('editor')) && trim($landingPage['content']) !== ''):
?>
<div class="window" style="margin-bottom:14px">
<div class="win-titlebar">🏠 <?= h($landingPage['nav_label'] ?: $landingPage['title']) ?>
<?php if (has_role('editor')): ?>
<div class="win-actions">
<a href="<?= h(base_url('admin/pages.php?edit=landing')) ?>" class="button btn-sm">✎ Edit</a>
</div>
<?php endif; ?>
<?php if (!$landingPage['enabled']): ?>
<span style="font-size:11px;opacity:0.75">(disabled — only visible to editors)</span>
<?php endif; ?>
</div>
<div class="win-body">
<div class="markdown-body"><?= md($landingPage['content']) ?></div>
</div>
</div>
<?php endif; ?>
<!-- Hero -->
<div class="win-titlebar page-hero">
<div class="hero-inner">
<?php $logo = get_setting('logo'); if ($logo): ?>
<img src="<?= h(base_url('uploads/images/' . $logo)) ?>" alt="<?= h(get_setting('site_title')) ?>" class="hero-logo">
<?php else: ?>
<span class="hero-sitename"><?= h(get_setting('site_title', 'IndexGram')) ?></span>
<?php endif; ?>
<p class="hero-desc"><?= h(get_setting('site_description')) ?></p>
</div>
</div>
<!-- Search & Filter -->
<section class="search-section">
<form method="get" style="display:flex;gap:8px;align-items:center;flex-wrap:wrap">
<input type="search" name="q" placeholder="Search documents…" value="<?= h($filterQ) ?>"
style="font-size:13px;padding:4px 8px;border:2px solid;border-color:#808080 #FFF #FFF #808080;background:#FFF;font-family:inherit;flex:1;min-width:160px">
<select name="topic" style="font-size:13px;padding:4px 6px;border:2px solid;border-color:#808080 #FFF #FFF #808080;background:#FFF;font-family:inherit">
<option value="0" <?= !$filterTopic ? 'selected' : '' ?>>All Topics</option>
<?php foreach ($allTopics as $t): ?>
<?php $indent = $t['parent_id'] ? (get_topic_by_id((int)$t['parent_id'])['parent_id'] ? ' » ' : ' › ') : ''; ?>
<option value="<?= $t['id'] ?>" <?= $filterTopic === (int)$t['id'] ? 'selected' : '' ?>><?= $indent . h($t['title']) ?></option>
<?php endforeach; ?>
</select>
<?php if (!empty($allTags)): ?>
<select name="tag" style="font-size:13px;padding:4px 6px;border:2px solid;border-color:#808080 #FFF #FFF #808080;background:#FFF;font-family:inherit">
<option value="0" <?= !$filterTag ? 'selected' : '' ?>>All Audiences</option>
<?php foreach ($allTags as $tg): ?>
<option value="<?= $tg['id'] ?>" <?= $filterTag === (int)$tg['id'] ? 'selected' : '' ?>><?= h($tg['name']) ?></option>
<?php endforeach; ?>
</select>
<?php endif; ?>
<button type="submit" style="font-size:13px;padding:4px 12px;border:2px solid;border-color:#FFF #404040 #404040 #FFF;background:#C0C0C0;cursor:pointer;font-family:inherit">🔍 Search</button>
<?php if ($filterTopic || $filterTag || $filterQ): ?>
<a href="<?= h(base_url()) ?>" style="font-size:12px">✕ Clear</a>
<?php endif; ?>
</form>
</section>
<!-- Topics Grid -->
<section class="topics-section">
<div class="section-titlebar"><h2>📂 Topic Index</h2></div>
<div class="topics-grid">
<?php if (empty($topics)): ?>
<p class="empty-state">No topics yet. <a href="<?= h(base_url('login')) ?>">Log in</a> to add one.</p>
<?php endif; ?>
<?php foreach ($topics as $t): ?>
<?php $count = count(get_documents($t['id'])); ?>
<div class="topic-card">
<div class="topic-card-body">
<?php if ($t['og_image']): ?>
<img src="<?= h(base_url('uploads/og/' . $t['og_image'])) ?>" alt="" class="topic-thumb">
<?php else: ?>
<span class="topic-icon">📁</span>
<?php endif; ?>
<a href="<?= h(topic_url($t['slug'])) ?>" class="topic-card-link"><?= h($t['title']) ?></a>
<p class="topic-desc"><?= h($t['description']) ?></p>
<span class="topic-count"><?= $count ?> document<?= $count !== 1 ? 's' : '' ?></span>
<span class="topic-rss"><a href="<?= h(rss_url($t['slug'])) ?>">RSS</a></span>
</div>
</div>
<?php endforeach; ?>
</div>
</section>
<!-- Document Index -->
<section class="recent-section">
<div class="section-titlebar" id="doc-index-bar"
style="cursor:pointer;user-select:none"
onclick="toggleDocIndex()" title="Click to expand/collapse">
<h2 style="margin:0">📄 Document Index <span id="doc-index-arrow" style="font-size:11px">▶</span></h2>
</div>
<div id="doc-index-body" style="display:none">
<!-- Active audience filter tags shown as badges -->
<?php if (!empty($allTags) && !empty($recent) && audience_tags_enabled()): ?>
<div style="margin:6px 0 4px;display:flex;flex-wrap:wrap;gap:4px;align-items:center">
<span style="font-size:11px;color:#444">Filter by audience:</span>
<a href="<?= h(base_url() . ($filterTopic ? '?topic='.$filterTopic : '')) ?>"
class="tag-badge <?= !$filterTag ? 'active' : '' ?>"
style="background:#444;color:#FFF">All</a>
<?php foreach ($allTags as $tg): ?>
<?php $href = base_url() . '?tag=' . $tg['id'] . ($filterTopic ? '&topic='.$filterTopic : ''); ?>
<a href="<?= h($href) ?>"
class="tag-badge <?= $filterTag === (int)$tg['id'] ? 'active' : '' ?>"
style="background:<?= h($tg['color']) ?>;color:#FFF"><?= h($tg['name']) ?></a>
<?php endforeach; ?>
</div>
<?php endif; ?>
<?php if (empty($recent)): ?>
<p class="empty-state">No documents found.</p>
<?php else: ?>
<div class="doc-cards">
<?php foreach ($recent as $d): ?>
<?php
$dtags = audience_tags_enabled() ? get_document_tags($d['id']) : [];
$dgtags = get_document_generic_tags($d['id']);
?>
<div class="doc-card">
<div class="doc-card-body">
<?php if ($d['og_image']): ?>
<img src="<?= h(base_url('uploads/og/' . $d['og_image'])) ?>" alt="" class="doc-card-thumb">
<?php endif; ?>
<strong class="doc-card-name"><a href="<?= h(doc_url($d['topic_slug'], $d['slug'])) ?>"><?= h($d['title']) ?></a></strong>
<?php if ($d['meta_description']): ?>
<p class="doc-card-desc"><?= h($d['meta_description']) ?></p>
<?php endif; ?>
<div class="doc-card-meta">
<?php if (!empty($dtags)): ?>
<div class="doc-card-tags">
<?php foreach ($dtags as $tg): ?>
<?php $tagHref = base_url() . '?tag=' . $tg['id'] . ($filterTopic ? '&topic='.$filterTopic : ''); ?>
<a href="<?= h($tagHref) ?>"
class="tag-badge"
style="background:<?= h($tg['color']) ?>;color:#FFF"><?= h($tg['name']) ?></a>
<?php endforeach; ?>
</div>
<?php endif; ?>
<?php if (!empty($dgtags)): ?>
<div class="doc-card-tags">
<?php foreach ($dgtags as $gt): ?>
<span class="tag-badge" style="background:#555;color:#FFF"><?= h($gt['name']) ?></span>
<?php endforeach; ?>
</div>
<?php endif; ?>
<div class="doc-card-topic">
📂 <a href="<?= h(topic_url($d['topic_slug'])) ?>"><?= h($d['topic_title']) ?></a>
</div>
</div>
</div>
</div>
<?php endforeach; ?>
</div>
<?php endif; ?>
</div><!-- /#doc-index-body -->
</section>
<script>
(function(){
var open = sessionStorage.getItem('docIndexOpen') === '1';
// If there's an active filter, default to open
<?php if ($filterTopic || $filterTag || $filterQ): ?>open = true;<?php endif; ?>
var body = document.getElementById('doc-index-body');
var arrow = document.getElementById('doc-index-arrow');
function applyState() {
if (body) body.style.display = open ? '' : 'none';
if (arrow) arrow.textContent = open ? '▼' : '►';
}
applyState();
window.toggleDocIndex = function(){
open = !open;
sessionStorage.setItem('docIndexOpen', open ? '1' : '0');
applyState();
};
})();
</script>
<?php include ROOT_PATH . '/includes/footer.php'; ?>