import React, { useState, useEffect } from 'react'; import axios from 'axios'; import { Article } from '../types'; import { CategoryTitles, CityTitles } from '../types'; import { Pencil, Trash2, ImagePlus, ToggleLeft, ToggleRight, Plus } from 'lucide-react'; import MinutesWord from './Words/MinutesWord'; import { useAuthStore } from '../stores/authStore'; import { usePermissions } from '../hooks/usePermissions'; import {Pagination} from "./Pagination.tsx"; import {useSearchParams} from "react-router-dom"; interface ArticleListProps { articles: Article[]; setArticles: React.Dispatch>; onEdit: (id: string) => void; onDelete: (id: string) => void; onShowGallery: (id: string) => void; onNewArticle: () => void; refreshTrigger: number; } const ARTICLES_PER_PAGE = 6; export const ArticleList = React.memo(function ArticleList({ articles, setArticles, onEdit, onDelete, onShowGallery, onNewArticle, refreshTrigger, }: ArticleListProps) { const { user } = useAuthStore(); const { availableCategoryIds, availableCityIds, isAdmin } = usePermissions(); const [searchParams, setSearchParams] = useSearchParams(); const [totalPages, setTotalPages] = useState(1); const [totalArticles, setTotalArticles] = useState(0); const currentPage = Math.max(1, parseInt(searchParams.get('page') || '1', 10)); const [filterCategoryId, setFilterCategoryId] = useState(0); const [filterCityId, setFilterCityId] = useState(0); const [showDraftOnly, setShowDraftOnly] = useState(false); const [error, setError] = useState(null); const [loading, setLoading] = useState(false); useEffect(() => { const fetchArticles = async () => { setLoading(true); try { const response = await axios.get('/api/articles/', { params: { page: currentPage, categoryId: filterCategoryId, cityId: filterCityId, isDraft: showDraftOnly, userId: user?.id, isAdmin }, }); setArticles(response.data.articles); setTotalPages(response.data.totalPages); setTotalArticles(response.data.total); } catch (error) { setError('Не удалось загрузить статьи'); console.error(error); } finally { setLoading(false); } }; fetchArticles(); }, [currentPage, filterCategoryId, filterCityId, showDraftOnly, refreshTrigger, user, isAdmin, setArticles]); const handleToggleActive = async (id: string) => { const article = articles.find(a => a.id === id); if (article) { try { await axios.put( `/api/articles/active/${id}`, { isActive: !article.isActive }, { headers: { Authorization: `Bearer ${localStorage.getItem('token')}` } } ); setArticles(prev => prev.map(a => (a.id === id ? { ...a, isActive: !a.isActive } : a))); // Обновляем список с сервера после изменения статуса const response = await axios.get('/api/articles/', { params: { page: currentPage, categoryId: filterCategoryId, cityId: filterCityId, isDraft: showDraftOnly, userId: user?.id, isAdmin }, }); setArticles(response.data.articles); setTotalPages(response.data.totalPages); } catch (error) { setError('Не удалось переключить статус статьи'); console.error(error); } } }; const handlePageChange = (page: number) => { searchParams.set('page', page.toString()); setSearchParams(searchParams); window.scrollTo({ top: 0, behavior: 'smooth' }); }; const hasNoPermissions = availableCategoryIds.length === 0 || availableCityIds.length === 0; return (

Статьи

{!hasNoPermissions && ( )}

Статьи {Math.min((currentPage - 1) * ARTICLES_PER_PAGE + 1, totalArticles)} - {Math.min(currentPage * ARTICLES_PER_PAGE, totalArticles)} из {totalArticles}

{loading ? (
) : hasNoPermissions ? (

Недостаточно прав

У вас нет прав на создание и редактирование статей. Свяжитесь с администратором.

) : ( <>
    {articles.map(article => (
  • {article.title}

    · {CategoryTitles[article.categoryId]} · {CityTitles[article.cityId]} · {article.readTime}{' '} чтения

    {(() => { const writerAuthors = article.authors .filter(a => a.role === 'WRITER') .sort((a, b) => (a.author.order ?? 0) - (b.author.order ?? 0)); if (!writerAuthors) return null; return (
    {writerAuthors.map((authorLink) => ( {authorLink.author.displayName} ))}

    {writerAuthors.map((a, i) => ( {a.author.displayName} {i < writerAuthors.length - 1 ? ', ' : ''} ))}

    ); })()}
  • ))}
{totalPages > 1 && ( )} )} {error && isAdmin && (
{error}
)}
); });