russ_react/src/components/FeaturedSection.tsx

108 lines
3.4 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { useEffect, useState } from 'react';
import { useSearchParams } from 'react-router-dom';
import { ArticleCard } from './ArticleCard';
import { Pagination } from './Pagination';
import { Article, CategoryTitles, CityTitles } from '../types';
import axios from "axios";
const ARTICLES_PER_PAGE = 6;
export function FeaturedSection() {
const [searchParams, setSearchParams] = useSearchParams();
const category = searchParams.get('category');
const city = searchParams.get('city');
const currentPage = Math.max(1, parseInt(searchParams.get('page') || '1', 10));
const [articles, setArticles] = useState<Article[]>([]);
const [totalPages, setTotalPages] = useState(1);
const [totalArticles, setTotalArticles] = useState(0);
const [error, setError] = useState<string | null>(null);
// Загрузка статей
useEffect(() => {
const fetchArticles = async () => {
try {
const response = await axios.get('/api/articles/', {
params: {
page: currentPage,
categoryId: category || undefined,
cityId: city || undefined,
},
});
console.log(response.data.articles[0]);
setArticles(response.data.articles);
setTotalPages(response.data.totalPages);
setTotalArticles(response.data.total);
} catch (error) {
setError('Не удалось загрузить статьи');
console.error(error);
}
};
fetchArticles();
}, [category, city, currentPage]);
const handlePageChange = (page: number) => {
searchParams.set('page', page.toString());
setSearchParams(searchParams);
window.scrollTo({ top: 0, behavior: 'smooth' });
};
if (articles.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">
Еще нет заметок
</h3>
<p className="text-gray-500">
Выберите другой раздел или город
</p>
</div>
</section>
);
}
const shouldShowFeatured = currentPage === 1 && !category && !city;
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 ? `${CityTitles[Number(city)]} ` : ''}
{category ? `${CategoryTitles[Number(category)]}` : 'Читайте сегодня'}
</h2>
<p className="font-bold text-gray-600">
Статьи {Math.min((currentPage - 1) * ARTICLES_PER_PAGE + 1, totalArticles)}
-
{Math.min(currentPage * ARTICLES_PER_PAGE, totalArticles)} из {totalArticles}
</p>
</div>
{error && (
<div className="mb-6 bg-red-50 text-red-700 p-4 rounded-md">
{error}
</div>
)}
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-8">
{articles.map((article, index) => (
<ArticleCard
key={article.id}
article={article}
featured={shouldShowFeatured && index === 0}
/>
))}
</div>
{totalPages > 1 && (
<Pagination
currentPage={currentPage}
totalPages={totalPages}
onPageChange={handlePageChange}
/>
)}
</section>
);
}