From d1ebae6fa2280898414e01a918871675c079a66e Mon Sep 17 00:00:00 2001 From: tempus2016 Date: Thu, 15 Oct 2026 09:01:09 +0000 Subject: [PATCH] fix(rewards): measure reward progress against the selected child (#1068) With no child_id pinned, the progress bar and points figure used the first child's points for every child, so switching tabs changed the balance and the claim button but not the bar. Both render paths now use the pinned or selected child, the same child the affordability check already uses. --- .../taskmate/www/taskmate-rewards-card.js | 16 +++----- tests/frontend/taskmate-rewards-card.test.cjs | 39 +++++++++++++++++++ 2 files changed, 45 insertions(+), 10 deletions(-) diff --git a/custom_components/taskmate/www/taskmate-rewards-card.js b/custom_components/taskmate/www/taskmate-rewards-card.js index 77649839..b919dbde 100644 --- a/custom_components/taskmate/www/taskmate-rewards-card.js +++ b/custom_components/taskmate/www/taskmate-rewards-card.js @@ -1398,11 +1398,9 @@ class TaskMateRewardsCard extends LitElement { if (enablePoolMode) { // Pool mode: show this child's allocation for this reward currentStars = childId ? (poolAllocations[childId] || 0) : 0; - } else if (this.config.child_id) { - const filteredChild = children.find(c => c.id === this.config.child_id); - currentStars = filteredChild ? (filteredChild.points || 0) : 0; - } else if (relevantChildren.length > 0) { - currentStars = relevantChildren[0].points || 0; + } else { + // The pinned or selected child, so switching tabs moves the bar (#1068) + currentStars = relevantChild ? (relevantChild.points || 0) : 0; } } @@ -1899,11 +1897,9 @@ class TaskMateRewardsCard extends LitElement { }); } else if (enablePoolMode) { currentStars = childId ? (poolAllocations[childId] || 0) : 0; - } else if (this.config.child_id) { - const fc = children.find(c => c.id === this.config.child_id); - currentStars = fc ? (fc.points || 0) : 0; - } else if (relevantChildren.length > 0) { - currentStars = relevantChildren[0].points || 0; + } else { + // The pinned or selected child, so switching tabs moves the bar (#1068) + currentStars = relevantChild ? (relevantChild.points || 0) : 0; } const percentage = displayCost > 0 ? Math.min((currentStars / displayCost) * 100, 100) : 0; diff --git a/tests/frontend/taskmate-rewards-card.test.cjs b/tests/frontend/taskmate-rewards-card.test.cjs index bdd68051..f849bc8f 100644 --- a/tests/frontend/taskmate-rewards-card.test.cjs +++ b/tests/frontend/taskmate-rewards-card.test.cjs @@ -165,3 +165,42 @@ test("the classic Redeem button is disabled when the child cannot afford it", () assert.equal(claim.disabled, true); assert.match(claim.attrs, /cant-afford/); }); + +// ── Progress follows the selected child ────────────────────────────────── +// With no child_id pinned, the progress bar measured every child against the +// first child's points, so switching tabs changed the balance and the claim +// button but not the bar (#1068). + +function progress(rendered) { + const classic = rendered.classic.all(/class="progress-fill" style="width: ([\d.]+)%"/g).map(Number); + const designed = rendered.designed.all(/
{ + const children = [ + { id: "kid1", name: "Kid 1", points: 30 }, + { id: "kid2", name: "Kid 2", points: 10 }, + ]; + const reward = { id: "film", name: "Film night", cost: 40, is_jackpot: false, assigned_to: [] }; + + const first = renderRow(makeCard({ selectedChildId: "kid1" }), reward, children); + const second = renderRow(makeCard({ selectedChildId: "kid2" }), reward, children); + + assert.deepEqual(progress(first), { classic: [75], designed: [75] }); + assert.deepEqual(progress(second), { classic: [25], designed: [25] }); + assert.match(first.classic.markup, /30\/40/); + assert.match(second.classic.markup, /10\/40/); +}); + +test("a card pinned to a child still shows that child's progress", () => { + const children = [ + { id: "kid1", name: "Kid 1", points: 30 }, + { id: "kid2", name: "Kid 2", points: 10 }, + ]; + const reward = { id: "film", name: "Film night", cost: 40, is_jackpot: false, assigned_to: [] }; + + const pinned = renderRow(makeCard({ config: { child_id: "kid2" } }), reward, children); + + assert.deepEqual(progress(pinned), { classic: [25], designed: [25] }); +});