Commit f8f126d
authored
feat(rewards): benefits preview uses Tag for available count (#30196)
<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until this PR meets the canonical
Definition of Ready For Review in `docs/readme/ready-for-review.md`.
In short: the template must be materially complete (not just section
titles
present), all status checks must be currently passing, and the only
expected
follow-up commits must be reviewer-driven.
-->
## **Description**
> **Section header spacing alignment:**
[`CampaignsPreview.tsx`](app/components/UI/Rewards/components/Campaigns/CampaignsPreview.tsx)
— the campaigns preview **header row** now uses **`gap-1`** instead of
**`gap-2`** between the title row items (spinner when shown, heading,
chevron), matching the **Benefits** preview header spacing on the
Rewards dashboard.
The Rewards dashboard **Benefits** preview header previously used a
numeric `BadgeCount` beside the section title. This change replaces it
with a design-system **`Tag`** (`TagSeverity.Neutral`) that shows how
many benefits are available using the localized string
`rewards.benefits.available_count` (e.g. `%{count} available` in
English). Counts above 99 display as `99+`.
The header row is full width with **`justifyContent: space-between`**:
the title and chevron stay on the leading side; the tag sits on the
**trailing** edge so it matches the intended layout. Spacing uses
`gap-1` between the title and chevron. The empty-state header no longer
renders a redundant null badge slot.
**Motivation:** Align with design (muted pill copy and alignment) and
keep copy in i18n for the translation pipeline (English source string
only in `en.json`).
**Automated tests:** `yarn jest
app/components/UI/Rewards/components/Benefits/BenefitsPreview.test.tsx`
## **Changelog**
CHANGELOG entry: Updated the Rewards benefits preview header to show how
many benefits are available using a tag label next to the section title;
aligned campaigns preview section header spacing with the benefits
preview (`gap-1`).
## **Related issues**
Fixes:
## **Manual testing steps**
```gherkin
Feature: Rewards benefits preview header
Scenario: User sees benefits count when they have benefits
Given the user is opted into Rewards and the benefits API returns at least one benefit
When user opens the Rewards dashboard (home) and scrolls to the Benefits preview
Then a neutral tag shows the correct count and available wording for the current locale
And the tag is aligned to the far right of the header row with the title and chevron grouped on the left
And tapping the header row still navigates to the full benefits view
Scenario: User has no benefits
Given the user has no benefits in the list
When user opens the Rewards dashboard and views the Benefits preview
Then the count tag is not shown and the empty state behaves as before
Feature: Rewards campaigns preview header spacing
Scenario: User compares section headers on Rewards home
Given the user is on the Rewards dashboard home tab
When user views the Campaigns preview section header
Then the title row uses gap-1 between the title row elements, matching the Benefits preview header spacing
```
## **Screenshots/Recordings**
### **Before**
Numeric badge style (`BadgeCount`) adjacent to the Benefits title
(previous implementation).
### **After**
<img width="413" height="827" alt="image"
src="https://github.com/user-attachments/assets/bd00ee97-2ae3-4ccb-b924-51ba6d0ca677"
/>
Neutral `Tag` with “{count} available” (per locale), title + chevron on
the left, tag aligned to the trailing edge. (Screenshot also attached in
an earlier PR update.)
## **Pre-merge author checklist**
<!--
Every checklist item must be consciously assessed before marking this PR
as
"Ready for review". A checked box means you deliberately considered that
responsibility, not that you literally performed every action listed.
Unchecked boxes are ambiguous: they are not an implicit "N/A" and they
are not
a silent "skip". See `docs/readme/ready-for-review.md` for the full
checklist
semantics.
-->
- [x] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [x] I've included tests if applicable
- [x] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I've applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.
#### Performance checks (if applicable)
- [ ] I've tested on Android
- Ideally on a mid-range device; emulator is acceptable
- [ ] I've tested with a power user scenario
- Use these [power-user
SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93)
to import wallets with many accounts and tokens
- [ ] I've instrumented key operations with Sentry traces for production
performance metrics
- See [`trace()`](/app/util/trace.ts) for usage and
[`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274)
for an example
For performance guidelines and tooling, see the [Performance
Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers).
## **Pre-merge reviewer checklist**
<!--
Reviewer checklist items follow the same semantics as the author
checklist: an
unchecked box is ambiguous, a checked box means the reviewer consciously
assessed that responsibility. See `docs/readme/ready-for-review.md`.
-->
- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> **Low Risk**
> Low risk UI/i18n change with unit test updates; primary risk is minor
layout/regression in rewards preview headers and count formatting around
the 99/99+ boundary.
>
> **Overview**
> The Benefits preview header now replaces the numeric `BadgeCount` with
a neutral design-system `Tag` that shows a localized
`rewards.benefits.available_count` label (capped to `99+`), and adjusts
header layout to keep the title+chevron grouped left with the tag
right-aligned.
>
> Campaigns preview header spacing is tightened (`gap-1`), and tests
were expanded to cover the new benefits count behavior (including empty
state and 99/99+ cases) plus treating `undefined` campaigns as an empty
list. Adds the new English i18n key `rewards.benefits.available_count`.
>
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
5ece706. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->1 parent 714d6b6 commit f8f126d
5 files changed
Lines changed: 140 additions & 23 deletions
File tree
- app/components/UI/Rewards/components
- Benefits
- Campaigns
- locales/languages
Lines changed: 92 additions & 4 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
12 | 12 | | |
13 | 13 | | |
14 | 14 | | |
15 | | - | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
16 | 23 | | |
17 | 24 | | |
18 | 25 | | |
| |||
42 | 49 | | |
43 | 50 | | |
44 | 51 | | |
45 | | - | |
| 52 | + | |
| 53 | + | |
46 | 54 | | |
47 | 55 | | |
48 | 56 | | |
| |||
126 | 134 | | |
127 | 135 | | |
128 | 136 | | |
129 | | - | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
130 | 141 | | |
131 | 142 | | |
132 | 143 | | |
| |||
169 | 180 | | |
170 | 181 | | |
171 | 182 | | |
172 | | - | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
| 192 | + | |
| 193 | + | |
| 194 | + | |
| 195 | + | |
| 196 | + | |
173 | 197 | | |
174 | 198 | | |
175 | 199 | | |
| |||
225 | 249 | | |
226 | 250 | | |
227 | 251 | | |
| 252 | + | |
| 253 | + | |
| 254 | + | |
| 255 | + | |
| 256 | + | |
| 257 | + | |
| 258 | + | |
| 259 | + | |
| 260 | + | |
| 261 | + | |
| 262 | + | |
| 263 | + | |
| 264 | + | |
| 265 | + | |
| 266 | + | |
| 267 | + | |
| 268 | + | |
| 269 | + | |
| 270 | + | |
| 271 | + | |
| 272 | + | |
| 273 | + | |
| 274 | + | |
| 275 | + | |
| 276 | + | |
| 277 | + | |
| 278 | + | |
| 279 | + | |
| 280 | + | |
| 281 | + | |
| 282 | + | |
| 283 | + | |
| 284 | + | |
| 285 | + | |
| 286 | + | |
| 287 | + | |
| 288 | + | |
| 289 | + | |
| 290 | + | |
| 291 | + | |
| 292 | + | |
| 293 | + | |
| 294 | + | |
| 295 | + | |
| 296 | + | |
| 297 | + | |
| 298 | + | |
| 299 | + | |
| 300 | + | |
| 301 | + | |
| 302 | + | |
| 303 | + | |
| 304 | + | |
| 305 | + | |
| 306 | + | |
| 307 | + | |
| 308 | + | |
| 309 | + | |
| 310 | + | |
| 311 | + | |
| 312 | + | |
| 313 | + | |
| 314 | + | |
| 315 | + | |
228 | 316 | | |
229 | 317 | | |
230 | 318 | | |
| |||
Lines changed: 31 additions & 17 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | | - | |
3 | | - | |
4 | 2 | | |
5 | 3 | | |
6 | | - | |
7 | 4 | | |
| 5 | + | |
8 | 6 | | |
| 7 | + | |
9 | 8 | | |
10 | 9 | | |
11 | 10 | | |
| 11 | + | |
| 12 | + | |
12 | 13 | | |
13 | 14 | | |
14 | 15 | | |
| |||
41 | 42 | | |
42 | 43 | | |
43 | 44 | | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
44 | 48 | | |
45 | 49 | | |
46 | | - | |
47 | | - | |
48 | | - | |
49 | | - | |
50 | | - | |
51 | | - | |
52 | | - | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
53 | 57 | | |
54 | 58 | | |
55 | 59 | | |
56 | 60 | | |
57 | 61 | | |
58 | 62 | | |
59 | 63 | | |
60 | | - | |
| 64 | + | |
| 65 | + | |
61 | 66 | | |
62 | | - | |
63 | | - | |
64 | | - | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
65 | 81 | | |
66 | | - | |
67 | 82 | | |
68 | 83 | | |
69 | 84 | | |
70 | 85 | | |
71 | 86 | | |
72 | 87 | | |
73 | | - | |
| 88 | + | |
74 | 89 | | |
75 | 90 | | |
76 | 91 | | |
77 | 92 | | |
78 | | - | |
79 | 93 | | |
80 | 94 | | |
81 | 95 | | |
| |||
Lines changed: 14 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
129 | 129 | | |
130 | 130 | | |
131 | 131 | | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
132 | 146 | | |
133 | 147 | | |
134 | 148 | | |
| |||
Lines changed: 1 addition & 1 deletion
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
57 | 57 | | |
58 | 58 | | |
59 | 59 | | |
60 | | - | |
| 60 | + | |
61 | 61 | | |
62 | 62 | | |
63 | 63 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
8598 | 8598 | | |
8599 | 8599 | | |
8600 | 8600 | | |
8601 | | - | |
| 8601 | + | |
| 8602 | + | |
8602 | 8603 | | |
8603 | 8604 | | |
8604 | 8605 | | |
| |||
0 commit comments