151 lines
4.8 KiB
TypeScript
151 lines
4.8 KiB
TypeScript
"use client";
|
|
import { useState } from "react";
|
|
import Link from "next/link";
|
|
import PostFilterItems from "./post-filter/PostFilterItems";
|
|
|
|
const BlogItems = () => {
|
|
const [currentPage, setCurrentPage] = useState(1);
|
|
const [totalPages, setTotalPages] = useState(1);
|
|
const postsPerPage = 6;
|
|
|
|
const handlePageChange = (page: number) => {
|
|
if (page >= 1 && page <= totalPages) {
|
|
setCurrentPage(page);
|
|
// Scroll to top of posts section
|
|
window.scrollTo({ top: 0, behavior: 'smooth' });
|
|
}
|
|
};
|
|
|
|
const handleTotalPagesChange = (total: number) => {
|
|
setTotalPages(total);
|
|
};
|
|
|
|
// Generate page numbers to display
|
|
const getPageNumbers = () => {
|
|
const pages: (number | string)[] = [];
|
|
const maxPagesToShow = 5;
|
|
|
|
if (totalPages <= maxPagesToShow) {
|
|
// Show all pages if total is small
|
|
for (let i = 1; i <= totalPages; i++) {
|
|
pages.push(i);
|
|
}
|
|
} else {
|
|
// Show first page
|
|
pages.push(1);
|
|
|
|
// Calculate range around current page
|
|
let startPage = Math.max(2, currentPage - 1);
|
|
let endPage = Math.min(totalPages - 1, currentPage + 1);
|
|
|
|
// Add ellipsis after first page if needed
|
|
if (startPage > 2) {
|
|
pages.push('...');
|
|
}
|
|
|
|
// Add pages around current page
|
|
for (let i = startPage; i <= endPage; i++) {
|
|
pages.push(i);
|
|
}
|
|
|
|
// Add ellipsis before last page if needed
|
|
if (endPage < totalPages - 1) {
|
|
pages.push('...');
|
|
}
|
|
|
|
// Show last page
|
|
if (totalPages > 1) {
|
|
pages.push(totalPages);
|
|
}
|
|
}
|
|
|
|
return pages;
|
|
};
|
|
|
|
return (
|
|
<section className="fix-top pb-120 blog-m">
|
|
<div className="container">
|
|
<div className="row align-items-center vertical-column-gap">
|
|
<div className="col-12 col-lg-7">
|
|
<h2 className="mt-8 fw-7 text-secondary title-anim">Latest Company Insights</h2>
|
|
</div>
|
|
<div className="col-12 col-lg-5">
|
|
<form action="#" method="post" autoComplete="off">
|
|
<div className="search-form">
|
|
<input
|
|
type="search"
|
|
name="search-post"
|
|
id="searchPost"
|
|
placeholder="Search"
|
|
required
|
|
/>
|
|
<button
|
|
type="submit"
|
|
aria-label="search post"
|
|
title="search post"
|
|
>
|
|
<i className="fa-solid fa-magnifying-glass"></i>
|
|
</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
<PostFilterItems
|
|
currentPage={currentPage}
|
|
onPageChange={handlePageChange}
|
|
onTotalPagesChange={handleTotalPagesChange}
|
|
postsPerPage={postsPerPage}
|
|
/>
|
|
{totalPages > 1 && (
|
|
<div className="row mt-60">
|
|
<div className="col-12">
|
|
<div className="section__cta">
|
|
<ul className="pagination">
|
|
<li>
|
|
<button
|
|
onClick={() => handlePageChange(currentPage - 1)}
|
|
disabled={currentPage === 1}
|
|
aria-label="Previous page"
|
|
style={{ opacity: currentPage === 1 ? 0.5 : 1, cursor: currentPage === 1 ? 'not-allowed' : 'pointer' }}
|
|
>
|
|
<i className="fa-solid fa-angle-left"></i>
|
|
</button>
|
|
</li>
|
|
{getPageNumbers().map((page, index) => (
|
|
<li key={index}>
|
|
{typeof page === 'number' ? (
|
|
<button
|
|
onClick={() => handlePageChange(page)}
|
|
className={currentPage === page ? 'active' : ''}
|
|
aria-label={`Go to page ${page}`}
|
|
aria-current={currentPage === page ? 'page' : undefined}
|
|
>
|
|
{page}
|
|
</button>
|
|
) : (
|
|
<span style={{ padding: '0 10px' }}>{page}</span>
|
|
)}
|
|
</li>
|
|
))}
|
|
<li>
|
|
<button
|
|
onClick={() => handlePageChange(currentPage + 1)}
|
|
disabled={currentPage === totalPages}
|
|
aria-label="Next page"
|
|
style={{ opacity: currentPage === totalPages ? 0.5 : 1, cursor: currentPage === totalPages ? 'not-allowed' : 'pointer' }}
|
|
>
|
|
<i className="fa-solid fa-angle-right"></i>
|
|
</button>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
)}
|
|
</div>
|
|
</section>
|
|
);
|
|
};
|
|
|
|
export default BlogItems;
|