90 lines
2.8 KiB
TypeScript
90 lines
2.8 KiB
TypeScript
import React, { useState, useMemo } from 'react';
|
|
import { useLocation, useSearchParams } from 'react-router-dom';
|
|
import { ArticleCard } from './ArticleCard';
|
|
import { Pagination } from './Pagination';
|
|
import { articles } from '../data/mock';
|
|
|
|
const ARTICLES_PER_PAGE = 6;
|
|
|
|
export function FeaturedSection() {
|
|
const location = useLocation();
|
|
const [searchParams, setSearchParams] = useSearchParams();
|
|
const category = searchParams.get('category');
|
|
const city = searchParams.get('city');
|
|
const currentPage = parseInt(searchParams.get('page') || '1', 10);
|
|
|
|
const filteredArticles = useMemo(() => {
|
|
return articles.filter(article => {
|
|
if (category && city) {
|
|
return article.category === category && article.city === city;
|
|
}
|
|
if (category) {
|
|
return article.category === category;
|
|
}
|
|
if (city) {
|
|
return article.city === city;
|
|
}
|
|
return true;
|
|
});
|
|
}, [category, city]);
|
|
|
|
const totalPages = Math.ceil(filteredArticles.length / ARTICLES_PER_PAGE);
|
|
|
|
const currentArticles = useMemo(() => {
|
|
const startIndex = (currentPage - 1) * ARTICLES_PER_PAGE;
|
|
return filteredArticles.slice(startIndex, startIndex + ARTICLES_PER_PAGE);
|
|
}, [filteredArticles, currentPage]);
|
|
|
|
const handlePageChange = (page: number) => {
|
|
searchParams.set('page', page.toString());
|
|
setSearchParams(searchParams);
|
|
window.scrollTo({ top: 0, behavior: 'smooth' });
|
|
};
|
|
|
|
if (filteredArticles.length === 0) {
|
|
return (
|
|
<section className="py-12 px-4 sm:px-6 lg:px-8 max-w-7xl mx-auto">
|
|
<div className="text-center py-12">
|
|
<h3 className="text-xl font-medium text-gray-900 mb-2">
|
|
No articles found
|
|
</h3>
|
|
<p className="text-gray-500">
|
|
Please try a different category or city
|
|
</p>
|
|
</div>
|
|
</section>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<section className="py-12 px-4 sm:px-6 lg:px-8 max-w-7xl mx-auto">
|
|
<div className="flex justify-between items-center mb-8">
|
|
<h2 className="text-3xl font-bold text-gray-900">
|
|
{city ? `${city} ` : ''}
|
|
{category ? `${category} Stories` : 'Featured Stories'}
|
|
</h2>
|
|
<p className="text-gray-600">
|
|
Showing {Math.min(currentPage * ARTICLES_PER_PAGE, filteredArticles.length)} of {filteredArticles.length} articles
|
|
</p>
|
|
</div>
|
|
|
|
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">
|
|
{currentArticles.map((article, index) => (
|
|
<ArticleCard
|
|
key={article.id}
|
|
article={article}
|
|
featured={currentPage === 1 && index === 0 && !category && !city}
|
|
/>
|
|
))}
|
|
</div>
|
|
|
|
{totalPages > 1 && (
|
|
<Pagination
|
|
currentPage={currentPage}
|
|
totalPages={totalPages}
|
|
onPageChange={handlePageChange}
|
|
/>
|
|
)}
|
|
</section>
|
|
);
|
|
} |