Skip to content

feat(my-predictions): status and title filters with a filtered summary - #1795

Open
bilhokista wants to merge 3 commits into
Arena1X:mainfrom
bilhokista:feat/1556-predictions-filter
Open

feat(my-predictions): status and title filters with a filtered summary#1795
bilhokista wants to merge 3 commits into
Arena1X:mainfrom
bilhokista:feat/1556-predictions-filter

Conversation

@bilhokista

Copy link
Copy Markdown

Closes #1556.

Starting point

A status filter already existed (All / Active / Won / Lost / Pending) with counts on each tab. Missing were the Refunded status, the text search, the summary chips, and URL persistence — and the existing summary had a subtler problem, below.

The change

Filtering and summarising move into a new pure module, frontend/src/lib/predictions.ts, so the rules can be tested without rendering the page. The page keeps rendering and URL state.

Text search matches the market title, case-insensitively, trimmed. Status and search compose.

Refunded. Cancelling a prediction used to delete the row:

setPredictions((prev) => prev.filter((p) => p.id !== prediction.id));

A refund is part of the history the user opened this page to review, so it is now marked Refunded instead of vanishing, and has its own tab and badge.

URL persistence via ?status=&q=, written with router.replace rather than push so typing in the search box does not bury the previous page under a stack of history entries. Values at their default are omitted, keeping a pristine URL clean. An unrecognised status in a hand-edited or stale link falls back to defaults rather than failing.

Because useSearchParams opts the subtree into client rendering and Next refuses to build a page that calls it outside a Suspense boundary, the screen moved into MyPredictionsContent and the default export now supplies that boundary.

Two judgement calls worth review

The summary now describes the filtered set, not lifetime totals. The issue asks for exactly this ("summary reflects the filtered set"), and it is what makes the chips useful while filtering — but it does change what the four cards at the top of the page mean. The first card relabels itself from "Total Predictions" to "Predictions Shown" when a filter is active, so the number is not mistaken for a lifetime count.

Win rate is won ÷ settled, not won ÷ total. On the sample data that is 1 of 2 settled = 50%; over all six it would read 17% and would keep falling every time the user places a new prediction, which reads as though they are getting worse at this. winRate is null when nothing has settled, so the card shows "—" rather than a misleading 0%.

Also: net P/L counts a win as payout minus stake, not the gross payout, and treats open stakes as 0 rather than as losses — otherwise an untouched account with open bets looks under water.

Scope note

The page still renders MOCK_PREDICTIONS. The issue lists frontend/src/lib/api.ts in its file list, but wiring a real endpoint is a separate piece of work with its own contract to agree, so I left the fixture in place and kept this change to filtering and presentation. filterPredictions and summarisePredictions are generic over the prediction shape, so swapping in real data later does not touch them. ActivePrediction.tsx turned out not to be involved in this page and is untouched.

Tests

New predictions.test.ts, 30 cases across parseAmount, computePnl, filterPredictions, summarisePredictions, formatSignedAmount, and the URL round-trip — including the empty set (no division by zero), a search of pure whitespace, an unparseable amount, "-0.00" never being rendered as a loss, and an explicit case asserting the summary follows the filtered set.

Honest note on verification: I could not run the frontend Vitest suite locally (no full workspace install). Both changed files and the new module were parsed with the TypeScript compiler API, and predictions.ts was transpiled and executed standalone against 32 assertions — all passed. The page component itself needs CI; it has no test of its own here, since the logic worth asserting is in the module and testing the page would mostly re-test React.

🤖 Generated with Claude Code

https://claude.ai/code/session_01CrfEY1tvXrbeMDAUzxfuk7

@vercel

vercel Bot commented Sep 10, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
insight-arena-4rll Ready Ready Preview Sep 10, 2026 2:39pm UTC

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Frontend] — My Predictions Filter by Status and Outcome

1 participant