Skip to content

✨ refactor(wallet): Top-up layout to embed subscription plans into the recharge card tabs#2878

Merged
Calcium-Ion merged 2 commits into
mainfrom
feat/hide-subscription-card-when-no-plans
Feb 6, 2026
Merged

✨ refactor(wallet): Top-up layout to embed subscription plans into the recharge card tabs#2878
Calcium-Ion merged 2 commits into
mainfrom
feat/hide-subscription-card-when-no-plans

Conversation

@t0ng7u
Copy link
Copy Markdown
Collaborator

@t0ng7u t0ng7u commented Feb 6, 2026

  • Defaulting to subscriptions when available and avoiding initial flash when no plans exist.
  • Adjust the wide-screen layout to place wallet and invite sections side by side, simplify the subscription header and controls, and add padding to prevent card borders from clipping.
  • Update related i18n strings by adding the new tab label and removing the obsolete subscription blurb.
image

Summary by CodeRabbit

  • New Features

    • Added tabbed interface to view subscription plans and top-up options in a single screen.
  • UI/UX Improvements

    • Reorganized layout for clearer navigation between subscription and top-up sections.
    • Enhanced billing preference header with refresh functionality.
    • Consolidated subscription management features into the recharge card.
  • Localization

    • Updated UI labels across all supported languages to reflect the new top-up feature naming.

QuentinHsu and others added 2 commits February 6, 2026 20:27
…e recharge card tabs

- Defaulting to subscriptions when available and avoiding initial flash when no plans exist.
- Adjust the wide-screen layout to place wallet and invite sections side by side, simplify the subscription header and controls, and add padding to prevent card borders from clipping.
- Update related i18n strings by adding the new tab label and removing the obsolete subscription blurb.
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Feb 6, 2026

Walkthrough

The PR restructures the TopUp component by integrating SubscriptionPlansCard as a tabbed interface within RechargeCard, consolidating subscription management logic into the recharge card, simplifying the parent layout from 12-column to 2-column grid, and renaming translation keys across 6 locale files to reflect "quota top-up" terminology.

Changes

Cohort / File(s) Summary
TopUp UI Restructuring
web/src/components/topup/RechargeCard.jsx
Added tabbed UI (Tabs/TabPane) with subscription and topup tabs, introduced activeTab state management, imported SubscriptionPlansCard, and expanded public props to accept subscription data (subscriptionLoans, subscriptionPlans, billingPreference, activeSubscriptions, allSubscriptions, reloadSubscriptionSelf) and callbacks. Extracted topupContent as reusable constant and added conditional rendering logic based on subscription availability.
TopUp UI Restructuring
web/src/components/topup/SubscriptionPlansCard.jsx
Added new withCard prop (default true) to control Card wrapper rendering; reorganized header layout with billing preference Select and refresh Button; removed Avatar/Crown icon; adjusted grid classes and gaps to accommodate new structure; changed one button type from tertiary to primary in purchase button.
TopUp UI Restructuring
web/src/components/topup/index.jsx
Removed SubscriptionPlansCard import and left-column rendering; refactored grid layout from 12-column to 2-column; moved subscription-related props (subscriptionLoading, subscriptionPlans, billingPreference, onChangeBillingPreference, activeSubscriptions, allSubscriptions, reloadSubscriptionSelf) from separate panel to RechargeCard; retained existing modals and their wiring.
Internationalization
web/src/i18n/locales/en.json, fr.json, ja.json, ru.json, vi.json, zh.json
Renamed translation key from "购买订阅获得模型额度/次数" to "额度充值" with locale-specific values: EN: "Quota Top-up", FR: "Recharge de quota", JA: "クォータ補充", RU: "Пополнение квоты", VI: "Nạp hạn mức", ZH: "额度充值".

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested reviewers

  • seefs001
  • Calcium-Ion

Poem

🐰 Tabs now dance where columns stood so tall,
Subscriptions nestled in the Recharge hall,
Quota top-ups whisper cross the globe's tongue,
A simpler grid, where tabbed flows have sprung! ✨

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main refactoring work: embedding subscription plans into recharge card tabs. It is clear, specific, and directly relates to the primary changes across multiple files.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/hide-subscription-card-when-no-plans

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@t0ng7u t0ng7u requested a review from Calcium-Ion February 6, 2026 16:15
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@web/src/components/topup/SubscriptionPlansCard.jsx`:
- Around line 320-345: The header controls in SubscriptionPlansCard (the Select
with value billingPreference and the icon-only Button using RefreshCw) lack
accessible names; add aria-label (or aria-labelledby) props to the Select (e.g.,
aria-label={t('billing preference')} or link it to a visible label) and to the
refresh Button (e.g., aria-label={t('刷新/刷新列表' or t('refresh')}) so screen
readers can announce them; ensure the Button keeps its icon-only UI but includes
the aria-label and consider adding a title prop or Tooltip for visual hinting
while using the existing refreshing state and handleRefresh handler.

Comment on lines +320 to +345
<div className='flex items-center gap-2'>
<Select
value={billingPreference}
onChange={onChangeBillingPreference}
size='small'
optionList={[
{ value: 'subscription_first', label: t('优先订阅') },
{ value: 'wallet_first', label: t('优先钱包') },
{ value: 'subscription_only', label: t('仅用订阅') },
{ value: 'wallet_only', label: t('仅用钱包') },
]}
/>
<Button
size='small'
theme='light'
type='tertiary'
icon={
<RefreshCw
size={12}
className={refreshing ? 'animate-spin' : ''}
/>
}
onClick={handleRefresh}
loading={refreshing}
/>
</div>
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Add accessible labels to header controls. The billing preference Select and icon-only refresh Button should expose an accessible name for screen readers.

🔧 Suggested fix
-                <Select
+                <Select
+                  aria-label={t('计费偏好')}
                   value={billingPreference}
                   onChange={onChangeBillingPreference}
                   size='small'
                   optionList={[
                     { value: 'subscription_first', label: t('优先订阅') },
                     { value: 'wallet_first', label: t('优先钱包') },
                     { value: 'subscription_only', label: t('仅用订阅') },
                     { value: 'wallet_only', label: t('仅用钱包') },
                   ]}
                 />
                 <Button
                   size='small'
                   theme='light'
                   type='tertiary'
+                  aria-label={t('刷新')}
                   icon={
                     <RefreshCw
                       size={12}
                       className={refreshing ? 'animate-spin' : ''}
                     />
                   }
🤖 Prompt for AI Agents
In `@web/src/components/topup/SubscriptionPlansCard.jsx` around lines 320 - 345,
The header controls in SubscriptionPlansCard (the Select with value
billingPreference and the icon-only Button using RefreshCw) lack accessible
names; add aria-label (or aria-labelledby) props to the Select (e.g.,
aria-label={t('billing preference')} or link it to a visible label) and to the
refresh Button (e.g., aria-label={t('刷新/刷新列表' or t('refresh')}) so screen
readers can announce them; ensure the Button keeps its icon-only UI but includes
the aria-label and consider adding a title prop or Tooltip for visual hinting
while using the existing refreshing state and handleRefresh handler.

@Calcium-Ion Calcium-Ion merged commit e57bac7 into main Feb 6, 2026
1 check passed
@Calcium-Ion Calcium-Ion deleted the feat/hide-subscription-card-when-no-plans branch February 22, 2026 07:57
ennnnny pushed a commit to ennnnny/new-api that referenced this pull request Mar 17, 2026
…iption-card-when-no-plans

✨ refactor(wallet): Top-up layout to embed subscription plans into the recharge card tabs
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.

3 participants