96 lines
3.5 KiB
JavaScript
96 lines
3.5 KiB
JavaScript
"use client";
|
|
import { useState } from "react";
|
|
import Link from "next/link";
|
|
import Pagination from "./Pagination";
|
|
import "public/assets/css/Pagination.css";
|
|
|
|
const truncateWords = (text, limit = 20) => {
|
|
const words = text.split(" ");
|
|
return words.length > limit ? words.slice(0, limit).join(" ") + " ..." : text;
|
|
};
|
|
|
|
const stripHtml = (html) => {
|
|
if (!html) return "";
|
|
return html.replace(/<[^>]*>/g, "");
|
|
};
|
|
|
|
const truncateTitle = (text, limit) => {
|
|
if (!text) return "";
|
|
return text.length > limit ? text.slice(0, limit) + "..." : text;
|
|
};
|
|
|
|
const BlogList = ({ blogs }) => {
|
|
const [currentPage, setCurrentPage] = useState(1);
|
|
const postsPerPage = 12;
|
|
|
|
// Sort posts by date descending (newest first) - exactly like original code
|
|
const sortedPosts = [...blogs].sort((a, b) => new Date(b.date) - new Date(a.date));
|
|
|
|
// Calculate pagination
|
|
const totalPages = Math.ceil(sortedPosts.length / postsPerPage);
|
|
const indexOfLastPost = currentPage * postsPerPage;
|
|
const indexOfFirstPost = indexOfLastPost - postsPerPage;
|
|
const currentPosts = sortedPosts.slice(indexOfFirstPost, indexOfLastPost);
|
|
|
|
const handlePageChange = (page) => {
|
|
setCurrentPage(page);
|
|
};
|
|
|
|
return (
|
|
<div className="blog-section"> {/* Wrapper for scroll functionality */}
|
|
<div className="row clearfix">
|
|
{currentPosts.map((blog) => (
|
|
<div
|
|
key={blog.id}
|
|
className="col-lg-4 col-md-6 col-sm-12 mb-4 pt-5"
|
|
>
|
|
<div className="blog-card rounded shadow-sm overflow-hidden">
|
|
{/* Blog Image */}
|
|
<div className="blog-image">
|
|
<img
|
|
src={blog.imageDetail}
|
|
alt={blog.title}
|
|
className="img-fluid w-100"
|
|
/>
|
|
</div>
|
|
|
|
{/* Blog Title */}
|
|
<div className="blog-content p-3">
|
|
<h3 className="mb-2 text-lg font-semibold blog-title-hover">
|
|
<Link href={`/blog/${blog.slug}`} className="blog-title-link">
|
|
{truncateTitle(stripHtml(blog.title), 40)}
|
|
</Link>
|
|
</h3>
|
|
|
|
{/* Blog Excerpt */}
|
|
<p className="text-gray-700 mb-3">
|
|
{truncateWords(stripHtml(blog.para))}
|
|
</p>
|
|
|
|
{/* Read More Button */}
|
|
<Link
|
|
href={`/blog/${blog.slug}`}
|
|
className="font-medium blog-title-link"
|
|
>
|
|
Read More
|
|
</Link>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
))}
|
|
</div>
|
|
|
|
{/* Pagination Component */}
|
|
{totalPages > 1 && (
|
|
<Pagination
|
|
currentPage={currentPage}
|
|
totalPages={totalPages}
|
|
onPageChange={handlePageChange}
|
|
/>
|
|
)}
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default BlogList;
|