Skip to content

fix: give the eco-challenge error screen a way out (#1105) - #1110

Open
MOHITKOURAV01 wants to merge 1 commit into
Aditya8369:mainfrom
MOHITKOURAV01:fix/1105-eco-challenge-error-state
Open

fix: give the eco-challenge error screen a way out (#1105)#1110
MOHITKOURAV01 wants to merge 1 commit into
Aditya8369:mainfrom
MOHITKOURAV01:fix/1105-eco-challenge-error-state

Conversation

@MOHITKOURAV01

Copy link
Copy Markdown
Contributor

Closes #1105

setError(null) appeared nowhere in this component, so the first failed load ended it for the life of the page: a red box holding whatever string the service threw — for an offline user, the browser's raw TypeError: Failed to fetch — with no button, no link, and no way back other than a reload.

Worse, the paths that do re-fetch could not clear it. handleJoin and handleClaim both await loadData() on success, and loadData never reset the flag on the way in, so those loads populated data behind an error screen nobody could see past.

What changed

  • The error is recoverable. Cleared by a successful load; a Try again button on the full-page state; once challenges are on screen, a failure is a banner over them rather than instead of them.
  • Empty is not failure. A successful response with no active challenges said nothing at all — just the "Active Challenges" heading above an empty grid. It now says so.
  • A partial payload no longer throws. data?.challenges.map(...) stopped its optional chain at data, so a response of {} was undefined.map during render. fetchActiveChallenges returns response.json() unchecked, so nothing ruled that out. readChallengeData normalises the shape.
  • The progress bar stays inside its track. Math.min((progress / target) * 100, 100) capped the top and left the divisor unguarded. A targetValue of 0 gives InfinityNaN when progress is 0 too — and width: "NaN%" is dropped by the browser, so the bar silently vanished rather than looking wrong. Negative and missing values did the same, and progress.progress rendered raw as undefined / 10 reports.
  • The stray full stop. A leftover edit rendered ✅ Challenge Completed! Claim your reward. . under every completed challenge — on the one line a user is most likely to read closely.
  • window.alert → the page. Join and claim outcomes are reported in-place instead of blocking the tab.

Tests

26 new tests in src/components/EcoChallengeDashboard.test.jsx. progressPercent, progressCount and readChallengeData are asserted directly — including a property-style pass checking that progressPercent returns a finite value in [0, 100] for every hostile input — and the error, empty and malformed-payload paths through the component.

Verification

npx vitest run src/components/EcoChallengeDashboard.test.jsx   # 26 passed
npx eslint src/components/EcoChallengeDashboard.jsx src/components/EcoChallengeDashboard.test.jsx   # clean

setError(null) appeared nowhere, so the first failed load ended the
component for the life of the page: a red box holding whatever string the
service threw — for an offline user, the browser's raw
"TypeError: Failed to fetch" — with no retry and no way to dismiss it.
handleJoin and handleClaim both re-fetch on success, but loadData never
reset the flag, so those loads populated `data` behind an error screen
nobody could see past.

The error is now cleared by a successful load, carries a Try again
button, and once there are challenges on screen it appears as a banner
over them rather than instead of them.

A successful-but-empty response is no longer indistinguishable from a
failure — it says there are no challenges running, rather than leaving
the "Active Challenges" heading above an empty grid.

`data?.challenges.map(...)` stopped its optional chain at `data`, so a
response of `{}` was `undefined.map` and threw during render.
fetchActiveChallenges returns response.json() unchecked, so nothing ruled
that out. readChallengeData normalises the shape instead.

progressPercent replaces the inline `Math.min(x, 100)`, which capped the
top but left the divisor unguarded: a targetValue of 0 produced Infinity
(NaN when progress was 0 too), and `width: "NaN%"` is dropped by the
browser, so the bar silently disappeared rather than looking wrong. A
missing progress value also printed "undefined / 5 reports".

Removed the stray "." that rendered under every completed challenge, and
moved join/claim outcomes off window.alert into the page.
@vercel

vercel Bot commented Aug 28, 2026

Copy link
Copy Markdown

@MOHITKOURAV01 is attempting to deploy a commit to the Aditya Mahajan's projects Team on Vercel.

A member of the Team first needs to authorize it.

@github-actions github-actions Bot added the ECSoC26 Contributions considered under ECSoC'26 label Aug 28, 2026
@github-actions

Copy link
Copy Markdown

Thank You for Your Contribution! 🎉

Hi @MOHITKOURAV01,

Thank you for opening this Pull Request and contributing to our project. We truly appreciate your efforts.

Please make sure that:

  • Your code follows the project's guidelines.
  • You have linked the appropriate issue (if applicable).
  • Screenshots are added for UI/UX changes.
  • Your PR is ready for review.

The maintainer @Aditya8369 will review your PR shortly!

Happy Contributing! 🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ECSoC26 Contributions considered under ECSoC'26

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Eco-challenge dashboard is stuck on its error screen with no way to retry, and throws on a payload with no challenges array

1 participant