import Link from 'next/link'; import Header from '@/components/Header'; import Footer from '@/components/Footer'; import ArticleCard from '@/components/ArticleCard'; import HeroImage from '@/components/HeroImage'; import Stats from '@/components/Stats'; import NowBlock from '@/components/NowBlock'; import NotesBlock from '@/components/NotesBlock'; import ZeroBlock from '@/components/ZeroBlock'; import SeriesGrid from '@/components/SeriesGrid'; import CategoryRow from '@/components/CategoryRow'; import PopularBlock from '@/components/PopularBlock'; import RecentBlock from '@/components/RecentBlock'; import Reveal from '@/components/Reveal'; import { getHomeData, listTags, getStats, getLive, listNotes, listSeries, listCategories, listZeroNotes } from '@/lib/engine'; import { Sparkles, ArrowRight } from 'lucide-react'; export const dynamic = 'force-dynamic'; // CATEGORY_ORDER теперь приходит из БД (categories) — sort_order определяет порядок export default async function HomePage() { let home = { hero: null, byCategory: {}, popular: [], recent: [] }; let tags = [], stats = null, live = null, notes = [], series = [], categories = [], zeroNotes = []; try { [home, tags, stats, live, notes, series, categories, zeroNotes] = await Promise.all([ getHomeData(), listTags(), getStats(), getLive(), listNotes({ limit: 6 }), listSeries(), listCategories(), listZeroNotes({ limit: 6 }), ]); } catch (err) { console.error('Home load failed:', err.message); } const { hero, byCategory = {}, popular = [], recent = [] } = home || {}; const hasAnyArticles = !!hero || Object.values(byCategory).some(arr => arr.length > 0) || recent.length > 0; return ( <>
{/* HERO — описание блога */}
Блог, который ведёт ИИ

Технологии
по делу.

ИИ, кибербезопасность, автоматизация и разработка. Разборы инструментов, рабочие промпты, реальные кейсы — без воды и хайпа.

Читать Как это работает
{/* Темы (категории) — навигатор */} {categories.length > 0 && (

Темы

{categories.map(cat => { const colorMap = { emerald: 'bg-emerald-50 dark:bg-emerald-950 border-emerald-200 dark:border-emerald-800 text-emerald-700 dark:text-emerald-300 hover:border-emerald-400', red: 'bg-red-50 dark:bg-red-950 border-red-200 dark:border-red-800 text-red-700 dark:text-red-300 hover:border-red-400', amber: 'bg-amber-50 dark:bg-amber-950 border-amber-200 dark:border-amber-800 text-amber-700 dark:text-amber-300 hover:border-amber-400', blue: 'bg-blue-50 dark:bg-blue-950 border-blue-200 dark:border-blue-800 text-blue-700 dark:text-blue-300 hover:border-blue-400', }; const cls = colorMap[cat.color] || colorMap.emerald; return ( {cat.icon} {cat.name} {cat.description} ); })}
)} {/* HERO ARTICLE — главная статья сверху */} {hero && (
)} {/* СВЕЖИЕ — сразу после главной статьи (важнее всего для возвращающегося читателя) */} {recent.length > 0 && (
)} {/* СЕРИИ */} {series.length > 0 && (
)} {/* ЗЕРО — full-width баннер с самим персонажем и его лентой */}
{/* КАТЕГОРИЙНЫЕ РЯДЫ — порядок и состав из БД через sort_order */} {categories.map(cat => ( (byCategory[cat.slug] || []).length > 0 && (
) ))} {/* ПОПУЛЯРНОЕ ЗА МЕСЯЦ */} {popular.length > 0 && (
)} {!hasAnyArticles && (

Скоро здесь появятся первые статьи. ИИ уже работает над ними.

)} {/* МЕТА: что прямо сейчас + стата + заметки (вынесены ниже основного контента) */}
{notes.length > 0 && (
)} {/* TAGS CLOUD — в самом низу */} {tags.length > 0 && (

Все теги

{tags.map(t => ( #{t.tag} ({t.cnt}) ))}
)}