frontend: move insurance into marketplace#4113
Conversation
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
📝 WalkthroughWalkthroughThis pull request moves Bitsurance screens under /market/bitsurance and serves them via a new MarketplaceLayout with outlet context. Market navigation helpers and an "Insure" tab are added. Bitsurance pages are simplified from guided wrappers to View-based layouts and their internal routes updated to /market/bitsurance/*. Bitsurance entries were removed from the sidebar and settings; bottom-nav/back-navigation rules, tests, localization (generic.insure), and the changelog were updated accordingly. ✨ Finishing Touches🧪 Generate unit tests (beta)
Tip 💬 Introducing Slack Agent: The best way for teams to turn conversations into code.Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.
Built for teams:
One agent for your entire SDLC. Right inside Slack. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 3
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
frontends/web/src/routes/bitsurance/bitsurance.tsx (1)
44-57:⚠️ Potential issue | 🟠 Major | ⚡ Quick winAlways clear
scanLoadingon lookup failures.If
bitsuranceLookup()fails here, the function returns before resettingscanLoading, which leaves the detect CTA permanently disabled for the rest of the session.🔧 Suggested fix
const detect = async (redirectToDashboard: boolean) => { setScanLoading(true); setScanDone(false); setInsuredAccounts([]); - const response = await bitsuranceLookup(); - if (!response.success) { - alertUser(response.errorMessage); - return; - } - const insuredAccountsCodes = response.bitsuranceAccounts.map(account => account.status ? account.code : null); - const insured = accounts.filter(({ code }) => insuredAccountsCodes.includes(code)); - setInsuredAccounts(insured); - setScanDone(true); - setScanLoading(false); - if (insured.length && redirectToDashboard) { - navigate('/market/bitsurance/dashboard'); + try { + const response = await bitsuranceLookup(); + if (!response.success) { + alertUser(response.errorMessage); + return; + } + const insuredAccountsCodes = response.bitsuranceAccounts.map(account => account.status ? account.code : null); + const insured = accounts.filter(({ code }) => insuredAccountsCodes.includes(code)); + setInsuredAccounts(insured); + setScanDone(true); + if (insured.length && redirectToDashboard) { + navigate('/market/bitsurance/dashboard'); + } + } finally { + setScanLoading(false); } };🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@frontends/web/src/routes/bitsurance/bitsurance.tsx` around lines 44 - 57, The detect function currently returns early on bitsuranceLookup() failure without resetting scanLoading, leaving the CTA disabled; update detect to ensure setScanLoading(false) is always called on error paths (including after alertUser(response.errorMessage) and any other early returns), e.g., call setScanLoading(false) before returning or use a try/finally around the bitsuranceLookup() flow so setScanLoading(false) runs regardless; refer to the detect function, bitsuranceLookup, setScanLoading and setScanDone to apply the fix.frontends/web/src/components/sidebar/sidebar.tsx (1)
95-153:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winHandle account-scoped market routes in the sidebar active check.
This predicate only matches
/market..., so the Marketplace entry stays inactive on preserved account-scoped paths like/account/:code/market/....🔧 Suggested fix
- const userInSpecificAccountMarketPage = pathname.startsWith('/market'); + const userInSpecificAccountMarketPage = + pathname.startsWith('/market') + || /^\/account\/[^/]+\/market(?:\/|$)/.test(pathname);🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@frontends/web/src/components/sidebar/sidebar.tsx` around lines 95 - 153, The sidebar currently sets userInSpecificAccountMarketPage = pathname.startsWith('/market'), which misses account-scoped market routes like /account/:code/market; update the predicate used by userInSpecificAccountMarketPage (and the NavLink market active check) to detect both top-level and account-scoped market paths — e.g., replace the startsWith check with a broader match (pathname.startsWith('/market') || pathname.includes('/market') or a regex like /(^\/market|\/account\/[^/]+\/market)/) and ensure the NavLink className for the market entry uses this updated variable to mark the link active.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@frontends/web/src/routes/bitsurance/dashboard.tsx`:
- Around line 117-123: The Button's title prop is using the wrong translation
key (t('account.exportTransactions')) causing an unrelated tooltip; update the
title to use the bitsurance-related translation (e.g., set
title={t('bitsurance.dashboard.button')} or another appropriate bitsurance key)
on the Button component (the JSX around Button with className={style.button},
primary, onClick={() => navigate('/market/bitsurance/account')} and children
{t('bitsurance.dashboard.button')}) so the hover text matches the "Insure a new
account" CTA.
In `@frontends/web/src/routes/bitsurance/widget.tsx`:
- Around line 145-156: Replace the hardcoded iframe title "Bitsurance" with a
translated string: import and call useTranslation() in the widget component
(frontends/web/src/routes/bitsurance/widget.tsx), then replace
title="Bitsurance" with title={t('bitsurance.widgetTitle')} (or your chosen
translation key) and add the key to your i18n resource files; ensure iframeRef,
onIframeLoad, height and iframeURL usage remain unchanged.
In `@frontends/web/src/routes/router.tsx`:
- Around line 334-346: The nested Route with path="bitsurance" under the parent
Route path="bitsurance" creates a dead /bitsurance/bitsurance route; update the
child route inside the outer Route (the one rendering BitsuranceRedirect) to
either be removed or changed to a catch-all by replacing the child Route
path="bitsurance" with path="*" so it will match any legacy /bitsurance/...
paths and render BitsuranceRedirect; locate the Routes referencing
path="bitsurance" and the BitsuranceRedirect element to apply the fix.
---
Outside diff comments:
In `@frontends/web/src/components/sidebar/sidebar.tsx`:
- Around line 95-153: The sidebar currently sets userInSpecificAccountMarketPage
= pathname.startsWith('/market'), which misses account-scoped market routes like
/account/:code/market; update the predicate used by
userInSpecificAccountMarketPage (and the NavLink market active check) to detect
both top-level and account-scoped market paths — e.g., replace the startsWith
check with a broader match (pathname.startsWith('/market') ||
pathname.includes('/market') or a regex like
/(^\/market|\/account\/[^/]+\/market)/) and ensure the NavLink className for the
market entry uses this updated variable to mark the link active.
In `@frontends/web/src/routes/bitsurance/bitsurance.tsx`:
- Around line 44-57: The detect function currently returns early on
bitsuranceLookup() failure without resetting scanLoading, leaving the CTA
disabled; update detect to ensure setScanLoading(false) is always called on
error paths (including after alertUser(response.errorMessage) and any other
early returns), e.g., call setScanLoading(false) before returning or use a
try/finally around the bitsuranceLookup() flow so setScanLoading(false) runs
regardless; refer to the detect function, bitsuranceLookup, setScanLoading and
setScanDone to apply the fix.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: c20af321-9a3b-40c2-8e63-18820a32918b
📒 Files selected for processing (20)
frontends/web/src/app.tsxfrontends/web/src/components/bottom-navigation/bottom-navigation.tsxfrontends/web/src/components/bottom-navigation/utils.tsfrontends/web/src/components/sidebar/sidebar.tsxfrontends/web/src/contexts/BackNavigationContext.tsxfrontends/web/src/locales/en/app.jsonfrontends/web/src/routes/account/components/insuredtag.tsxfrontends/web/src/routes/bitsurance/account.tsxfrontends/web/src/routes/bitsurance/bitsurance.tsxfrontends/web/src/routes/bitsurance/dashboard.tsxfrontends/web/src/routes/bitsurance/widget.module.cssfrontends/web/src/routes/bitsurance/widget.tsxfrontends/web/src/routes/market/components/marketplace-navigation.tsxfrontends/web/src/routes/market/components/markettab.module.cssfrontends/web/src/routes/market/components/markettab.test.tsxfrontends/web/src/routes/market/components/markettab.tsxfrontends/web/src/routes/market/market.tsxfrontends/web/src/routes/market/marketplace-layout.tsxfrontends/web/src/routes/router.tsxfrontends/web/src/routes/settings/more.tsx
💤 Files with no reviewable changes (2)
- frontends/web/src/app.tsx
- frontends/web/src/routes/bitsurance/widget.module.css
0a4f4b8 to
03f2bdb
Compare
a318c9e to
42e71f8
Compare
There was a problem hiding this comment.
Actionable comments posted: 5
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
frontends/web/src/routes/router.tsx (1)
291-319:⚠️ Potential issue | 🟠 Major | ⚡ Quick winAdd legacy
/bitsuranceroute redirects or update PR description.The PR objective states "redirect legacy
/bitsuranceroutes accordingly", but the current router contains no redirects for legacy paths like/bitsurance,/bitsurance/dashboard,/bitsurance/account/:code, or/bitsurance/widget/:code. These paths will now fail to match any route, breaking external links and user bookmarks.Either:
- Add a redirect subtree at the root
/bitsurancepath that maps these legacy routes to their new/market/bitsurance/*counterparts, or- Update the PR description to reflect that legacy URLs are intentionally no longer supported.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@frontends/web/src/routes/router.tsx` around lines 291 - 319, The router is missing legacy redirects for /bitsurance/* so external links break; add a root-level Route subtree that matches legacy paths (e.g., path="bitsurance" with nested routes for index, dashboard, account/:code, widget/:code) and redirect them to their new counterparts under /market/bitsurance (use the same target routes used in the Market subtree such as the index -> /market/bitsurance, dashboard -> /market/bitsurance/dashboard, account/:code -> /market/bitsurance/account/:code, widget/:code -> /market/bitsurance/widget/:code) so existing bookmarks resolve to the new components (the new Market bitsurance routes reference Bitsurance, BitsuranceAccountEl, BitsuranceWidgetEl, BitsuranceDashboard and MarketplaceLayoutEl); alternatively update the PR description to state legacy URLs are intentionally removed.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@frontends/web/src/components/sidebar/sidebar.tsx`:
- Line 95: The variable userInSpecificAccountMarketPage no longer matches its
predicate pathname.startsWith('/market'); rename it (e.g., inMarketSection) or
inline the condition where used to improve clarity—update all occurrences of
userInSpecificAccountMarketPage (including the second usage block within the
same file) to the new name or replace with pathname.startsWith('/market') so
references like the assignment and any conditionals or JSX checks remain
consistent.
In `@frontends/web/src/routes/bitsurance/account.tsx`:
- Around line 90-114: The JSX return wraps a single <View> in an unnecessary
fragment (<>...</>); remove the fragment tokens so the component returns the
<View> directly (keep the existing <ViewContent>, conditional rendering of
btcAccounts, GroupedAccountSelector props like disabled, selected,
onChange={handleChangeAccount}, onProceed={handleProceed}, and the
t('bitsuranceAccount.noAccount') branch unchanged). Ensure
parentheses/whitespace remain correct around the returned <View>.
In `@frontends/web/src/routes/bitsurance/bitsurance.tsx`:
- Around line 86-143: The top-level fragment wrapping the single <View> in the
Bitsurance component is unnecessary; remove the <> and </> so the render returns
the <View fullscreen={false}> element directly (update the return in
bitsurance.tsx to return <View>... without the surrounding fragment), keeping
all inner children and props unchanged.
In `@frontends/web/src/routes/bitsurance/dashboard.tsx`:
- Around line 105-197: The JSX fragment wrapping the single <View> is
unnecessary; remove the outer <>...</> so the component returns the <View>
directly (update the return in the render of this file: remove the fragment
tokens surrounding the View element), ensuring the remaining structure and
import usage of View, ViewContent and children stay intact.
In `@frontends/web/src/routes/market/marketplace-layout.tsx`:
- Around line 78-82: The Header currently always uses t('generic.buySell'),
causing Bitsurance pages to show the wrong title; update the title prop in
marketplace-layout's JSX (the Header component usage) to conditionally choose
t('generic.insure') when the page is a Bitsurance route (use the existing
pathname check, isBitsurance flag, or activeTab) and fall back to
t('generic.buySell') otherwise, ensuring the translation hook
useTranslation()/t() is used and keeping the existing HideAmountsButton
rendering unchanged.
---
Outside diff comments:
In `@frontends/web/src/routes/router.tsx`:
- Around line 291-319: The router is missing legacy redirects for /bitsurance/*
so external links break; add a root-level Route subtree that matches legacy
paths (e.g., path="bitsurance" with nested routes for index, dashboard,
account/:code, widget/:code) and redirect them to their new counterparts under
/market/bitsurance (use the same target routes used in the Market subtree such
as the index -> /market/bitsurance, dashboard -> /market/bitsurance/dashboard,
account/:code -> /market/bitsurance/account/:code, widget/:code ->
/market/bitsurance/widget/:code) so existing bookmarks resolve to the new
components (the new Market bitsurance routes reference Bitsurance,
BitsuranceAccountEl, BitsuranceWidgetEl, BitsuranceDashboard and
MarketplaceLayoutEl); alternatively update the PR description to state legacy
URLs are intentionally removed.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 5e9759fe-e298-4b56-b496-1909e709ab2c
📒 Files selected for processing (21)
CHANGELOG.mdfrontends/web/src/app.tsxfrontends/web/src/components/bottom-navigation/bottom-navigation.tsxfrontends/web/src/components/bottom-navigation/utils.tsfrontends/web/src/components/sidebar/sidebar.tsxfrontends/web/src/contexts/BackNavigationContext.tsxfrontends/web/src/locales/en/app.jsonfrontends/web/src/routes/account/components/insuredtag.tsxfrontends/web/src/routes/bitsurance/account.tsxfrontends/web/src/routes/bitsurance/bitsurance.tsxfrontends/web/src/routes/bitsurance/dashboard.tsxfrontends/web/src/routes/bitsurance/widget.module.cssfrontends/web/src/routes/bitsurance/widget.tsxfrontends/web/src/routes/market/components/marketplace-navigation.tsxfrontends/web/src/routes/market/components/markettab.module.cssfrontends/web/src/routes/market/components/markettab.test.tsxfrontends/web/src/routes/market/components/markettab.tsxfrontends/web/src/routes/market/market.tsxfrontends/web/src/routes/market/marketplace-layout.tsxfrontends/web/src/routes/router.tsxfrontends/web/src/routes/settings/more.tsx
💤 Files with no reviewable changes (2)
- frontends/web/src/app.tsx
- frontends/web/src/routes/bitsurance/widget.module.css
42e71f8 to
9160192
Compare
There was a problem hiding this comment.
Actionable comments posted: 4
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@frontends/web/src/routes/bitsurance/bitsurance.tsx`:
- Around line 48-52: The bitsuranceLookup result is not being used to stop or
redirect before navigation: update the logic around bitsuranceLookup(),
alertUser(), and detect(false) so that you only call
navigate('/market/bitsurance/account') when the lookup succeeded and the account
actually needs onboarding; if response.success is false, return early (no
navigation) after calling alertUser(response.errorMessage); if the response
indicates the account is already insured, either short-circuit to the
appropriate account view or show the "already insured" UI instead of proceeding
to the insure flow. Adjust both the initial lookup block (bitsuranceLookup,
alertUser, detect(false)) and the later navigation block that currently
unconditionally calls navigate('/market/bitsurance/account') so navigation is
gated by response.success and the lookup's insured status.
In `@frontends/web/src/routes/market/components/markettab.module.css`:
- Around line 1-9: The .navigation rule uses justify-content: center (a no-op
without a flex/grid container) and suggests it was intended to be both a flex
item and a flex container (flex-grow: 0); update the .navigation CSS to make
justify-content effective by adding display: flex (and optionally align-items:
center if vertical centering of the pill buttons is desired) so children are
centered, or remove justify-content if you do not want it to be a container —
edit the .navigation block to add display: flex and align-items: center to
restore the intended centering behavior.
In `@frontends/web/src/routes/market/components/markettab.test.tsx`:
- Line 76: Tests are failing because the i18n mock used by frontends/web tests
does not include translations for 'generic.swap' and 'generic.insure', so t(...)
falls back to the key strings and the queries for button names 'Swap'/'Insure'
fail; open the i18n mock (frontends/web/__mocks__/i18n.ts) and add entries
'generic.swap': 'Swap' and 'generic.insure': 'Insure' to the resources object
used by the mocked t function so the rendered buttons have the expected
accessible names.
In `@frontends/web/src/routes/market/market.tsx`:
- Around line 75-90: The effect currently selects nextAccount but never updates
the URL when the route lacked a valid account code; update it to perform a
replace-navigation to the account-scoped path whenever validRouteAccountCode is
falsy and you choose a non-empty nextAccount: after calling
setMarketAccountCode?.(nextAccount) and setSelectedAccount(nextAccount) in the
useEffect, call your router replace (e.g. history.replace or navigate with {
replace: true }) with getMarketSelectPath(activeTab, nextAccount) so the URL is
normalized into the account-scoped path; guard this navigation behind
validRouteAccountCode being empty and nextAccount !== '' to avoid unnecessary
redirects.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 024b5c9a-1805-4ee9-b76c-816761377a95
📒 Files selected for processing (21)
CHANGELOG.mdfrontends/web/src/app.tsxfrontends/web/src/components/bottom-navigation/bottom-navigation.tsxfrontends/web/src/components/bottom-navigation/utils.tsfrontends/web/src/components/sidebar/sidebar.tsxfrontends/web/src/contexts/BackNavigationContext.tsxfrontends/web/src/locales/en/app.jsonfrontends/web/src/routes/account/components/insuredtag.tsxfrontends/web/src/routes/bitsurance/account.tsxfrontends/web/src/routes/bitsurance/bitsurance.tsxfrontends/web/src/routes/bitsurance/dashboard.tsxfrontends/web/src/routes/bitsurance/widget.module.cssfrontends/web/src/routes/bitsurance/widget.tsxfrontends/web/src/routes/market/components/marketplace-navigation.tsxfrontends/web/src/routes/market/components/markettab.module.cssfrontends/web/src/routes/market/components/markettab.test.tsxfrontends/web/src/routes/market/components/markettab.tsxfrontends/web/src/routes/market/market.tsxfrontends/web/src/routes/market/marketplace-layout.tsxfrontends/web/src/routes/router.tsxfrontends/web/src/routes/settings/more.tsx
💤 Files with no reviewable changes (2)
- frontends/web/src/routes/bitsurance/widget.module.css
- frontends/web/src/app.tsx
2ef541b to
7b7ab45
Compare
There was a problem hiding this comment.
Actionable comments posted: 2
♻️ Duplicate comments (1)
frontends/web/src/routes/market/components/markettab.module.css (1)
1-9:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winAdd
display: flexto makejustify-content: centereffective.The
.navigationrule includesjustify-content: center, but withoutdisplay: flex, this property has no effect. Theflex-grow: 0on line 3 confirms this element is intended to participate in both flex-item and flex-container roles.🛠️ Proposed fix
.navigation { box-sizing: border-box; + display: flex; flex-grow: 0; justify-content: center; margin: 0 auto; max-width: var(--content-width); padding: 0 var(--space-default); width: 100%; }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@frontends/web/src/routes/market/components/markettab.module.css` around lines 1 - 9, The .navigation CSS block is missing display: flex so justify-content: center has no effect; update the .navigation rule to include display: flex (keeping existing properties like flex-grow: 0, width, padding, etc.) so it becomes a flex container and the justify-content center behavior works as intended.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@frontends/web/src/routes/market/components/marketplace-navigation.tsx`:
- Line 20: cachedShowSwap is a module-level boolean preserving swap visibility
across remounts; replace it with a proper shared state provider to be safe for
SSR/concurrent renders. Create a SwapVisibilityContext (or use existing global
store like Redux/Zustand) that exposes showSwap and setShowSwap, update
MarketplaceNavigation to read/write via useContext/useStore instead of the
module variable, remove cachedShowSwap, and optionally persist initial value to
localStorage inside the provider if you need cross-session caching.
In `@frontends/web/src/routes/market/marketplace-layout.tsx`:
- Around line 41-72: The pathname checks using startsWith in
marketplace-layout.tsx (variables isBitsurance, isMarketSelect, and
showMarketplaceNavigation) are too permissive; update them to anchor with exact
match or a trailing slash (e.g., replace
pathname.startsWith('/market/bitsurance') with pathname === '/market/bitsurance'
|| pathname.startsWith('/market/bitsurance/')) and do the same for
'/market/select' and the '/market/bitsurance/widget' check so sibling segments
like '/market/bitsurance-foo' no longer match; keep the rest of the logic
(marketAccountCode, outletContext, handleChangeTab) unchanged.
---
Duplicate comments:
In `@frontends/web/src/routes/market/components/markettab.module.css`:
- Around line 1-9: The .navigation CSS block is missing display: flex so
justify-content: center has no effect; update the .navigation rule to include
display: flex (keeping existing properties like flex-grow: 0, width, padding,
etc.) so it becomes a flex container and the justify-content center behavior
works as intended.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 23d82b71-52c4-4f7f-8657-38a0029d0392
📒 Files selected for processing (22)
CHANGELOG.mdfrontends/web/__mocks__/i18n.tsfrontends/web/src/app.tsxfrontends/web/src/components/bottom-navigation/bottom-navigation.tsxfrontends/web/src/components/bottom-navigation/utils.tsfrontends/web/src/components/sidebar/sidebar.tsxfrontends/web/src/contexts/BackNavigationContext.tsxfrontends/web/src/locales/en/app.jsonfrontends/web/src/routes/account/components/insuredtag.tsxfrontends/web/src/routes/bitsurance/account.tsxfrontends/web/src/routes/bitsurance/bitsurance.tsxfrontends/web/src/routes/bitsurance/dashboard.tsxfrontends/web/src/routes/bitsurance/widget.module.cssfrontends/web/src/routes/bitsurance/widget.tsxfrontends/web/src/routes/market/components/marketplace-navigation.tsxfrontends/web/src/routes/market/components/markettab.module.cssfrontends/web/src/routes/market/components/markettab.test.tsxfrontends/web/src/routes/market/components/markettab.tsxfrontends/web/src/routes/market/market.tsxfrontends/web/src/routes/market/marketplace-layout.tsxfrontends/web/src/routes/router.tsxfrontends/web/src/routes/settings/more.tsx
💤 Files with no reviewable changes (2)
- frontends/web/src/app.tsx
- frontends/web/src/routes/bitsurance/widget.module.css
0b1d8c4 to
3bfc0bb
Compare
|
@thisconnect thanks I addressed your comments in the second commit, PTAL 🙏 |
|
added a third commit to address comments, PTAL, thanks |
ffc093d to
540aab3
Compare
425f7e3 to
153d405
Compare
|
thanks, updated in 4th commit, PTAL 🙏 |
shonsirsha
left a comment
There was a problem hiding this comment.
Great work thx! I noticed one small UI bug/potential improvement
e045562 to
2ca2b31
Compare
2ca2b31 to
7c5238d
Compare
|
updated, thanks, also I removed the unused |
| </Routes> | ||
| </MarketProvider> | ||
| } /> | ||
| <Route path="market"> |
There was a problem hiding this comment.
I think it doens't make sense to have <Route path="market/*" (few lines before) AND <Route path="market">
@coderabbitai review
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -e
fd -a market-context frontends/web/src/routes/market
echo "---"
cat -n frontends/web/src/routes/market/market-context.tsx 2>/dev/null | head -60Length of output: 5358
@thisconnect, agreed — this is a valid concern. Right now there are two sibling Route declarations for market:
<Route path="market/*" element={...}>— wrapsselect,select/:code, and the newbitsurance/*paths inMarketProvider, using a manually nested<Routes>inside theelementprop.<Route path="market">— the pre-existing declarative nested-Routetree forbtcdirect,bitrefill,moonpay,pocket,swap,*-otc, withoutMarketProvider.
Technically React Router v6 resolves overlaps by route specificity (static/dynamic segments outrank splats), so the second block would currently win for its own paths — but that's fragile to rely on, and having two different routing patterns (splat + inline <Routes> vs. idiomatic nested <Route>) for the same path prefix is confusing to maintain, exactly as you noted.
A cleaner approach is to merge them into a single market route tree, and scope MarketProvider with a layout route + Outlet instead of a manual splat/<Routes> nesting:
import { Outlet } from 'react-router-dom';
// ...
const MarketProviderLayout = () => (
<MarketProvider accounts={activeAccounts}>
<Outlet />
</MarketProvider>
);
// ...
<Route path="market">
<Route element={<MarketProviderLayout />}>
<Route path="select" element={MarketEl} />
<Route path="select/:code" element={MarketEl} />
<Route path="bitsurance/widget/:code" element={BitsuranceWidgetEl} />
<Route path="bitsurance">
<Route path=":code" element={BitsuranceIntroEl} />
<Route path="account/:code" element={BitsuranceAccountEl} />
<Route path="dashboard/:code" element={BitsuranceDashboardRouteEl} />
</Route>
</Route>
<Route path="btcdirect/buy/:code" element={BTCDirectBuyEl} />
<Route path="btcdirect/buy/:code/:region" element={BTCDirectBuyEl} />
<Route path="btcdirect/sell/:code" element={BTCDirectSellEl} />
<Route path="btcdirect/sell/:code/:region" element={BTCDirectSellEl} />
<Route path="bitrefill/spend/:code" element={BitrefillEl} />
<Route path="bitrefill/spend/:code/:region" element={BitrefillEl} />
<Route path="moonpay/buy/:code" element={MoonpayEl} />
<Route path="moonpay/buy/:code/:region" element={MoonpayEl} />
<Route path="pocket/buy/:code" element={PocketBuyEl} />
<Route path="pocket/buy/:code/:region" element={PocketBuyEl} />
<Route path="pocket/sell/:code" element={PocketSellEl} />
<Route path="pocket/sell/:code/:region" element={PocketSellEl} />
<Route path="btcdirect-otc" element={<BTCDirectOTC/>} />
<Route path="pocket-otc" element={<PocketOTC/>} />
<Route path="swap" element={SwapEl} />
</Route>This gives you one unambiguous market route tree, keeps MarketProvider scoped to only the routes that need it, and avoids mixing splat-based and declarative route nesting for the same path.
Let me know if you'd like me to draft this as an actual code change to the PR.
🧬 Code Graph Analysis Results
frontends/web/src/routes/router.tsx (lines 313-343)
<Route path="market/*" element={
<MarketProvider accounts={activeAccounts}>
<Routes>
<Route path="select" element={MarketEl} />
<Route path="select/:code" element={MarketEl} />
<Route path="bitsurance/widget/:code" element={BitsuranceWidgetEl} />
<Route path="bitsurance">
<Route path=":code" element={BitsuranceIntroEl} />
<Route path="account/:code" element={BitsuranceAccountEl} />
<Route path="dashboard/:code" element={BitsuranceDashboardRouteEl} />
</Route>
</Routes>
</MarketProvider>
} />
<Route path="market">
<Route path="btcdirect/buy/:code" element={BTCDirectBuyEl} />
<Route path="btcdirect/buy/:code/:region" element={BTCDirectBuyEl} />
<Route path="btcdirect/sell/:code" element={BTCDirectSellEl} />
<Route path="btcdirect/sell/:code/:region" element={BTCDirectSellEl} />
<Route path="bitrefill/spend/:code" element={BitrefillEl} />
<Route path="bitrefill/spend/:code/:region" element={BitrefillEl} />
<Route path="moonpay/buy/:code" element={MoonpayEl} />
<Route path="moonpay/buy/:code/:region" element={MoonpayEl} />
<Route path="pocket/buy/:code" element={PocketBuyEl} />
<Route path="pocket/buy/:code/:region" element={PocketBuyEl} />
<Route path="pocket/sell/:code" element={PocketSellEl} />
<Route path="pocket/sell/:code/:region" element={PocketSellEl} />
<Route path="btcdirect-otc" element={<BTCDirectOTC/>} />
<Route path="pocket-otc" element={<PocketOTC/>} />
<Route path="swap" element={SwapEl} />
</Route>frontends/web/src/routes/market/market-context.tsx (lines 28-96)
/**
* MarketProvider({ accounts, children }: TProps) -> ReactNode
* - Parameters:
* - accounts: accounts used to load swap availability/status
* - children: nested routes/components to render within the context
* - Behavior:
* - Loads region codes (getMarketRegionCodes) and swap status (getSwapStatus)
* - Derives/initializes `regions` and `selectedRegion` based on config + locale
* - Sets `showSwap` based on swapStatus.available
* - Provides context value: { regions, selectedRegion, setSelectedRegion, showSwap }
* - Returns:
* - <MarketContext.Provider value={...}>{children}</MarketContext.Provider>
* - Error handling:
* - No explicit try/catch here; relies on useLoad hooks for loading/error states.
*/
export const MarketProvider = ({
accounts,
children,
}: TProps) => {
...
};✏️ Learnings added
Learnt from: thisconnect
Repo: BitBoxSwiss/bitbox-wallet-app PR: 4113
File: frontends/web/src/routes/router.tsx:328-328
Timestamp: 2026-07-01T10:17:50.077Z
Learning: In frontends/web/src/routes/router.tsx (React Router v6, BitBoxSwiss/bitbox-wallet-app), avoid declaring a splat route like `<Route path="market/*" element={<MarketProvider><Routes>...</Routes></MarketProvider>}>` as a sibling of a declarative nested `<Route path="market">{...}</Route>` for the same path prefix. Prefer a single `market` route tree using a layout route (`<Route element={<SomeProviderLayout />}><Outlet/></Route>`) to scope context providers like `MarketProvider` (frontends/web/src/routes/market/market-context.tsx) around only the subset of nested routes that need it.
Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.
🧠 Learnings used
Learnt from: thisconnect
Repo: BitBoxSwiss/bitbox-wallet-app PR: 4038
File: frontends/web/src/routes/settings/components/about/support-link-setting.tsx:7-7
Timestamp: 2026-04-22T18:36:13.978Z
Learning: In files under `frontends/web/src/routes/`, do not flag relative imports within the `src/routes/` directory tree (e.g., `./...` and `../...`). Use the `@/` alias mainly when the import leaves `src/routes/` and targets other `src/` areas (e.g., `@/components`, `@/api`, `@/utils`).
Learnt from: thisconnect
Repo: BitBoxSwiss/bitbox-wallet-app PR: 4102
File: frontends/web/src/components/infobutton/infobutton.tsx:6-6
Timestamp: 2026-05-05T13:22:38.824Z
Learning: In this repository’s web frontend, accessibility (screen reader support and meaningful ARIA semantics such as aria-labels/roles) is intentionally deferred until an active accessibility effort starts. During code reviews, do not raise or require missing ARIA attributes, roles, or screen-reader support as issues in TSX changes; wait to enforce these concerns once accessibility work is underway.
Learnt from: thisconnect
Repo: BitBoxSwiss/bitbox-wallet-app PR: 3916
File: frontends/web/src/components/banners/offline-error.tsx:16-17
Timestamp: 2026-05-19T14:46:15.693Z
Learning: In BitBoxSwiss/bitbox-wallet-app, treat `proxy` as optional on `TBackendConfig` (defined in `frontends/web/src/api/config.ts`). When accessing `useProxy`, use the correct optional-chaining pattern: `config?.backend.proxy?.useProxy` (because `config` may be `undefined`, `backend` is required once `config` exists, and `proxy` may be missing). Do not flag code during review for not treating `proxy` as a required field of `TBackendConfig`.
There was a problem hiding this comment.
@coderabbitai we don't want to use Outlet so we can change to another router in the future. Can you suggest a solution without outlet?
There was a problem hiding this comment.
@thisconnect, understood — no Outlet needed. You can get the same effect by wrapping each individual element with MarketProvider at the point where it's defined (like the other route elements in this file already do with InjectParams), and then folding both market blocks into one flat <Route path="market"> tree with plain <Route path="..." element={...} /> entries — no splat, no nested <Routes>, no Outlet:
const MarketEl = (<InjectParams>
<MarketProvider accounts={activeAccounts}>
<Market
accounts={activeAccounts}
code={''}
/>
</MarketProvider>
</InjectParams>);
const BitsuranceWidgetEl = (<InjectParams>
<MarketProvider accounts={activeAccounts}>
<BitsuranceWidget code={''} />
</MarketProvider>
</InjectParams>);
const BitsuranceIntroEl = (
<InjectParams>
<MarketProvider accounts={activeAccounts}>
<Bitsurance
accounts={activeAccounts}
code={''} />
</MarketProvider>
</InjectParams>
);
const BitsuranceAccountEl = (<InjectParams>
<MarketProvider accounts={activeAccounts}>
<BitsuranceAccount
code={''}
accounts={activeAccounts} />
</MarketProvider>
</InjectParams>);
const BitsuranceDashboardRouteEl = (
<InjectParams>
<MarketProvider accounts={activeAccounts}>
<BitsuranceDashboard
accounts={activeAccounts}
code={''} />
</MarketProvider>
</InjectParams>
);And then a single, flat market route tree:
<Route path="market">
<Route path="select" element={MarketEl} />
<Route path="select/:code" element={MarketEl} />
<Route path="bitsurance/widget/:code" element={BitsuranceWidgetEl} />
<Route path="bitsurance">
<Route path=":code" element={BitsuranceIntroEl} />
<Route path="account/:code" element={BitsuranceAccountEl} />
<Route path="dashboard/:code" element={BitsuranceDashboardRouteEl} />
</Route>
<Route path="btcdirect/buy/:code" element={BTCDirectBuyEl} />
<Route path="btcdirect/buy/:code/:region" element={BTCDirectBuyEl} />
<Route path="btcdirect/sell/:code" element={BTCDirectSellEl} />
<Route path="btcdirect/sell/:code/:region" element={BTCDirectSellEl} />
<Route path="bitrefill/spend/:code" element={BitrefillEl} />
<Route path="bitrefill/spend/:code/:region" element={BitrefillEl} />
<Route path="moonpay/buy/:code" element={MoonpayEl} />
<Route path="moonpay/buy/:code/:region" element={MoonpayEl} />
<Route path="pocket/buy/:code" element={PocketBuyEl} />
<Route path="pocket/buy/:code/:region" element={PocketBuyEl} />
<Route path="pocket/sell/:code" element={PocketSellEl} />
<Route path="pocket/sell/:code/:region" element={PocketSellEl} />
<Route path="btcdirect-otc" element={<BTCDirectOTC/>} />
<Route path="pocket-otc" element={<PocketOTC/>} />
<Route path="swap" element={SwapEl} />
</Route>This keeps MarketProvider scoped only to the select/bitsurance/* elements (matching the current behavior), removes the splat + inline <Routes> pattern entirely, avoids Outlet, and results in a single unambiguous market route tree consistent with the rest of this file's style — each element is fully constructed once, then referenced declaratively in the route tree.
✏️ Learnings added
Learnt from: thisconnect
Repo: BitBoxSwiss/bitbox-wallet-app PR: 4113
File: frontends/web/src/routes/router.tsx:328-328
Timestamp: 2026-07-01T10:21:40.216Z
Learning: In frontends/web/src/routes/router.tsx (React Router v6, BitBoxSwiss/bitbox-wallet-app), the team wants to avoid using `Outlet`-based layout routes to keep the option of switching routers in the future. When a context provider (e.g., `MarketProvider` from frontends/web/src/routes/market/market-context.tsx) needs to be scoped to a subset of nested routes, prefer wrapping each individual route element with the provider at the point where the element is constructed (similar to how `InjectParams` already wraps elements in this file), and then declare all routes under a single flat `<Route path="...">` tree using plain `<Route path="..." element={...} />` entries — avoid splat routes (`path="market/*"`) combined with inline nested `<Routes>` as a sibling of a declarative `<Route path="market">` tree.
Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.
🧠 Learnings used
Learnt from: thisconnect
Repo: BitBoxSwiss/bitbox-wallet-app PR: 4038
File: frontends/web/src/routes/settings/components/about/support-link-setting.tsx:7-7
Timestamp: 2026-04-22T18:36:13.978Z
Learning: In files under `frontends/web/src/routes/`, do not flag relative imports within the `src/routes/` directory tree (e.g., `./...` and `../...`). Use the `@/` alias mainly when the import leaves `src/routes/` and targets other `src/` areas (e.g., `@/components`, `@/api`, `@/utils`).
Learnt from: thisconnect
Repo: BitBoxSwiss/bitbox-wallet-app PR: 4102
File: frontends/web/src/components/infobutton/infobutton.tsx:6-6
Timestamp: 2026-05-05T13:22:38.824Z
Learning: In this repository’s web frontend, accessibility (screen reader support and meaningful ARIA semantics such as aria-labels/roles) is intentionally deferred until an active accessibility effort starts. During code reviews, do not raise or require missing ARIA attributes, roles, or screen-reader support as issues in TSX changes; wait to enforce these concerns once accessibility work is underway.
Learnt from: thisconnect
Repo: BitBoxSwiss/bitbox-wallet-app PR: 3916
File: frontends/web/src/components/banners/offline-error.tsx:16-17
Timestamp: 2026-05-19T14:46:15.693Z
Learning: In BitBoxSwiss/bitbox-wallet-app, treat `proxy` as optional on `TBackendConfig` (defined in `frontends/web/src/api/config.ts`). When accessing `useProxy`, use the correct optional-chaining pattern: `config?.backend.proxy?.useProxy` (because `config` may be `undefined`, `backend` is required once `config` exists, and `proxy` may be missing). Do not flag code during review for not treating `proxy` as a required field of `TBackendConfig`.
There was a problem hiding this comment.
InjectParams wont work as it clones the child but injects the params only in the cloned child which is MarketProvider and not the actual component i.e. BitsuranceAccount
Lets keep this as is and migrate to wrouter soon.
There was a problem hiding this comment.
@thisconnect, good catch — you're right, InjectParams uses React.cloneElement on its direct child, so it would only pass route params onto MarketProvider, not down into the actual leaf component like BitsuranceAccount that needs code. My suggested refactor wouldn't have worked as written. Keeping the current splat + separate market route structure as-is makes sense given the planned migration to wouter.
✏️ Learnings added
Learnt from: thisconnect
Repo: BitBoxSwiss/bitbox-wallet-app PR: 4113
File: frontends/web/src/routes/router.tsx:328-328
Timestamp: 2026-07-02T07:16:44.393Z
Learning: In frontends/web/src/routes/router.tsx (BitBoxSwiss/bitbox-wallet-app), `InjectParams` uses `React.cloneElement` on its direct child, so it only injects route params (e.g., `code`) onto that direct child element — not onto deeper/nested components. This means wrapping a leaf route component with another wrapper (e.g., `MarketProvider`) as the direct child of `InjectParams` breaks param injection, since params would land on the wrapper instead of the actual component (e.g., `BitsuranceAccount`). The team intends to keep the current `market/*` splat route + separate declarative `market` route structure as-is, and plans to migrate the router from react-router-dom to wouter soon, at which point routing patterns like this can be revisited.
Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.
🧠 Learnings used
Learnt from: thisconnect
Repo: BitBoxSwiss/bitbox-wallet-app PR: 4038
File: frontends/web/src/routes/settings/components/about/support-link-setting.tsx:7-7
Timestamp: 2026-04-22T18:36:13.978Z
Learning: In files under `frontends/web/src/routes/`, do not flag relative imports within the `src/routes/` directory tree (e.g., `./...` and `../...`). Use the `@/` alias mainly when the import leaves `src/routes/` and targets other `src/` areas (e.g., `@/components`, `@/api`, `@/utils`).
Learnt from: thisconnect
Repo: BitBoxSwiss/bitbox-wallet-app PR: 4102
File: frontends/web/src/components/infobutton/infobutton.tsx:6-6
Timestamp: 2026-05-05T13:22:38.824Z
Learning: In this repository’s web frontend, accessibility (screen reader support and meaningful ARIA semantics such as aria-labels/roles) is intentionally deferred until an active accessibility effort starts. During code reviews, do not raise or require missing ARIA attributes, roles, or screen-reader support as issues in TSX changes; wait to enforce these concerns once accessibility work is underway.
Learnt from: thisconnect
Repo: BitBoxSwiss/bitbox-wallet-app PR: 3916
File: frontends/web/src/components/banners/offline-error.tsx:16-17
Timestamp: 2026-05-19T14:46:15.693Z
Learning: In BitBoxSwiss/bitbox-wallet-app, treat `proxy` as optional on `TBackendConfig` (defined in `frontends/web/src/api/config.ts`). When accessing `useProxy`, use the correct optional-chaining pattern: `config?.backend.proxy?.useProxy` (because `config` may be `undefined`, `backend` is required once `config` exists, and `proxy` may be missing). Do not flag code during review for not treating `proxy` as a required field of `TBackendConfig`.
| <Route path="add-account" element={<AddAccount accounts={accounts}/>} /> | ||
| <Route path="account-summary" element={AccountsSummaryEl} /> | ||
| <Route path="market/*" element={ | ||
| <MarketProvider accounts={activeAccounts}> |
There was a problem hiding this comment.
I like that the MarketProvider is only added for the routes that actually need it.
Route Bitsurance through the marketplace flow so tab navigation, account selection, and swap availability share one context.
Drop unnecessary supported-accounts state. Simplify routing without the layout wrapper. Move market logic into MarketContext. Drop the one-use tab reader because the tab is controlled by app. Treat account code as one of the account codes. Update market tab tests.
6472194 to
f0d250e
Compare
Route Bitsurance through the marketplace flow
so tab navigation, account selection, and swap
availability share one context.