// Dashboard. Welcome + stat cards + quick actions + recent posts grid.
function Dashboard({ user, org, data, onNavigate, onApprove }) {
const { Button, Card, Badge, SectionHead } = window.UI;
const I = window.Icons;
const { SlideThumb } = window.Carousel;
const posts = data.posts || [];
const pending = posts.filter(p => p.status === 'pending');
const stats = [
{ kicker: 'готовы', v: posts.filter(p => p.status === 'ready').length, sub: 'к публикации сейчас', icon: 'Check', tint: 'mint' },
{ kicker: 'ждут одобрения', v: pending.length, sub: 'нужен ваш ок', icon: 'ClockApprove', tint: 'peach' },
{ kicker: 'черновики', v: posts.filter(p => p.status === 'draft').length, sub: 'в работе', icon: 'Edit', tint: 'sky' },
{ kicker: 'источники', v: (data.sources || []).filter(s => s.enabled).length, sub: 'активны', icon: 'Plug', tint: 'lavender' },
];
const hour = new Date().getHours();
const greet = hour < 6 ? 'Доброй ночи' : hour < 12 ? 'Доброе утро' : hour < 18 ? 'Добрый день' : 'Добрый вечер';
return (
{/* Hero */}
{/* decorative doodles */}
{greet}, {user.name || user.email.split('@')[0]}
Сегодня в
{org.name}
42 свежих статьи за сутки. 7 тем уже ждут вашего согласия.
{/* Stats */}
{stats.map((s, i) => {
const Icon = I[s.icon];
const tintBg = {
mint: 'bg-mint-soft text-mint-ink',
peach: 'bg-peach-soft text-peach-ink',
sky: 'bg-sky-soft text-sky-ink',
lavender: 'bg-lavender-soft text-lavender-ink',
lemon: 'bg-lemon-soft text-lemon-ink',
rose: 'bg-rose-soft text-rose-ink',
}[s.tint] || 'bg-ink-100 text-ink-700';
const cardTintBg = {
mint: 'bg-mint-soft/40',
peach: 'bg-peach-soft/50',
sky: 'bg-sky-soft/40',
lavender: 'bg-lavender-soft/50',
lemon: 'bg-lemon-soft/50',
}[s.tint] || 'bg-white';
return (
);
})}
{/* Quick actions row */}
} title="Сгенерировать пост" sub="Из источников, идей или своей темы" onClick={() => onNavigate('generate')} tint="violet"/>
} title="Добавить идею" sub="Текст, ссылка или голосовое" onClick={() => onNavigate('ideas')} tint="lemon"/>
} title="Подключить источник" sub="RSS, Telegram, сайт, файлы" onClick={() => onNavigate('sources')} tint="mint"/>
{/* Pending approval — only shown when there are pending posts */}
{pending.length > 0 && (
ждут одобрения
{pending.length} {pending.length === 1 ? 'пост готов к проверке' : 'постов готовы к проверке'}
Авто-одобрение выключено
{pending.map((p) => (
{window.NetworkChip && }
{p.title}
публикация {p.approveAt || 'после одобрения'}
))}
)}
{/* Recent posts */}
} onClick={() => onNavigate('posts')}>Все посты}
/>
{posts.filter(p => p.status !== 'pending').slice(0, 8).map((p) => (
))}
{/* Footer note */}
Telegram-бот
Получайте «пост готов» прямо в личку
@omneee_bot — подключите за 30 секунд.
);
}
function QuickAction({ icon, title, sub, onClick, tint = 'violet' }) {
const tintMap = {
violet: { bg: 'bg-violet-soft/55', icon: 'bg-violet text-white', ring: 'hover:border-violet/30' },
lemon: { bg: 'bg-lemon-soft/55', icon: 'bg-lemon-soft text-lemon-ink', ring: 'hover:border-lemon-ink/20' },
mint: { bg: 'bg-mint-soft/55', icon: 'bg-mint-soft text-mint-ink', ring: 'hover:border-mint-ink/20' },
peach: { bg: 'bg-peach-soft/55', icon: 'bg-peach-soft text-peach-ink', ring: 'hover:border-peach-ink/20' },
sky: { bg: 'bg-sky-soft/55', icon: 'bg-sky-soft text-sky-ink', ring: 'hover:border-sky-ink/20' },
}[tint] || { bg: 'bg-white', icon: 'bg-ink-100 text-ink-700', ring: 'hover:border-ink-300' };
return (
);
}
window.Screens = window.Screens || {};
window.Screens.Dashboard = Dashboard;