update stats

This commit is contained in:
JCEEE
2026-09-21 11:09:09 +01:00
parent 67b5eff06b
commit 0fed19461e
+70
View File
@@ -107,6 +107,39 @@
}
return map;
});
// ─── All-time per-member stats ───
let allTimeByMember = $derived.by(() => {
const map = new Map<string, { points: number; cash: number; chores: number }>();
for (const m of trend as any[]) {
const pts = (m.weeks || []).reduce((s: number, w: any) => s + (Number(w.points) || 0), 0);
const cash = (m.weeks || []).reduce((s: number, w: any) => s + (Number(w.cash) || 0), 0);
const chores = (m.weeks || []).reduce((s: number, w: any) => s + (Number(w.chores) || 0), 0);
map.set(m.memberId, { points: pts, cash, chores });
}
return map;
});
let goalsAllTimeByMember = $derived.by(() => {
const pmIds = new Set(bonusConfigs.filter((c: any) => c.isPocketMoney).map((c: any) => c.id));
const map = new Map<string, { count: number; names: string[] }>();
for (const r of rewards as any[]) {
if (!r.bonusConfigId || pmIds.has(r.bonusConfigId)) continue;
const cfg = bonusConfigs.find((c: any) => c.id === r.bonusConfigId);
const entry = map.get(r.memberId) || { count: 0, names: [] };
entry.count++;
if (cfg?.name && !entry.names.includes(cfg.name)) entry.names.push(cfg.name);
map.set(r.memberId, entry);
}
return map;
});
let pocketMoneyAllTimeByMember = $derived.by(() => {
const pmIds = new Set(bonusConfigs.filter((c: any) => c.isPocketMoney).map((c: any) => c.id));
const map = new Map<string, number>();
for (const r of rewards as any[]) {
if (!r.bonusConfigId || !pmIds.has(r.bonusConfigId)) continue;
map.set(r.memberId, (map.get(r.memberId) || 0) + 1);
}
return map;
});
// ─── Trend chart window: show current month, expand a month at a time up to 3. ───
let trend = $derived.by(() => {
@@ -413,6 +446,8 @@
{@const tdPct = tdTotal > 0 ? Math.min(100, Math.round((tdDone / tdTotal) * 100)) : 0}
{@const sc = overallRateFor(s.memberId)}
{@const goals = goalsByMember.get(s.memberId)}
{@const goalsAll = goalsAllTimeByMember.get(s.memberId)}
{@const at = allTimeByMember.get(s.memberId)}
<div class="column col-member" style="--mc: {s.memberColor}">
<div class="member-head">
<span class="dot" style="background:{s.memberColor}"></span>
@@ -439,6 +474,7 @@
</div>
</div>
<div class="member-stats">
<div class="stat-group-lbl">This week</div>
<div class="stat-row">
<span class="stat-lbl">Points</span>
<span class="stat-val pts">{s.pointsEarned}</span>
@@ -461,6 +497,29 @@
<span class="stat-lbl">Pocket Money</span>
<span class="stat-val pm">{pocketMoneyByMember.get(s.memberId) ?? 0}</span>
</div>
<div class="stat-group-lbl">All time</div>
<div class="stat-row">
<span class="stat-lbl">Points</span>
<span class="stat-val pts">{at?.points ?? s.pointsEarned}</span>
</div>
<div class="stat-row">
<span class="stat-lbl">Cash</span>
<span class="stat-val cash">£{Number(at?.cash ?? s.moneyEarned ?? 0).toFixed(2)}</span>
</div>
<div class="stat-row">
<span class="stat-lbl">Done</span>
<span class="stat-val">{sc.done}/{sc.total}</span>
</div>
<div class="stat-row">
<span class="stat-lbl">Goals 🎉</span>
<span class="stat-val goals" title={goalsAll?.names.join(' · ')}
>{goalsAll?.count ?? 0}</span
>
</div>
<div class="stat-row">
<span class="stat-lbl">Pocket Money</span>
<span class="stat-val pm">{pocketMoneyAllTimeByMember.get(s.memberId) ?? 0}</span>
</div>
</div>
</div>
{/each}
@@ -766,6 +825,17 @@
align-items: center;
font-size: 0.8rem;
}
.stat-group-lbl {
font-size: 0.65rem;
font-weight: 800;
text-transform: uppercase;
letter-spacing: 0.07em;
color: #9ca3af;
margin-top: 0.35rem;
}
.stat-group-lbl:first-child {
margin-top: 0;
}
.stat-lbl {
color: #6b7280;
font-weight: 500;