fix(admin): open billing portal in same tab to reflect edits on return - #1722
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughSummary by CodeRabbit
WalkthroughThe billing portal flow now skips pre-opening a separate tab and redirects the current page to the checkout URL returned by ChangesBilling portal navigation update
Estimated code review effort: 2 (Simple) | ~10 minutes Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 2✅ Passed checks (2 passed)
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.
🧹 Nitpick comments (2)
web/sdk/admin/views/organizations/details/side-panel/billing-details-section.tsx (2)
94-107: 🎯 Functional Correctness | 🔵 Trivial | 🏗️ Heavy liftOne-shot refresh flag may leave data stale on repeated portal round-trips.
portalOpenedRef.currentis reset tofalsethe moment the tab becomes visible again, so only the first return from the Stripe portal triggers a refetch. If the user keeps the portal tab open and toggles back to the admin tab multiple times while still editing (e.g., checks something in admin, returns to the portal, edits the address further, comes back again), subsequent returns won't refresh — reintroducing the exact stale-data problem this PR is meant to fix.Consider not resetting the flag until the portal tab is actually known to be closed (e.g., track the
portalTab/window reference and poll.closed, or listen for itsunload/pagehide), so every return-to-tab visit while the portal is still open triggers a refresh.💡 Illustrative approach
- useEffect(() => { - const handleVisibilityChange = () => { - if (document.visibilityState === "visible" && portalOpenedRef.current) { - portalOpenedRef.current = false; - fetchBillingAccountDetails(); - } - }; + useEffect(() => { + const handleVisibilityChange = () => { + if (document.visibilityState === "visible" && portalOpenedRef.current) { + fetchBillingAccountDetails(); + // Only stop refreshing once the portal tab itself has been closed. + if (portalTabRef.current?.closed) { + portalOpenedRef.current = false; + } + } + }; document.addEventListener("visibilitychange", handleVisibilityChange); return () => { document.removeEventListener("visibilitychange", handleVisibilityChange); }; }, [fetchBillingAccountDetails]);
100-100: 🩺 Stability & Availability | 🔵 Trivial | 💤 Low valueUnhandled rejection risk on
fetchBillingAccountDetails().The refetch promise is fired without a
.catch/await. If it rejects, this could surface as an unhandled promise rejection.🛡️ Proposed fix
- fetchBillingAccountDetails(); + fetchBillingAccountDetails()?.catch(() => { + // errors are already surfaced via the query's error state + });
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 65ec65f6-485e-4c28-92d1-7397f5df75ec
📒 Files selected for processing (1)
web/sdk/admin/views/organizations/details/side-panel/billing-details-section.tsx
a1f1029 to
7b05b8f
Compare
7b05b8f to
80c0b10
Compare
Coverage Report for CI Build 28501806572Warning Build has drifted: This PR's base is out of sync with its target branch, so coverage data may include unrelated changes. Coverage remained the same at 43.819%Details
Uncovered ChangesNo uncovered changes found. Coverage RegressionsNo coverage regressions found. Coverage Stats
💛 - Coveralls |
What
Opens the Stripe customer portal in the same tab from the admin org Billing side panel (the pencil action from #1715), instead of a new tab.
This matches the client app's billing flow: the admin page navigates away to Stripe, and when the super user finishes (via Stripe's return link or the browser back button) they land back on a freshly loaded admin page — so any billing address / details they edited show up without any manual refresh.
Why
The new-tab approach left the admin panel showing the stale address after an edit, because the original tab was never reloaded. Rather than adding tab-visibility refetch logic, this mirrors the client app and lets a normal page navigation do the work.
How
window.open(and its popup-blocker workaround) withwindow.location.href = checkoutUrl, the same pattern used in the client billing view.fetchBillingAccountDetailscontext call).successUrl/cancelUrlremain the current admin page, so Stripe returns the user here.Test plan
eslintpasses on the changed file.