'use client'; import React, { useState, useEffect } from 'react'; import Link from 'next/link'; import { Plus, Search, Filter, Eye, Edit, Trash2, Calendar, Tag, Loader2 } from 'lucide-react'; interface NewsItem { id: string; title: string; slug: string; summary: string; content: string; category: string; imageUrl?: string; featured: boolean; published: boolean; publishedAt: string; createdAt: string; updatedAt: string; views: number; likes: number; author?: { id: string; name?: string; username: string; }; } interface NewsCategory { id: string; name: string; slug: string; color: string; } const NEWS_CATEGORIES: NewsCategory[] = [ { id: 'company', name: 'Новости компании', slug: 'company', color: 'bg-blue-500' }, { id: 'promotions', name: 'Акции', slug: 'promotions', color: 'bg-green-500' }, { id: 'other', name: 'Другое', slug: 'other', color: 'bg-purple-500' } ]; export default function AdminNewsPage() { const [news, setNews] = useState([]); const [loading, setLoading] = useState(true); const [searchQuery, setSearchQuery] = useState(''); const [selectedCategory, setSelectedCategory] = useState('all'); const [selectedStatus, setSelectedStatus] = useState('all'); const [sortBy, setSortBy] = useState('publishedAt'); const [sortOrder, setSortOrder] = useState<'asc' | 'desc'>('desc'); useEffect(() => { loadNews(); }, [searchQuery, selectedCategory, selectedStatus, sortBy, sortOrder]); const loadNews = async () => { try { setLoading(true); const params = new URLSearchParams(); params.append('page', '1'); params.append('limit', '100'); params.append('sortBy', sortBy); params.append('sortOrder', sortOrder); if (searchQuery.trim()) { params.append('search', searchQuery); } if (selectedCategory !== 'all') { params.append('category', selectedCategory); } // Для админки показываем все новости if (selectedStatus === 'published') { params.append('published', 'true'); } else if (selectedStatus === 'draft') { params.append('published', 'false'); } else if (selectedStatus === 'featured') { params.append('featured', 'true'); } const response = await fetch(`/api/news?${params}`); const data = await response.json(); if (data.success) { setNews(data.data.news); } else { console.error('Error loading news:', data.error); } } catch (error) { console.error('Error loading news:', error); } finally { setLoading(false); } }; const formatDate = (dateString: string) => { return new Date(dateString).toLocaleDateString('ru-RU', { year: 'numeric', month: 'short', day: 'numeric' }); }; const getCategoryInfo = (categoryId: string) => { return NEWS_CATEGORIES.find(cat => cat.id === categoryId); }; const handleDelete = async (id: string) => { if (!confirm('Вы уверены, что хотите удалить эту новость?')) { return; } try { const response = await fetch(`/api/news/${id}`, { method: 'DELETE' }); if (response.ok) { setNews(news.filter(item => item.id !== id)); } else { console.error('Error deleting news'); } } catch (error) { console.error('Error deleting news:', error); } }; const togglePublished = async (id: string) => { try { const newsItem = news.find(item => item.id === id); if (!newsItem) return; const response = await fetch(`/api/news/${id}`, { method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ published: !newsItem.published }) }); if (response.ok) { const data = await response.json(); if (data.success) { setNews(news.map(item => item.id === id ? { ...item, published: !item.published } : item )); } } } catch (error) { console.error('Error toggling published status:', error); } }; const toggleFeatured = async (id: string) => { try { const newsItem = news.find(item => item.id === id); if (!newsItem) return; const response = await fetch(`/api/news/${id}`, { method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ featured: !newsItem.featured }) }); if (response.ok) { const data = await response.json(); if (data.success) { setNews(news.map(item => item.id === id ? { ...item, featured: !item.featured } : item )); } } } catch (error) { console.error('Error toggling featured status:', error); } }; if (loading) { return (
Загрузка новостей...
); } return (
{/* Header */}

Управление новостями

Создание, редактирование и публикация новостей

Создать новость
{/* Filters */}
{/* Search */}
setSearchQuery(e.target.value)} className="w-full pl-10 pr-4 py-2 border border-gray-300 rounded-md focus:ring-2 focus:ring-blue-500 focus:border-transparent" />
{/* Category Filter */} {/* Status Filter */} {/* Sort */}
{/* News List */}

Новости ({news.length})

{news.length > 0 ? (
{news.map((newsItem) => { const categoryInfo = getCategoryInfo(newsItem.category); return (

{newsItem.title}

{categoryInfo && ( {categoryInfo.name} )} {newsItem.featured && ( Рекомендуемое )} {newsItem.published ? 'Опубликовано' : 'Черновик'}

{newsItem.summary}

{formatDate(newsItem.publishedAt)} {newsItem.views} просмотров ❤️ {newsItem.likes} лайков {newsItem.author && ( Автор: {newsItem.author.name || newsItem.author.username} )}
); })}
) : (

Новости не найдены

Попробуйте изменить фильтры или создать новую новость

Создать новость
)}
); }