// Stats — графики активности + достижения + распределение по категориям // Changes from the design prototype: // - weeks array computed from history sent_at in api.js (was static demo) // - avg_response hidden when backend doesn't expose it // - achievements computed from real streak/best_streak/total/days // - category rows use `_default` meta for unknown keys window.StatsScreen = function StatsScreen({ data }) { const D = data; const totalCat = Object.values(D.stats.by_category).reduce((a, b) => a + b, 0); const hasAvg = D.stats.avg_response != null; const maxWeek = Math.max(1, ...D.stats.weeks); return (

Статистика пары

За всё время · с {D.pair.started_at}
Серия
{D.pair.current_streak}дней
🔥 рекорд {D.pair.best_streak}
Всего вопросов
{D.pair.total_questions}
+{D.stats.last_week} за неделю
Оба ответили
{D.pair.answer_rate}%
{D.pair.both_answered} / {D.pair.total_questions}
Дней вместе
{D.pair.days_together}
{hasAvg ? `${D.stats.avg_response} мин средн. ответ` : 'с первого вопроса'}

Активность за 12 недель

раскрытые ответы
{D.stats.weeks.map((w, i) => (
{w > 0 && {w}}
{i === 11 ? 'сейчас' : `-${11 - i}`}
))}

По категориям

{totalCat === 0 ? (
Пока нет раскрытых ответов
) : (
{Object.entries(D.stats.by_category) .sort((a, b) => b[1] - a[1]) .map(([k, v]) => { const cat = D.cats[k] || D.cats._default; const pct = Math.round(v * 100 / totalCat); return (
{cat.emoji} {cat.ru} {v} · {pct}%
); })}
)}

Достижения

{D.achievements.map(a => (
{a.icon}
{a.name}
{a.desc}
{!a.got && a.progress != null && a.progress > 0 && (
)}
))}
); };