// 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 && (
)}
))}
);
};