feat: news pagination — replace show more/collapse with page controls

This commit is contained in:
2026-03-26 12:16:56 +03:00
parent c9cfe63837
commit c9303e5aad

View File

@@ -121,11 +121,11 @@ function CompactArticle({
); );
} }
const INITIAL_VISIBLE = 4; const PER_PAGE = 4;
export function News({ data }: NewsProps) { export function News({ data }: NewsProps) {
const [selected, setSelected] = useState<NewsItem | null>(null); const [selected, setSelected] = useState<NewsItem | null>(null);
const [showAll, setShowAll] = useState(false); const [page, setPage] = useState(0);
if (!data.items || data.items.length === 0) return null; if (!data.items || data.items.length === 0) return null;
@@ -135,8 +135,8 @@ export function News({ data }: NewsProps) {
.sort((a, b) => (b.date || "").localeCompare(a.date || "")); .sort((a, b) => (b.date || "").localeCompare(a.date || ""));
if (sorted.length === 0) return null; if (sorted.length === 0) return null;
const [featured, ...rest] = sorted; const [featured, ...rest] = sorted;
const visibleRest = showAll ? rest : rest.slice(0, INITIAL_VISIBLE - 1); const totalPages = Math.max(1, Math.ceil(rest.length / PER_PAGE));
const hasMore = rest.length > INITIAL_VISIBLE - 1 && !showAll; const visibleRest = rest.slice(page * PER_PAGE, (page + 1) * PER_PAGE);
return ( return (
<section id="news" className="section-glow relative section-padding"> <section id="news" className="section-glow relative section-padding">
@@ -168,17 +168,48 @@ export function News({ data }: NewsProps) {
</Reveal> </Reveal>
)} )}
{hasMore && ( {totalPages > 1 && (
<Reveal> <div className="flex items-center justify-center gap-2">
<div className="text-center"> <button
onClick={() => {
setPage((p) => Math.max(0, p - 1));
const el = document.getElementById("news");
if (el) el.scrollIntoView({ behavior: "smooth", block: "start" });
}}
disabled={page === 0}
className="rounded-full border border-white/10 bg-white/[0.03] px-4 py-2 text-sm font-medium text-neutral-400 hover:text-white hover:border-white/25 transition-colors cursor-pointer disabled:opacity-30 disabled:cursor-not-allowed"
>
</button>
{Array.from({ length: totalPages }, (_, i) => (
<button <button
onClick={() => setShowAll(true)} key={i}
className="rounded-full border border-white/10 bg-white/[0.03] px-6 py-2.5 text-sm font-medium text-neutral-400 hover:text-white hover:border-white/25 transition-colors cursor-pointer" onClick={() => {
setPage(i);
const el = document.getElementById("news");
if (el) el.scrollIntoView({ behavior: "smooth", block: "start" });
}}
className={`h-8 w-8 rounded-full text-sm font-medium transition-colors cursor-pointer ${
i === page
? "bg-gold text-black"
: "border border-white/10 text-neutral-400 hover:text-white hover:border-white/25"
}`}
> >
Показать ещё ({rest.length - INITIAL_VISIBLE + 1}) {i + 1}
</button> </button>
</div> ))}
</Reveal> <button
onClick={() => {
setPage((p) => Math.min(totalPages - 1, p + 1));
const el = document.getElementById("news");
if (el) el.scrollIntoView({ behavior: "smooth", block: "start" });
}}
disabled={page === totalPages - 1}
className="rounded-full border border-white/10 bg-white/[0.03] px-4 py-2 text-sm font-medium text-neutral-400 hover:text-white hover:border-white/25 transition-colors cursor-pointer disabled:opacity-30 disabled:cursor-not-allowed"
>
</button>
</div>
)} )}
</div> </div>
</div> </div>