feat: журнальная главная, страница Зеро, TG-баннер, stats, auto-publish UI

- Журнальная главная: hero, CategoryRow, PopularBlock, RecentBlock (Сегодня/Вчера/Неделя)
- ArticleCard: 3 размера (hero/regular/compact), цветной badge без дублей тегов
- ArticleCoverSVG: 6 брендовых палитр, аватар Зеро в углу вместо #ZEROPOST
- /about/zero: страница персонажа с галереей 8 поз
- Footer: TG-баннер с аватаром Зеро на каждой странице
- Конец статьи: блок «Понравилась? → Подписаться на канал»
- ChannelEditor: 4 вкладки (Настройки/Расписание/Авто-публикация/Ручная)
- AutoPublishTab: toggle, категории, delay, template, live preview
- ArticlePicker: typeahead с was_sent_to_channel / next_scheduled_at флагами
- /admin/channels/[id]/stats: график роста подписчиков (recharts)
- Dashboard: блок TG-статистики (подписчики, delta 24h/7d, постов)
- Header: упрощён до 2 пунктов desktop + расширенное мобильное меню
- AutogenPanel: корректные time-picker'ы, calcNextRun с учётом last_run_at
This commit is contained in:
Nik (Claude)
2026-06-07 14:04:09 +03:00
parent 6f7c47a258
commit 334b2f51df
32 changed files with 2492 additions and 353 deletions
+23
View File
@@ -0,0 +1,23 @@
import ArticleCard from './ArticleCard';
import { Flame } from 'lucide-react';
/**
* Блок «Популярное за неделю/месяц».
* Не рендерится если пусто.
*/
export default function PopularBlock({ articles }) {
if (!articles || articles.length === 0) return null;
return (
<section className="container-wide pb-10">
<div className="flex items-center gap-2 mb-5 pb-3 border-b border-orange-200 dark:border-orange-900">
<Flame className="w-5 h-5 text-orange-500" />
<h2 className="text-xl sm:text-2xl font-bold text-orange-600 dark:text-orange-400">
Популярное за месяц
</h2>
</div>
<div className="grid sm:grid-cols-2 lg:grid-cols-3 gap-5">
{articles.map(a => <ArticleCard key={a.id} article={a} />)}
</div>
</section>
);
}