russ_react/src/pages/SearchPage.tsx

102 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 { Header } from '../components/Header';
import { ArticleCard } from '../components/ArticleCard';
import { Pagination } from '../components/Pagination';
import { Article } from '../types';
import api from '../utils/api';
const ARTICLES_PER_PAGE = 9;
export function SearchPage() {
const [searchParams, setSearchParams] = useSearchParams();
const query = searchParams.get('q') || '';
const authorId = searchParams.get('author');
const page = parseInt(searchParams.get('page') || '1', 10);
const [articles, setArticles] = useState<Article[]>([]);
const [totalPages, setTotalPages] = useState(1);
const [loading, setLoading] = useState(false);
useEffect(() => {
const fetchResults = async () => {
if (!query && !authorId) return;
setLoading(true);
try {
const response = await api.get('/articles/search', {
params: {
q: query,
author: authorId,
page,
limit: ARTICLES_PER_PAGE
}
});
setArticles(response.data.articles);
setTotalPages(response.data.totalPages);
} catch (error) {
console.error('Ошибка поиска:', error);
} finally {
setLoading(false);
}
};
window.scrollTo({ top: 0, behavior: 'smooth' });
fetchResults();
}, [query, authorId, page]);
const handlePageChange = (newPage: number) => {
setSearchParams({ q: query, page: newPage.toString() });
window.scrollTo({ top: 0, behavior: 'smooth' });
};
return (
<div className="min-h-screen bg-gray-50">
<Header />
<main className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-12">
<div className="mb-8">
<h1 className="text-3xl font-bold text-gray-900">
{query ? `Результаты поиска "${query}"` : 'Статьи автора'}
</h1>
{articles.length > 0 && (
<p className="mt-2 text-gray-600">
Найдено {articles.length} статей
</p>
)}
</div>
{loading ? (
<div className="flex justify-center items-center h-64">
<div className="animate-spin rounded-full h-12 w-12 border-b-2 border-blue-600"></div>
</div>
) : articles.length > 0 ? (
<>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">
{articles.map((article) => (
<ArticleCard key={article.id} article={article} />
))}
</div>
{totalPages > 1 && (
<Pagination
currentPage={page}
totalPages={totalPages}
onPageChange={handlePageChange}
/>
)}
</>
) : (query || authorId) ? (
<div className="text-center py-12">
<h2 className="text-xl font-medium text-gray-900 mb-2">
Не найдено ни одной статьи
</h2>
<p className="text-gray-500">
{authorId ? "Этот автор не опубликовал пока ни одной статьи" : "Ничего не найдено. Попытайтесь изменить сроку поиска"}
</p>
</div>
) : null}
</main>
</div>
);
}