import React from 'react'; import Icon from './Icon'; /** * Лента истории публикации проекта (синий wow-стиль Рублокса). * Показывает события: публикация → блокировка → возврат и т.п. * * Premoderation убрана (RUBLOX_SMART_FEED_PLAN.md). Новые типы событий: * published, submitted_review, blocked, unblocked, restored_feed. * Старые типы (submitted, approved_rank*, needs_changes, rejected) * оставлены — они есть в истории игр, опубликованных до перехода. * * Props: * history — массив событий [{ event_type, actor_user_id, comment, * age_rating, created_at, ... }] */ // Самописные inline-SVG-иконки вместо эмодзи (правило проекта). const EV_ICONS = { upload: , check: , search: <>, pencil: , cross: , lock: <>, block: <>, }; const EVENT_META = { // --- Новые события умной ленты --- published: { ico: 'check', label: 'Опубликовано в ленте', color: '#10b981', bg: 'linear-gradient(135deg, #10b981 0%, #0f9d56 100%)', glow: 'rgba(16, 185, 129, 0.35)', }, submitted_review: { ico: 'search', label: 'Отправлено на быструю проверку', color: '#f59e0b', bg: 'linear-gradient(135deg, #f59e0b 0%, #d97706 100%)', glow: 'rgba(245, 158, 11, 0.35)', }, blocked: { ico: 'block', label: 'Заблокировано администрацией', color: '#ef4444', bg: 'linear-gradient(135deg, #ff6f7a 0%, #c0303f 100%)', glow: 'rgba(239, 68, 68, 0.35)', }, unblocked: { ico: 'check', label: 'Разблокировано', color: '#10b981', bg: 'linear-gradient(135deg, #10b981 0%, #0f9d56 100%)', glow: 'rgba(16, 185, 129, 0.35)', }, restored_feed: { ico: 'check', label: 'Возвращено в ленту', color: '#10b981', bg: 'linear-gradient(135deg, #10b981 0%, #0f9d56 100%)', glow: 'rgba(16, 185, 129, 0.35)', }, // --- Старые события (до перехода на умную ленту) --- submitted: { ico: 'upload', label: 'Отправлено на модерацию', color: '#f59e0b', bg: 'linear-gradient(135deg, #f59e0b 0%, #d97706 100%)', glow: 'rgba(245, 158, 11, 0.35)', }, approved_rank1: { ico: 'check', label: 'Одобрено (главная лента)', color: '#ef4444', bg: 'linear-gradient(135deg, #ec4899 0%, #ef4444 50%, #f59e0b 100%)', glow: 'rgba(239, 68, 68, 0.40)', }, approved_rank2: { ico: 'check', label: 'Одобрено (только профиль)', color: '#10b981', bg: 'linear-gradient(135deg, #10b981 0%, #0f9d56 100%)', glow: 'rgba(16, 185, 129, 0.35)', }, needs_changes: { ico: 'pencil', label: 'Возвращено на доработку', color: '#f97316', bg: 'linear-gradient(135deg, #f97316 0%, #ea580c 100%)', glow: 'rgba(249, 115, 22, 0.35)', }, rejected: { ico: 'cross', label: 'Отклонено', color: '#ef4444', bg: 'linear-gradient(135deg, #ff6f7a 0%, #c0303f 100%)', glow: 'rgba(239, 68, 68, 0.35)', }, unpublished: { ico: 'lock', label: 'Снято с публикации', color: '#94a3b8', bg: 'linear-gradient(135deg, #94a3b8 0%, #64748b 100%)', glow: 'rgba(100, 116, 139, 0.30)', }, }; const ModerationHistory = ({ history, compact = false }) => { if (!history || history.length === 0) { return (
История публикации пуста.
); } return (
История публикации ({history.length})
{/* Вертикальная линия */}
{history.map((ev, i) => { const meta = EVENT_META[ev.event_type] || EVENT_META.submitted; return (
{/* Кружок с иконкой */}
{EV_ICONS[meta.ico] || EV_ICONS.upload}
{/* Заголовок события */}
{meta.label}
{/* Метаданные */}
{ev.created_at} {ev.age_rating && ( {ev.age_rating}+ )} {ev.actor_user_id && ( #{ev.actor_user_id} )}
{/* Комментарий модератора */} {ev.comment && (
{ev.comment}
)}
); })}
); }; const pillStyle = (color) => ({ display: 'inline-flex', alignItems: 'center', background: `${color}22`, border: `1px solid ${color}55`, color: color, padding: '1px 8px', borderRadius: 999, fontSize: 10, fontWeight: 800, letterSpacing: 0.2, }); export default ModerationHistory;