import Link from 'next/link';
import { requireAdminAuth } from '@/lib/adminAuth';
import { adminListArticles, getStats } from '@/lib/engine';
import { FileText, Eye, TrendingUp, Plus, Image, RefreshCw } from 'lucide-react';
export const dynamic = 'force-dynamic';
export const metadata = { title: 'Дашборд' };
function StatCard({ label, value, icon: Icon, color = 'emerald' }) {
const colors = {
emerald: 'bg-emerald-50 dark:bg-emerald-950 text-emerald-600 dark:text-emerald-400',
blue: 'bg-blue-50 dark:bg-blue-950 text-blue-600 dark:text-blue-400',
amber: 'bg-amber-50 dark:bg-amber-950 text-amber-600 dark:text-amber-400',
};
return (
);
}
export default async function AdminDashboard() {
await requireAdminAuth();
const [articles, stats] = await Promise.allSettled([
adminListArticles({ limit: 50 }),
getStats(),
]);
const arts = articles.status === 'fulfilled' ? (Array.isArray(articles.value) ? articles.value : articles.value?.articles || []) : [];
const st = stats.status === 'fulfilled' ? stats.value : null;
const published = arts.filter(a => a.status === 'published').length;
const drafts = arts.filter(a => a.status === 'draft').length;
const withoutCover = arts.filter(a => !a.cover_url).length;
const recentArts = arts.slice(0, 8);
return (
Дашборд
Управление контентом zeropost.ru
Новая статья
{/* Статистика */}
0 ? 'amber' : 'emerald'} />
{/* Быстрые действия */}
Быстрые действия
Написать статью
Все статьи
{withoutCover > 0 && (
)}
{/* Последние статьи */}
Последние статьи
Все →
{recentArts.map(a => (
{/* Обложка-превью */}
{a.cover_url ? (

) : (
)}
{a.title}
{a.status === 'published' ? 'Опубликовано' : 'Черновик'}
{a.tags?.slice(0, 2).map(t => (
#{t}
))}
{a.published_at ? new Date(a.published_at).toLocaleDateString('ru-RU', { day: 'numeric', month: 'short' }) : '—'}
))}
);
}
// Кнопка backfill — клиентская
function BackfillButton({ count }) {
return (
);
}