split account modal into multiple tabs#3986
Conversation
WalkthroughAccountModal is refactored from a monolithic single-renderer into a tab-driven modal that dynamically shows account, stats, and games tabs only when the user is linked. The modal detects linked status, defines tab configuration, routes content through a tab renderer, and displays dedicated panels with empty-state fallbacks. Five new localization keys support the tab labels and empty messages. ChangesTab-Driven Refactor
Possibly Related PRs
Estimated Code Review Effort🎯 3 (Moderate) | ⏱️ ~25 minutes Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. 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 (1)
src/client/AccountModal.ts (1)
101-110: ⚡ Quick winUse a typed union for
AccountModaltab keys (narrow before routing).
AccountModal.tscurrently routes on plain string literals ("account" | "stats" | "games") inmodalConfig(),renderBody(tab: string), andrenderTab(tab: string). KeeprenderBody(tab: string)as-is to matchBaseModal’s(tab: string)signature, but narrow to aAccountModalTabunion before theswitch(and type-check thetabsarray withsatisfiesto avoid unsafe casts).Proposed shape
type AccountModalTab = "account" | "stats" | "games"; function isAccountModalTab(tab: string): tab is AccountModalTab { return tab === "account" || tab === "stats" || tab === "games"; } protected modalConfig() { if (this.isLoadingUser || !this.isLinkedAccount()) return {}; const tabs = [ { key: "account", label: translateText("account_modal.tab_account") }, { key: "stats", label: translateText("account_modal.tab_stats") }, { key: "games", label: translateText("account_modal.tab_games") }, ] satisfies Array<{ key: AccountModalTab; label: string }>; return { tabs }; } protected renderBody(tab: string) { const safeTab = isAccountModalTab(tab) ? tab : "account"; // ... return this.renderTab(safeTab); } private renderTab(tab: AccountModalTab): TemplateResult { switch (tab) { case "stats": return this.renderStatsTab(); case "games": return this.renderGamesTab(); default: return this.renderAccountTab(); } }🤖 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 `@src/client/AccountModal.ts` around lines 101 - 110, Create a narrow union type AccountModalTab ("account" | "stats" | "games") and a type guard isAccountModalTab(tab: string): tab is AccountModalTab; in modalConfig() replace the untyped tabs array with a const tabs = [...] that is type-checked using satisfies Array<{ key: AccountModalTab; label: string }>; in renderBody(tab: string) validate the incoming tab with isAccountModalTab and fall back to "account" (e.g. const safeTab = isAccountModalTab(tab) ? tab : "account") before calling renderTab; change renderTab signature to renderTab(tab: AccountModalTab) and switch on the narrowed AccountModalTab to call renderAccountTab, renderStatsTab, or renderGamesTab accordingly.
🤖 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.
Nitpick comments:
In `@src/client/AccountModal.ts`:
- Around line 101-110: Create a narrow union type AccountModalTab ("account" |
"stats" | "games") and a type guard isAccountModalTab(tab: string): tab is
AccountModalTab; in modalConfig() replace the untyped tabs array with a const
tabs = [...] that is type-checked using satisfies Array<{ key: AccountModalTab;
label: string }>; in renderBody(tab: string) validate the incoming tab with
isAccountModalTab and fall back to "account" (e.g. const safeTab =
isAccountModalTab(tab) ? tab : "account") before calling renderTab; change
renderTab signature to renderTab(tab: AccountModalTab) and switch on the
narrowed AccountModalTab to call renderAccountTab, renderStatsTab, or
renderGamesTab accordingly.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 9c8b6ad5-0113-4f0f-9f2c-126845b00082
📒 Files selected for processing (2)
resources/lang/en.jsonsrc/client/AccountModal.ts
Description:
The account modal was getting too large, too much scrolling.
Please complete the following:
Please put your Discord username so you can be contacted if a bug or regression is found:
evan