user testing and fixing minor issues
This commit is contained in:
@@ -382,28 +382,50 @@
|
||||
rewards.filter((r) => r.memberId === memberId && (r.date?.slice(0, 10) || r.date) >= weekStart)
|
||||
);
|
||||
|
||||
let allTimeCash = $derived.by(() =>
|
||||
completions
|
||||
.filter((c) => c.memberId === memberId)
|
||||
.reduce((sum, c) => {
|
||||
const chore = assigned.find((a) => a.id === c.assignedChoreId);
|
||||
return sum + (chore?.type === 'money' ? Number(chore.value) : 0);
|
||||
}, 0) +
|
||||
rewards
|
||||
.filter((r) => r.memberId === memberId && r.rewardType === 'cash' && r.status === 'claimed')
|
||||
.reduce((sum, r) => sum + Number(r.value), 0)
|
||||
// Money-type todos auto-create a matching cash reward when completed (see
|
||||
// completions.toggle). Those rewards are already counted via the chore
|
||||
// completions below, so skip any claimed reward that a completion linked to
|
||||
// (via rewardId) to avoid double-counting the same earning event.
|
||||
let autoRewardIds = $derived(
|
||||
new Set(completions.map((c) => (c as any).rewardId).filter((id) => !!id))
|
||||
);
|
||||
|
||||
let allTimePoints = $derived.by(() =>
|
||||
completions
|
||||
.filter((c) => c.memberId === memberId)
|
||||
.reduce((sum, c) => {
|
||||
const chore = assigned.find((a) => a.id === c.assignedChoreId);
|
||||
return sum + (chore?.type === 'points' ? Number(chore.value) : 0);
|
||||
}, 0) +
|
||||
rewards
|
||||
.filter((r) => r.memberId === memberId && r.rewardType === 'points' && r.status === 'claimed')
|
||||
.reduce((sum, r) => sum + Number(r.value), 0)
|
||||
let allTimeCash = $derived.by(
|
||||
() =>
|
||||
completions
|
||||
.filter((c) => c.memberId === memberId)
|
||||
.reduce((sum, c) => {
|
||||
const chore = assigned.find((a) => a.id === c.assignedChoreId);
|
||||
return sum + (chore?.type === 'money' ? Number(chore.value) : 0);
|
||||
}, 0) +
|
||||
rewards
|
||||
.filter(
|
||||
(r) =>
|
||||
r.memberId === memberId &&
|
||||
r.rewardType === 'cash' &&
|
||||
r.status === 'claimed' &&
|
||||
!autoRewardIds.has(r.id)
|
||||
)
|
||||
.reduce((sum, r) => sum + Number(r.value), 0)
|
||||
);
|
||||
|
||||
let allTimePoints = $derived.by(
|
||||
() =>
|
||||
completions
|
||||
.filter((c) => c.memberId === memberId)
|
||||
.reduce((sum, c) => {
|
||||
const chore = assigned.find((a) => a.id === c.assignedChoreId);
|
||||
return sum + (chore?.type === 'points' ? Number(chore.value) : 0);
|
||||
}, 0) +
|
||||
rewards
|
||||
.filter(
|
||||
(r) =>
|
||||
r.memberId === memberId &&
|
||||
r.rewardType === 'points' &&
|
||||
r.status === 'claimed' &&
|
||||
!autoRewardIds.has(r.id)
|
||||
)
|
||||
.reduce((sum, r) => sum + Number(r.value), 0)
|
||||
);
|
||||
|
||||
// Week-to-date totals from chore completions (not rewards — rewards are created at EOW)
|
||||
@@ -1386,17 +1408,14 @@
|
||||
<div class="wallet">
|
||||
<div class="wallet-top">
|
||||
<span class="wallet-lbl">{@html walletIcon} Wallet</span>
|
||||
</div>
|
||||
|
||||
<!-- Lifetime earnings (everything earned + claimed), one-shot totals -->
|
||||
<div class="lifetime">
|
||||
<div class="life-cell life-cash">
|
||||
<span class="life-num">£{allTimeCash.toFixed(2)}</span>
|
||||
<span class="life-lbl">earned all time</span>
|
||||
</div>
|
||||
<div class="life-cell life-pts">
|
||||
<span class="life-num">{allTimePoints.toLocaleString()}</span>
|
||||
<span class="life-lbl">points accrued</span>
|
||||
<!-- Lifetime earnings (everything earned + claimed), one-shot totals -->
|
||||
<div class="life-badges">
|
||||
<span class="life-badge life-cash"
|
||||
>£{allTimeCash.toFixed(2)} <i>all time</i></span
|
||||
>
|
||||
<span class="life-badge life-pts"
|
||||
>{allTimePoints.toLocaleString()} <i>pts</i></span
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -2431,18 +2450,31 @@
|
||||
vertical-align: -0.15em;
|
||||
margin-right: 0.3em;
|
||||
}
|
||||
.lifetime {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 0.75rem;
|
||||
margin: 0.75rem 0 1rem;
|
||||
}
|
||||
.life-cell {
|
||||
.life-badges {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.1rem;
|
||||
padding: 0.85rem 1rem;
|
||||
border-radius: 12px;
|
||||
align-items: center;
|
||||
gap: 0.4rem;
|
||||
flex-wrap: wrap;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
.life-badge {
|
||||
display: inline-flex;
|
||||
align-items: baseline;
|
||||
gap: 0.3rem;
|
||||
font-size: 0.8rem;
|
||||
font-weight: 800;
|
||||
padding: 3px 11px;
|
||||
border-radius: 999px;
|
||||
color: #fff;
|
||||
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
.life-badge i {
|
||||
font-style: normal;
|
||||
font-size: 0.65rem;
|
||||
font-weight: 700;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.05em;
|
||||
opacity: 0.9;
|
||||
}
|
||||
.life-cash {
|
||||
background: linear-gradient(135deg, #059669, #10b981);
|
||||
@@ -2450,20 +2482,6 @@
|
||||
.life-pts {
|
||||
background: linear-gradient(135deg, #7c3aed, #a855f7);
|
||||
}
|
||||
.life-num {
|
||||
font-size: 1.7rem;
|
||||
font-weight: 900;
|
||||
color: #fff;
|
||||
line-height: 1;
|
||||
letter-spacing: -0.01em;
|
||||
}
|
||||
.life-lbl {
|
||||
font-size: 0.68rem;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.06em;
|
||||
color: rgba(255, 255, 255, 0.9);
|
||||
margin-top: 0.15rem;
|
||||
}
|
||||
.wallet-sub {
|
||||
border-top: 1px solid #eef0f2;
|
||||
padding-top: 0.6rem;
|
||||
|
||||
Reference in New Issue
Block a user