research-document-archive / web /src /views /search-results.php
datamatters24's picture
Upload web/src/views/search-results.php with huggingface_hub
546ae02 verified
<?php
/**
* Search Results Page
*
* Variables:
* $query - Current search query string
* $collection - Selected collection filter (or empty/null for all)
* $results - Array of search results with: document_id, document_name, file_path,
* source_section, page_number, snippet (may contain <mark> tags)
* $total - Total number of matching results
* $page - Current page number
* $perPage - Results per page
*/
$page = $page ?? 1;
$perPage = $perPage ?? 25;
$totalPages = ($perPage > 0) ? (int)ceil(($total ?? 0) / $perPage) : 1;
$query = $query ?? '';
$collection = $collection ?? '';
$collectionNames = [
'' => 'All Collections',
'jfk_assassination' => 'JFK Assassination Records',
'cia_declassified' => 'CIA Declassified',
'cia_stargate' => 'CIA Stargate Program',
'cia_mkultra' => 'CIA MKUltra',
'lincoln_archives' => 'Lincoln Archives',
'house_resolutions' => 'House Resolutions',
'nasa_apod' => 'NASA APOD',
'nasa_epic' => 'NASA EPIC',
'area51_cia' => 'Area 51 / CIA Declassified',
'court_records' => 'Court Records',
'foia' => 'FOIA Releases',
'house_oversight' => 'House Oversight',
];
$collectionBadgeColors = [
'jfk_assassination' => 'bg-purple-100 text-purple-700',
'cia_declassified' => 'bg-emerald-100 text-emerald-700',
'cia_stargate' => 'bg-teal-100 text-teal-700',
'cia_mkultra' => 'bg-rose-100 text-rose-700',
'lincoln_archives' => 'bg-amber-100 text-amber-700',
'house_resolutions' => 'bg-blue-100 text-blue-700',
'nasa_apod' => 'bg-indigo-100 text-indigo-700',
'nasa_epic' => 'bg-sky-100 text-sky-700',
'area51_cia' => 'bg-emerald-100 text-emerald-700',
'court_records' => 'bg-slate-100 text-slate-700',
'foia' => 'bg-cyan-100 text-cyan-700',
'house_oversight' => 'bg-orange-100 text-orange-700',
];
$title = ($query ? htmlspecialchars($query) . ' - ' : '') . 'Search - Research Document Archive';
$content = '';
ob_start();
?>
<!-- Search Form -->
<div class="mb-5">
<h1 class="text-xl font-bold text-gray-900 mb-4">Search Documents</h1>
<form action="/search" method="GET">
<div class="flex flex-col sm:flex-row gap-2">
<!-- Search Input -->
<div class="relative flex-1">
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<svg class="h-4 w-4 text-gray-400" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
<path stroke-linecap="round" stroke-linejoin="round" d="M21 21l-5.197-5.197m0 0A7.5 7.5 0 105.196 5.196a7.5 7.5 0 0010.607 10.607z" />
</svg>
</div>
<input type="text" name="q" value="<?= htmlspecialchars($query) ?>"
placeholder="Search text content, entities, titles..."
class="w-full pl-9 pr-3 py-2 text-sm border border-gray-300 rounded-lg
focus:outline-none focus:border-blue-500 focus:ring-1 focus:ring-blue-200
transition-all placeholder-gray-400">
</div>
<!-- Collection Filter -->
<div class="sm:w-52">
<select name="collection"
class="w-full py-2 px-3 text-sm border border-gray-300 rounded-lg
focus:outline-none focus:border-blue-500 focus:ring-1 focus:ring-blue-200
transition-all bg-white text-gray-700">
<?php foreach ($collectionNames as $key => $label): ?>
<option value="<?= htmlspecialchars($key) ?>"
<?= $collection === $key ? 'selected' : '' ?>>
<?= htmlspecialchars($label) ?>
</option>
<?php endforeach; ?>
</select>
</div>
<!-- Submit -->
<button type="submit"
class="px-4 py-2 bg-blue-600 text-white text-sm font-medium rounded-lg
hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500
focus:ring-offset-1 transition-colors whitespace-nowrap">
Search
</button>
</div>
<!-- Advanced Filters -->
<details class="mt-2">
<summary class="text-xs text-gray-500 cursor-pointer hover:text-gray-700">Advanced Filters</summary>
<div class="flex flex-wrap gap-2 mt-2">
<!-- Topic Filter -->
<select name="topic" class="py-1.5 px-2 text-xs border border-gray-300 rounded-md bg-white text-gray-700">
<option value="">Any Topic</option>
<?php foreach ($availableTopics ?? [] as $t): ?>
<option value="<?= htmlspecialchars($t) ?>" <?= ($topicFilter ?? '') === $t ? 'selected' : '' ?>>
<?= htmlspecialchars(ucwords($t)) ?>
</option>
<?php endforeach; ?>
</select>
<!-- Stamp Filter -->
<select name="stamp" class="py-1.5 px-2 text-xs border border-gray-300 rounded-md bg-white text-gray-700">
<option value="">Any Classification</option>
<?php foreach ($availableStamps ?? [] as $s): ?>
<option value="<?= htmlspecialchars($s) ?>" <?= ($stampFilter ?? '') === $s ? 'selected' : '' ?>>
<?= htmlspecialchars($s) ?>
</option>
<?php endforeach; ?>
</select>
<?php if (!empty($topicFilter) || !empty($stampFilter)): ?>
<a href="/search?q=<?= urlencode($query) ?>&collection=<?= urlencode($collection) ?>"
class="inline-flex items-center px-2 py-1.5 text-xs text-red-600 hover:text-red-800">
Clear filters
</a>
<?php endif; ?>
</div>
</details>
</form>
</div>
<!-- Results -->
<?php if ($query): ?>
<!-- Result Count -->
<div class="flex items-center justify-between mb-4">
<p class="text-sm text-gray-600">
<?php if ($total > 0): ?>
Showing
<span class="font-semibold text-gray-900"><?= number_format(($page - 1) * $perPage + 1) ?></span>
to
<span class="font-semibold text-gray-900"><?= number_format(min($page * $perPage, $total)) ?></span>
of
<span class="font-semibold text-gray-900"><?= number_format($total) ?></span>
results for "<span class="font-semibold text-gray-900"><?= htmlspecialchars($query) ?></span>"
<?php else: ?>
No results found for "<span class="font-semibold text-gray-900"><?= htmlspecialchars($query) ?></span>"
<?php endif; ?>
<?php if ($collection): ?>
in <span class="font-semibold"><?= htmlspecialchars($collectionNames[$collection] ?? $collection) ?></span>
<?php endif; ?>
</p>
</div>
<?php if (!empty($results)): ?>
<div class="space-y-3">
<?php foreach ($results as $result): ?>
<?php
$docId = $result['document_id'] ?? 0;
$docName = $result['document_name'] ?? basename($result['file_path'] ?? 'Unknown');
$section = $result['source_section'] ?? '';
$sectionName = $collectionNames[$section] ?? ucwords(str_replace('_', ' ', $section));
$badgeColor = $collectionBadgeColors[$section] ?? 'bg-gray-100 text-gray-700';
$pageNum = $result['page_number'] ?? null;
$snippet = $result['snippet'] ?? '';
?>
<div class="bg-white rounded-lg shadow-sm border border-gray-200 hover:shadow-md transition-shadow overflow-hidden">
<div class="p-3.5">
<!-- Document Name -->
<div class="flex flex-wrap items-center gap-1.5 mb-1.5">
<a href="/document/<?= (int)$docId ?><?= $pageNum ? '#page=' . (int)$pageNum : '' ?>"
class="text-sm font-semibold text-blue-600 hover:text-blue-800 transition-colors">
<?= htmlspecialchars($docName) ?>
</a>
<span class="inline-flex items-center px-2 py-0.5 rounded-full text-[10px] font-medium <?= $badgeColor ?>">
<?= htmlspecialchars($sectionName) ?>
</span>
<?php if ($pageNum !== null): ?>
<span class="inline-flex items-center px-1.5 py-0.5 rounded text-[10px] font-medium bg-gray-100 text-gray-600">
p.<?= (int)$pageNum ?>
</span>
<?php endif; ?>
</div>
<!-- Snippet -->
<?php if ($snippet): ?>
<div class="text-xs text-gray-700 leading-relaxed line-clamp-3">
<?= $snippet ?>
</div>
<?php endif; ?>
<!-- Action Link -->
<div class="mt-2">
<a href="/document/<?= (int)$docId ?><?= $pageNum ? '#page=' . (int)$pageNum : '' ?>"
class="inline-flex items-center text-xs font-medium text-blue-600 hover:text-blue-800 transition-colors group">
View
<svg class="ml-1 h-3 w-3 group-hover:translate-x-0.5 transition-transform" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
<path stroke-linecap="round" stroke-linejoin="round" d="M13.5 4.5L21 12m0 0l-7.5 7.5M21 12H3" />
</svg>
</a>
</div>
</div>
</div>
<?php endforeach; ?>
</div>
<!-- Pagination -->
<?php
$currentPage = $page;
$paginationParams = 'q=' . urlencode($query);
if ($collection) {
$paginationParams .= '&collection=' . urlencode($collection);
}
$baseUrl = '/search?' . $paginationParams;
include __DIR__ . '/partials/pagination.php';
?>
<?php else: ?>
<!-- No Results -->
<div class="text-center py-10 bg-white rounded-lg border border-gray-200">
<svg class="mx-auto h-8 w-8 text-gray-400" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="1.5">
<path stroke-linecap="round" stroke-linejoin="round" d="M21 21l-5.197-5.197m0 0A7.5 7.5 0 105.196 5.196a7.5 7.5 0 0010.607 10.607z" />
</svg>
<h3 class="mt-3 text-sm font-medium text-gray-900">No results found</h3>
<p class="mt-1 text-xs text-gray-500 max-w-md mx-auto">
Try adjusting your search terms or removing collection filters.
</p>
</div>
<?php endif; ?>
<?php else: ?>
<!-- Initial state: no query yet -->
<div class="text-center py-10">
<svg class="mx-auto h-10 w-10 text-gray-300" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="1">
<path stroke-linecap="round" stroke-linejoin="round" d="M21 21l-5.197-5.197m0 0A7.5 7.5 0 105.196 5.196a7.5 7.5 0 0010.607 10.607z" />
</svg>
<h3 class="mt-3 text-sm font-medium text-gray-700">Enter a search query</h3>
<p class="mt-1 text-xs text-gray-500">Search across all collections by text content, entity names, or document titles.</p>
</div>
<?php endif; ?>
<?php
$content = ob_get_clean();
include __DIR__ . '/layout.php';
?>