feat: news pagination — replace show more/collapse with page controls
This commit is contained in:
@@ -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>
|
||||||
|
|||||||
Reference in New Issue
Block a user