| <?php |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| $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'; |
| ?> |
| |