Files
ckeproekt/app/admin/page.tsx

190 lines
7.3 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.

'use client';
import React from 'react';
import Link from 'next/link';
import { FileText, Eye, Calendar, TrendingUp, Plus } from 'lucide-react';
import { NEWS_DATA } from '@/lib/news-data';
export default function AdminDashboard() {
// Подсчет статистики
const totalNews = NEWS_DATA.length;
const publishedNews = NEWS_DATA.filter(news => news.published !== false).length;
const featuredNews = NEWS_DATA.filter(news => news.featured).length;
const recentNews = NEWS_DATA.filter(news => {
const publishDate = new Date(news.publishedAt);
const weekAgo = new Date();
weekAgo.setDate(weekAgo.getDate() - 7);
return publishDate >= weekAgo;
}).length;
const stats = [
{
name: 'Всего новостей',
value: totalNews,
icon: FileText,
color: 'bg-blue-500',
textColor: 'text-blue-600'
},
{
name: 'Опубликовано',
value: publishedNews,
icon: Eye,
color: 'bg-green-500',
textColor: 'text-green-600'
},
{
name: 'Рекомендуемые',
value: featuredNews,
icon: TrendingUp,
color: 'bg-yellow-500',
textColor: 'text-yellow-600'
},
{
name: 'За неделю',
value: recentNews,
icon: Calendar,
color: 'bg-purple-500',
textColor: 'text-purple-600'
}
];
const latestNews = NEWS_DATA
.sort((a, b) => new Date(b.publishedAt).getTime() - new Date(a.publishedAt).getTime())
.slice(0, 5);
return (
<div className="space-y-8">
{/* Header */}
<div className="flex flex-col sm:flex-row sm:items-center sm:justify-between">
<div>
<h1 className="text-3xl font-bold text-gray-900">Панель управления</h1>
<p className="text-gray-600 mt-2">Обзор системы управления новостями</p>
</div>
<Link
href="/admin/news/create"
className="mt-4 sm:mt-0 inline-flex items-center px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 transition-colors"
>
<Plus className="h-4 w-4 mr-2" />
Создать новость
</Link>
</div>
{/* Stats Grid */}
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6">
{stats.map((stat) => (
<div key={stat.name} className="bg-white rounded-lg shadow-sm p-6">
<div className="flex items-center">
<div className={`p-3 rounded-lg ${stat.color} bg-opacity-10`}>
<stat.icon className={`h-6 w-6 ${stat.textColor}`} />
</div>
<div className="ml-4">
<p className="text-sm text-gray-600">{stat.name}</p>
<p className="text-2xl font-bold text-gray-900">{stat.value}</p>
</div>
</div>
</div>
))}
</div>
{/* Recent News */}
<div className="bg-white rounded-lg shadow-sm">
<div className="px-6 py-4 border-b border-gray-200">
<div className="flex items-center justify-between">
<h2 className="text-lg font-semibold text-gray-900">Последние новости</h2>
<Link
href="/admin/news"
className="text-blue-600 hover:text-blue-800 text-sm font-medium"
>
Показать все
</Link>
</div>
</div>
<div className="divide-y divide-gray-200">
{latestNews.map((news) => (
<div key={news.id} className="px-6 py-4 hover:bg-gray-50">
<div className="flex items-center justify-between">
<div className="flex-1">
<div className="flex items-center space-x-2">
<h3 className="text-sm font-medium text-gray-900 truncate">
{news.title}
</h3>
{news.featured && (
<span className="inline-flex items-center px-2 py-1 rounded-full text-xs font-medium bg-yellow-100 text-yellow-800">
Рекомендуемое
</span>
)}
<span className={`inline-flex items-center px-2 py-1 rounded-full text-xs font-medium ${
news.published !== false
? 'bg-green-100 text-green-800'
: 'bg-gray-100 text-gray-800'
}`}>
{news.published !== false ? 'Опубликовано' : 'Черновик'}
</span>
</div>
<p className="text-sm text-gray-500 mt-1">
{new Date(news.publishedAt).toLocaleDateString('ru-RU')}
</p>
</div>
<div className="flex items-center space-x-2">
<Link
href={`/admin/news/${news.id}/edit`}
className="text-blue-600 hover:text-blue-800 text-sm"
>
Редактировать
</Link>
<Link
href={`/news/${news.slug}`}
target="_blank"
className="text-gray-600 hover:text-gray-800 text-sm"
>
Просмотр
</Link>
</div>
</div>
</div>
))}
</div>
</div>
{/* Quick Actions */}
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
<div className="bg-white rounded-lg shadow-sm p-6">
<h3 className="text-lg font-semibold text-gray-900 mb-4">Быстрые действия</h3>
<div className="space-y-3">
<Link
href="/admin/news/create"
className="flex items-center p-3 rounded-md hover:bg-gray-50 transition-colors"
>
<Plus className="h-5 w-5 text-blue-600 mr-3" />
<span className="text-sm font-medium text-gray-900">Создать новость</span>
</Link>
<Link
href="/admin/news"
className="flex items-center p-3 rounded-md hover:bg-gray-50 transition-colors"
>
<FileText className="h-5 w-5 text-green-600 mr-3" />
<span className="text-sm font-medium text-gray-900">Управление новостями</span>
</Link>
</div>
</div>
<div className="bg-white rounded-lg shadow-sm p-6">
<h3 className="text-lg font-semibold text-gray-900 mb-4">Статистика по категориям</h3>
<div className="space-y-3">
{['company', 'promotions', 'other'].map((category) => {
const count = NEWS_DATA.filter(news => news.category === category).length;
const categoryName = category === 'company' ? 'Новости компании' :
category === 'promotions' ? 'Акции' : 'Другое';
return (
<div key={category} className="flex items-center justify-between">
<span className="text-sm text-gray-600">{categoryName}</span>
<span className="text-sm font-medium text-gray-900">{count}</span>
</div>
);
})}
</div>
</div>
</div>
</div>
);
}