Files
sachgiaokhoaorg/app/Views/books/index.php
T
sachgiaokhoaorg e6b265db99 Sách Giáo Khoa Việt Nam - sachgiaokhoa.org
CodeIgniter 4 website:
- Catalog 999 SGK (lớp 1-12) từ API, lọc theo lớp/môn/NXB, tìm kiếm
- Trang chủ grouped browse (bậc học -> lớp -> môn, ưu tiên môn quan trọng)
- Chi tiết sách: metadata đầy đủ, cover nghệ thuật /thumb/{W}x{H}/
- Đọc online qua gate captcha + countdown, PDF viewer pdf.js
- Download: captcha + token một lần + auto cache-bust version
- Tự đồng bộ catalog/cover khi API thay đổi (refresh:catalog)
- Legal: DMCA, miễn trừ trách nhiệm, điều khoản, bảo mật, liên hệ
2026-08-23 07:05:49 +00:00

104 lines
4.6 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?= $this->extend('layouts/main') ?>
<?= $this->section('content') ?>
<div class="hero">
<h1>
<?php if ($filters['q'] !== ''): ?>
Kết quả tìm kiếm "<?= esc($filters['q']) ?>"
<?php elseif ($filters['lop'] !== ''): ?>
Sách lớp <?= esc($filters['lop']) ?>
<?php elseif ($filters['mon'] !== ''): ?>
Môn <?= esc($filters['mon']) ?>
<?php else: ?>
Sách <?= esc($filters['nxb']) ?>
<?php endif; ?>
</h1>
<p><?= number_format($total) ?> đầu sách phù hợp.</p>
</div>
<form class="filters" method="get" action="/">
<div class="grade-pills">
<a href="<?= $filters['q'] !== '' ? '/?q=' . urlencode($filters['q']) : '/' ?>" class="<?= $filters['lop'] === '' ? 'active' : '' ?>">Tất cả</a>
<?php foreach ($grades as $g): ?>
<a class="<?= $filters['lop'] === (string) $g ? 'active' : '' ?>"
href="/?<?= esc(http_build_query(array_merge($_GET, ['trang' => 1, 'lop' => $g]))) ?>">Lớp <?= $g ?></a>
<?php endforeach; ?>
</div>
<label>Môn học
<select name="mon" onchange="this.form.submit()">
<option value="">-- Tất cả --</option>
<?php foreach ($subjects as $s => $n): ?>
<option value="<?= esc($s) ?>" <?= $filters['mon'] === $s ? 'selected' : '' ?>><?= esc($s ?: 'Khác') ?> (<?= $n ?>)</option>
<?php endforeach; ?>
</select>
</label>
<label>Nhà xuất bản
<select name="nxb" onchange="this.form.submit()">
<option value="">-- Tất cả --</option>
<?php foreach ($publishers as $p => $n): ?>
<option value="<?= esc($p) ?>" <?= $filters['nxb'] === $p ? 'selected' : '' ?>><?= esc($p) ?> (<?= $n ?>)</option>
<?php endforeach; ?>
</select>
</label>
<?php if ($filters['q'] !== ''): ?><input type="hidden" name="q" value="<?= esc($filters['q']) ?>"><?php endif; ?>
<button class="btn btn-primary" type="submit">Lọc</button>
<a class="btn btn-outline reset" href="/">Xóa lọc</a>
</form>
<?php foreach ($grouped as $groupLabel => $groupBooks): ?>
<div class="group-header">
<h2><?= esc($groupLabel) ?> <span class="group-count"><?= count($groupBooks) ?> sách</span></h2>
</div>
<div class="book-grid">
<?php foreach ($groupBooks as $b): ?>
<?php $m = $b['meta']; ?>
<a class="book-card" href="/sach/<?= esc($b['id']) ?>">
<div class="book-cover">
<img loading="lazy" src="/thumb/360x480/<?= esc($b['id']) ?>.jpg?v=<?= media_version() ?>" alt="Bìa <?= esc($b['title']) ?>"
onerror="this.src='data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 3 4%22%3E%3Crect width=%223%22 height=%224%22 fill=%22%23e8ecf4%22/%3E%3C/svg%3E'">
<?php if (! empty($m['pages'])): ?><span class="cover-pages"><?= (int) $m['pages'] ?> tr</span><?php endif; ?>
</div>
<div class="book-info">
<h3><?= esc($b['title']) ?></h3>
<?php if ($b['subject']): ?><span class="book-subject"><?= esc($b['subject']) ?></span><?php endif; ?>
<div class="badges">
<?php if ($b['grade']): ?><span class="badge">Lớp <?= esc($b['grade']) ?></span><?php endif; ?>
<?php if ($b['publisher']): ?><span class="badge pub"><?= esc($b['publisher']) ?></span><?php endif; ?>
</div>
<div class="book-meta">
<?php if (! empty($m['sizeMB'])): ?><span>💾 <?= number_format((float) $m['sizeMB'], 1) ?> MB</span><?php endif; ?>
<?php if (! empty($m['authors'])): ?><span class="authors">✍ <?= esc(mb_strimwidth($m['authors'], 0, 46, '…')) ?></span><?php endif; ?>
</div>
</div>
</a>
<?php endforeach; ?>
</div>
<?php endforeach; ?>
<?php if (empty($grouped)): ?>
<div class="legal-page"><p>Không tìm thấy sách phù hợp với bộ lọc. <a href="/">Xóa bộ lọc</a>.</p></div>
<?php endif; ?>
<?php if ($totalPage > 1): ?>
<div class="pagination">
<?php
$qs = fn($p) => '/?' . esc(http_build_query(array_merge($_GET, ['trang' => $p])));
?>
<?php if ($page > 1): ?><a href="<?= $qs($page - 1) ?>"> Trước</a><?php else: ?><span class="disabled"> Trước</span><?php endif; ?>
<?php
$start = max(1, $page - 2);
$end = min($totalPage, $start + 4);
$start = max(1, $end - 4);
for ($p = $start; $p <= $end; $p++):
?>
<?php if ($p === $page): ?><span class="active"><?= $p ?></span>
<?php else: ?><a href="<?= $qs($p) ?>"><?= $p ?></a><?php endif; ?>
<?php endfor; ?>
<?php if ($page < $totalPage): ?><a href="<?= $qs($page + 1) ?>">Sau </a><?php else: ?><span class="disabled">Sau </span><?php endif; ?>
</div>
<?php endif; ?>
<?= $this->endSection() ?>