diff --git a/docs/superpowers/plans/2026-08-30-wallet-plan-limit-summary.md b/docs/superpowers/plans/2026-08-30-wallet-plan-limit-summary.md new file mode 100644 index 000000000000..204e42b8cf98 --- /dev/null +++ b/docs/superpowers/plans/2026-08-30-wallet-plan-limit-summary.md @@ -0,0 +1,223 @@ +# Wallet Plan Limit Summary Implementation Plan + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. + +**Goal:** Make the authenticated wallet's plan-card short-window limits use the approved pricing-card panel and copy while keeping live usage meters unchanged. + +**Architecture:** Keep `PlanLimitSummary` as the single presentation boundary for `window_5h_amount` and `window_week_amount`. Convert quota units to fixed-USD strings, choose a combined or single translated sentence from the available positive windows, and render one responsive tinted panel. Reuse the existing `All models` key and add the three short-term sentence keys to every console locale; no plan values are hardcoded in the UI. + +**Tech Stack:** React 19, TypeScript, react-i18next, Tailwind CSS, Bun test, ESLint, TypeScript project references. + +--- + +### Task 1: Lock the approved summary contract with failing tests + +**Files:** +- Modify: `web/default/src/features/wallet/components/subscription-plans-card.test.tsx:404-451` +- Modify: `web/default/src/features/wallet/components/subscription-plans-card.test.tsx` (add a focused direct-render helper near the existing wallet render helpers) + +- [x] **Step 1: Replace old independent-box assertions with panel assertions** + +In the existing `renders migrated monthly quota values as strike-through prices for staging plans` test, keep the six dollar-value assertions and replace the old label assertions with: + +~~~tsx +expect(html).toContain('data-plan-limit-summary="true"') +expect(html).toContain('data-plan-limit-label="all-models"') +expect(html).toContain('Short-term caps: $8 / 5h · $12 / 7d') +expect(html).toContain('Short-term caps: $18 / 5h · $45 / 7d') +expect(html).toContain('Short-term caps: $78 / 5h · $220 / 7d') +expect(html).not.toContain('5-hour window limit (USD)') +expect(html).not.toContain('7-day window limit (USD)') +~~~ + +The existing `data-plan-limit="5h"` and `data-plan-limit="7d"` checks should be removed because the compact summary has one sentence rather than two independent boxes. + +Also update the later `renders current monthly and short-window usage meters with short windows side by side` test: keep its `data-wallet-usage-meter` assertions (those protect the live meters), but replace its two `data-plan-limit` assertions with one `data-plan-limit-summary="true"` assertion so the test does not depend on the removed box instrumentation. + +- [x] **Step 2: Add a direct renderer and single-window test** + +Import `PlanLimitSummary` beside the other wallet components and add this helper beside `renderWalletCardWithPlans`: + +~~~tsx +function renderPlanLimitSummary(plan: { + window_5h_amount?: number + window_week_amount?: number +}) { + return renderToStaticMarkup( + + + + ) +} +~~~ + +Add this test in the wallet-card describe block: + +~~~tsx +test('renders only the configured window in a compact summary', () => { + const html = renderPlanLimitSummary({ window_5h_amount: 4_000_000 }) + + expect(html).toContain('data-plan-limit-summary="true"') + expect(html).toContain('Short-term cap: $8 / 5h') + expect(html).not.toContain('7d') + expect(html).not.toContain('5-hour window limit (USD)') +}) +~~~ + +- [x] **Step 3: Run the focused test and verify the expected red state** + +From `web/default`, run: + +~~~bash +bun test src/features/wallet/components/subscription-plans-card.test.tsx +~~~ + +Expected: the new assertions fail because the current renderer emits two labeled boxes and no compact-panel marker or `Short-term ...` sentence. Fix only test setup errors; do not change production code before observing this feature failure. + +### Task 2: Implement the compact, data-driven summary and localized copy + +**Files:** +- Modify: `web/default/src/features/wallet/components/plan-limit-summary.tsx:24-77` +- Modify: `web/default/src/i18n/locales/en.json` +- Modify: `web/default/src/i18n/locales/zh.json` +- Modify: `web/default/src/i18n/locales/fr.json` +- Modify: `web/default/src/i18n/locales/ru.json` +- Modify: `web/default/src/i18n/locales/ja.json` +- Modify: `web/default/src/i18n/locales/vi.json` +- Modify: `web/default/src/i18n/locales/es.json` +- Modify: `web/default/src/i18n/locales/pt.json` + +- [x] **Step 1: Reuse the existing label key and add three real translations** + +The `All models` key already exists in every locale and should be reused. Add these three entries to every locale's `translation` object. Keep placeholder names exactly `fiveHour`, `week`, and `value`: + +~~~json +"Short-term cap: {{value}} / 5h": "Short-term cap: {{value}} / 5h", +"Short-term cap: {{value}} / 7d": "Short-term cap: {{value}} / 7d", +"Short-term caps: {{fiveHour}} / 5h · {{week}} / 7d": "Short-term caps: {{fiveHour}} / 5h · {{week}} / 7d" +~~~ + +Use these translated values in the non-English files: + +~~~text +zh: 短期上限:{{value}} / 5 小时; 短期上限:{{value}} / 7 天; 短期上限:{{fiveHour}} / 5 小时 · {{week}} / 7 天 +fr: Plafond à court terme : {{value}} / 5 h; Plafond à court terme : {{value}} / 7 j; Plafonds à court terme : {{fiveHour}} / 5 h · {{week}} / 7 j +ru: Краткосрочный лимит: {{value}} / 5 ч; Краткосрочный лимит: {{value}} / 7 д; Краткосрочные лимиты: {{fiveHour}} / 5 ч · {{week}} / 7 д +ja: 短期上限:{{value}} / 5時間; 短期上限:{{value}} / 7日; 短期上限:{{fiveHour}} / 5時間 · {{week}} / 7日 +vi: Hạn mức ngắn hạn: {{value}} / 5 giờ; Hạn mức ngắn hạn: {{value}} / 7 ngày; Hạn mức ngắn hạn: {{fiveHour}} / 5 giờ · {{week}} / 7 ngày +es: Límite a corto plazo: {{value}} / 5 h; Límite a corto plazo: {{value}} / 7 d; Límites a corto plazo: {{fiveHour}} / 5 h · {{week}} / 7 d +pt: Limite de curto prazo: {{value}} / 5 h; Limite de curto prazo: {{value}} / 7 d; Limites de curto prazo: {{fiveHour}} / 5 h · {{week}} / 7 d +~~~ + +The three values in each line are ordered as singular 5h, singular 7d, combined. + +- [x] **Step 2: Refactor `PlanLimitSummary` to one responsive panel** + +Keep `formatUSDQuota` and positive-value filtering. Build a typed `windows` array, return `null` when it is empty, choose the combined key when both windows exist and the matching singular key otherwise, then render one panel: + +~~~tsx +const windows = [ + { key: '5h' as const, amount: Number(props.plan.window_5h_amount || 0) }, + { key: '7d' as const, amount: Number(props.plan.window_week_amount || 0) }, +].filter((window) => window.amount > 0) + +if (windows.length === 0) return null + +let summary: string +if (windows.length === 2) { + summary = t('Short-term caps: {{fiveHour}} / 5h · {{week}} / 7d', { + fiveHour: formatUSDQuota(windows[0].amount), + week: formatUSDQuota(windows[1].amount), + }) +} else if (windows[0].key === '5h') { + summary = t('Short-term cap: {{value}} / 5h', { + value: formatUSDQuota(windows[0].amount), + }) +} else { + summary = t('Short-term cap: {{value}} / 7d', { + value: formatUSDQuota(windows[0].amount), + }) +} + +return ( +
+
+ {t('All models')} +
+

+ {summary} +

+
+) +~~~ + +Do not change `CurrentPlanCard`, `UsageWindowMeter`, or the `PlanLimitSummary` call site. + +- [x] **Step 3: Run the focused test and verify green** + +~~~bash +bun test src/features/wallet/components/subscription-plans-card.test.tsx +~~~ + +Expected: all tests in the file pass, including combined Go/Pro/Max values, single-window rendering, fixed-USD formatting, and existing current-plan meter assertions. + +### Task 3: Synchronize translations and verify the repository + +**Files:** +- Generated/modified: `web/default/src/i18n/locales/*.json` +- Generated/modified: `web/default/src/i18n/locales/_reports/*` and `_extras/*` as produced by the sync script + +- [x] **Step 1: Normalize locale ordering and inspect the report** + +~~~bash +bun run i18n:sync +~~~ + +Expected: exit code 0, no missing keys in `_sync-report.json`, and no newly flagged untranslated values for the three added keys. Correct a translation before continuing if the report flags one. + +- [x] **Step 2: Run typecheck and touched-file lint** + +~~~bash +bun run typecheck +bunx eslint src/features/wallet/components/plan-limit-summary.tsx src/features/wallet/components/subscription-plans-card.test.tsx +~~~ + +Expected: both commands exit 0 with no TypeScript or ESLint errors. + +- [x] **Step 3: Check the diff and inspect a local preview** + +~~~bash +git diff --check +git status --short +bun run dev --host 127.0.0.1 +~~~ + +Inspect the wallet route at desktop and narrow widths. Each plan card must have one lavender panel with `ALL MODELS` and one caps sentence; the current-plan monthly/5-hour/7-day meters must remain side-by-side and unchanged. + +Observed in this run: Rsbuild's dev compiler rebuilt the console successfully, and the static wallet render/tests verified the panel structure. The connected local browser kept an empty React root, so an interactive screenshot comparison remains a preview-environment gap. + +- [x] **Step 4: Commit the implementation with the Lore protocol** + +After verification: + +~~~bash +git add web/default/src/features/wallet/components/plan-limit-summary.tsx web/default/src/features/wallet/components/subscription-plans-card.test.tsx web/default/src/i18n/locales +git commit -m "Match wallet plan limits to pricing-card copy" -m "Present short-window caps in one localized pricing-style panel while preserving live usage meters. + +Constraint: all user-visible console copy must exist in all eight locales +Rejected: adding a Tools Credits section | wallet plan data has no matching entitlement +Confidence: high +Scope-risk: narrow +Directive: keep current-plan UsageWindowMeter layout unchanged +Tested: focused Bun test; i18n sync; typecheck; ESLint; git diff --check +Not-tested: production deployment" +~~~ diff --git a/docs/superpowers/specs/2026-08-30-wallet-plan-limit-summary-design.md b/docs/superpowers/specs/2026-08-30-wallet-plan-limit-summary-design.md new file mode 100644 index 000000000000..cb95ad438f84 --- /dev/null +++ b/docs/superpowers/specs/2026-08-30-wallet-plan-limit-summary-design.md @@ -0,0 +1,74 @@ +# Wallet plan limit summary aligned with pricing-card copy + +## Context + +The authenticated wallet page currently renders each plan's 5-hour and 7-day +limits as two separate bordered boxes. The public pricing cards already use a +compact purple information panel with an `ALL MODELS` label and one +short-term-cap sentence. The wallet should use the same visual language while +preserving its live usage meters. + +## Goals + +1. Make the Go, Pro, and Max plan-card limit summary visually match the pricing + card reference: tinted panel, compact hierarchy, and a single short-term + caps line. +2. Keep the limits data-driven from `window_5h_amount` and + `window_week_amount`; do not duplicate plan values in the frontend. +3. Localize the new user-visible copy in all eight console locales. +4. Leave the current-plan monthly, 5-hour, and 7-day progress meters unchanged. + +## Non-goals + +- Do not change backend quota enforcement or API responses. +- Do not change the current-plan progress-bar layout. +- Do not add the website card's Tools Credits section to the wallet; the wallet + plan projection does not expose a corresponding entitlement. +- Do not change plan prices, discounts, or checkout behavior. + +## Design + +`PlanLimitSummary` remains the sole renderer for short-window limits on the +plan cards. It will: + +- filter out zero/negative windows as it does today; +- render one `bg-*`/bordered rounded panel when at least one limit exists; +- show a compact uppercase `All models` label; +- render a localized sentence with each available limit in USD and its period + (`5h` and/or `7d`), separated by `·`; +- allow the sentence to wrap on narrow screens without introducing a second + grid row. + +When only one window is present, the sentence contains only that window. The +current-plan card continues to use `UsageWindowMeter` for live usage and reset +times; this change does not touch that component or its layout. + +## Internationalization + +Reuse the existing `All models` source key and add the following three keys to +all eight locale files (English is the source language; each other locale +receives a real translation): + +- `Short-term caps: {{fiveHour}} / 5h · {{week}} / 7d` +- `Short-term cap: {{value}} / 5h` +- `Short-term cap: {{value}} / 7d` + +The component chooses the singular key when only one window is available and +the combined key when both are present. Existing limit-label keys remain in +the locale files for the current-plan meter and other consumers. + +## Verification + +- Update `subscription-plans-card.test.tsx` to assert the compact panel and + combined/single-window copy, and to reject the old independent-box labels. +- Run the focused wallet component tests. +- Run `bun run typecheck` and the touched-file lint check from `web/default`. +- Run `bun run i18n:sync` and inspect the generated untranslated reports. +- Start the console preview and verify desktop and narrow layouts against the + supplied reference image. + +## Multi-node/deployment impact + +This is console-only presentation code. It does not alter router billing, +Redis counters, database state, or API contracts. A console frontend build is +required; router deployment is not required. diff --git a/web/default/src/features/wallet/components/plan-limit-summary.tsx b/web/default/src/features/wallet/components/plan-limit-summary.tsx index 919c0efa08d7..8b9fe865f915 100644 --- a/web/default/src/features/wallet/components/plan-limit-summary.tsx +++ b/web/default/src/features/wallet/components/plan-limit-summary.tsx @@ -38,40 +38,49 @@ function formatUSDQuota(quota: number): string { export function PlanLimitSummary(props: PlanLimitSummaryProps) { const { t } = useTranslation() - const items = [ + const windows = [ + { key: '5h' as const, amount: Number(props.plan.window_5h_amount || 0) }, { - key: '5h', - label: t('5-Hour Window'), - amount: Number(props.plan.window_5h_amount || 0), - }, - { - key: '7d', - label: t('7 Days'), + key: '7d' as const, amount: Number(props.plan.window_week_amount || 0), }, - ].filter((item) => item.amount > 0) + ].filter((window) => window.amount > 0) + + if (windows.length === 0) return null - if (items.length === 0) return null + let summary: string + if (windows.length === 2) { + summary = t('Short-term caps: {{fiveHour}} / 5h · {{week}} / 7d', { + fiveHour: formatUSDQuota(windows[0].amount), + week: formatUSDQuota(windows[1].amount), + }) + } else if (windows[0].key === '5h') { + summary = t('Short-term cap: {{value}} / 5h', { + value: formatUSDQuota(windows[0].amount), + }) + } else { + summary = t('Short-term cap: {{value}} / 7d', { + value: formatUSDQuota(windows[0].amount), + }) + } return ( -
- {items.map((item) => ( -
-
{item.label}
-
- {formatUSDQuota(item.amount)} -
-
- ))} -
+
+ {t('All models')} +
+

+ {summary} +

+ ) } diff --git a/web/default/src/features/wallet/components/subscription-plans-card.test.tsx b/web/default/src/features/wallet/components/subscription-plans-card.test.tsx index afc14751b2c6..92a20b09e737 100644 --- a/web/default/src/features/wallet/components/subscription-plans-card.test.tsx +++ b/web/default/src/features/wallet/components/subscription-plans-card.test.tsx @@ -46,6 +46,7 @@ import { CurrentPlanCard, CurrentPlanRenewalDialogContent, } from './current-plan-card' +import { PlanLimitSummary } from './plan-limit-summary' import { PlanPurchaseDialogContent } from './plan-purchase-dialog' import { SubscriptionPlansCard } from './subscription-plans-card' @@ -193,6 +194,17 @@ function renderWalletCardWithPlans( ) } +function renderPlanLimitSummary(plan: { + window_5h_amount?: number + window_week_amount?: number +}) { + return renderToStaticMarkup( + + + + ) +} + function renderWalletCard(selfData = normalizeSelfSubscriptionData(undefined)) { return renderWalletCardWithPlans(plans, selfData) } @@ -438,11 +450,13 @@ describe('SubscriptionPlansCard flexible wallet plan UI', () => { expect(html).toContain('data-subscription-reference-price="$450"') expect(html).not.toContain('data-subscription-reference-price="$45"') expect(html).not.toContain('data-subscription-reference-price="$300"') - expect(html).toContain('data-plan-limit="5h"') - expect(html).toContain('data-plan-limit="7d"') - expect(html).toContain('5-Hour Window') - expect(html).toContain('7 Days') - expect(html).not.toContain('window limit (USD)') + expect(html).toContain('data-plan-limit-summary="true"') + expect(html).toContain('data-plan-limit-label="all-models"') + expect(html).toContain('Short-term caps: $8 / 5h · $12 / 7d') + expect(html).toContain('Short-term caps: $18 / 5h · $45 / 7d') + expect(html).toContain('Short-term caps: $78 / 5h · $220 / 7d') + expect(html).not.toContain('5-hour window limit (USD)') + expect(html).not.toContain('7-day window limit (USD)') expect(html).toContain('$8') expect(html).toContain('$12') expect(html).toContain('$18') @@ -451,6 +465,15 @@ describe('SubscriptionPlansCard flexible wallet plan UI', () => { expect(html).toContain('$220') }) + test('renders only the configured window in a compact summary', () => { + const html = renderPlanLimitSummary({ window_5h_amount: 4_000_000 }) + + expect(html).toContain('data-plan-limit-summary="true"') + expect(html).toContain('Short-term cap: $8 / 5h') + expect(html).not.toContain('7d') + expect(html).not.toContain('5-hour window limit (USD)') + }) + test('keeps the Pro most-popular badge visible when there is an active plan', () => { const html = renderWalletCard( normalizeSelfSubscriptionData({ @@ -604,8 +627,7 @@ describe('SubscriptionPlansCard flexible wallet plan UI', () => { expect(html).not.toContain( 'data-wallet-usage-meter="Media generation credits"' ) - expect(html).toContain('data-plan-limit="5h"') - expect(html).toContain('data-plan-limit="7d"') + expect(html).toContain('data-plan-limit-summary="true"') expect(html).toContain('$18') expect(html).toContain('$45') expect(html).not.toContain('Media generation credits') diff --git a/web/default/src/i18n/locales/en.json b/web/default/src/i18n/locales/en.json index 6a67d2f43eb8..546f1f81fd66 100644 --- a/web/default/src/i18n/locales/en.json +++ b/web/default/src/i18n/locales/en.json @@ -4208,6 +4208,9 @@ "Share your link and earn rewards": "Share your link and earn rewards", "Shared configuration for all payment gateways": "Shared configuration for all payment gateways", "Shorten": "Shorten", + "Short-term cap: {{value}} / 5h": "Short-term cap: {{value}} / 5h", + "Short-term cap: {{value}} / 7d": "Short-term cap: {{value}} / 7d", + "Short-term caps: {{fiveHour}} / 5h · {{week}} / 7d": "Short-term caps: {{fiveHour}} / 5h · {{week}} / 7d", "Show": "Show", "Show agreement notice on sign-in and sign-up pages": "Show agreement notice on sign-in and sign-up pages", "Show All": "Show All", diff --git a/web/default/src/i18n/locales/es.json b/web/default/src/i18n/locales/es.json index 35aad880d1e9..580911a2766d 100644 --- a/web/default/src/i18n/locales/es.json +++ b/web/default/src/i18n/locales/es.json @@ -4208,6 +4208,9 @@ "Share your link and earn rewards": "Share your link and earn rewards", "Shared configuration for all payment gateways": "Shared configuration for all payment gateways", "Shorten": "Shorten", + "Short-term cap: {{value}} / 5h": "Límite a corto plazo: {{value}} / 5 h", + "Short-term cap: {{value}} / 7d": "Límite a corto plazo: {{value}} / 7 d", + "Short-term caps: {{fiveHour}} / 5h · {{week}} / 7d": "Límites a corto plazo: {{fiveHour}} / 5 h · {{week}} / 7 d", "Show": "Show", "Show agreement notice on sign-in and sign-up pages": "Show agreement notice on sign-in and sign-up pages", "Show All": "Show All", diff --git a/web/default/src/i18n/locales/fr.json b/web/default/src/i18n/locales/fr.json index 954a3ed83460..b6a6e39bfed3 100644 --- a/web/default/src/i18n/locales/fr.json +++ b/web/default/src/i18n/locales/fr.json @@ -4208,6 +4208,9 @@ "Share your link and earn rewards": "Partagez votre lien et gagnez des récompenses", "Shared configuration for all payment gateways": "Configuration partagée pour toutes les passerelles de paiement", "Shorten": "Raccourcir", + "Short-term cap: {{value}} / 5h": "Plafond à court terme : {{value}} / 5 h", + "Short-term cap: {{value}} / 7d": "Plafond à court terme : {{value}} / 7 j", + "Short-term caps: {{fiveHour}} / 5h · {{week}} / 7d": "Plafonds à court terme : {{fiveHour}} / 5 h · {{week}} / 7 j", "Show": "Afficher", "Show agreement notice on sign-in and sign-up pages": "Afficher l’avis d’accord sur les pages de connexion et d’inscription", "Show All": "Tout afficher", diff --git a/web/default/src/i18n/locales/ja.json b/web/default/src/i18n/locales/ja.json index a81d1fd5f0be..dca05bc74d79 100644 --- a/web/default/src/i18n/locales/ja.json +++ b/web/default/src/i18n/locales/ja.json @@ -4208,6 +4208,9 @@ "Share your link and earn rewards": "リンクを共有して報酬を獲得", "Shared configuration for all payment gateways": "すべての決済ゲートウェイの共有設定", "Shorten": "短縮", + "Short-term cap: {{value}} / 5h": "短期上限:{{value}} / 5時間", + "Short-term cap: {{value}} / 7d": "短期上限:{{value}} / 7日", + "Short-term caps: {{fiveHour}} / 5h · {{week}} / 7d": "短期上限:{{fiveHour}} / 5時間 · {{week}} / 7日", "Show": "表示", "Show agreement notice on sign-in and sign-up pages": "ログイン・登録ページに同意のお知らせを表示", "Show All": "すべて表示", diff --git a/web/default/src/i18n/locales/pt.json b/web/default/src/i18n/locales/pt.json index a24039c9d76e..ad668ccdee1d 100644 --- a/web/default/src/i18n/locales/pt.json +++ b/web/default/src/i18n/locales/pt.json @@ -4208,6 +4208,9 @@ "Share your link and earn rewards": "Compartilhe seu link e ganhe recompensas", "Shared configuration for all payment gateways": "Configuração compartilhada para todos os gateways de pagamento", "Shorten": "Encurtar", + "Short-term cap: {{value}} / 5h": "Limite de curto prazo: {{value}} / 5 h", + "Short-term cap: {{value}} / 7d": "Limite de curto prazo: {{value}} / 7 d", + "Short-term caps: {{fiveHour}} / 5h · {{week}} / 7d": "Limites de curto prazo: {{fiveHour}} / 5 h · {{week}} / 7 d", "Show": "Mostrar", "Show agreement notice on sign-in and sign-up pages": "Mostrar aviso de contrato nas páginas de login e inscrição", "Show All": "Mostrar tudo", diff --git a/web/default/src/i18n/locales/ru.json b/web/default/src/i18n/locales/ru.json index 8e34d058adc3..38050f8ebf9b 100644 --- a/web/default/src/i18n/locales/ru.json +++ b/web/default/src/i18n/locales/ru.json @@ -4208,6 +4208,9 @@ "Share your link and earn rewards": "Поделитесь своей ссылкой и получайте вознаграждения", "Shared configuration for all payment gateways": "Общая конфигурация для всех платежных шлюзов", "Shorten": "Сократить", + "Short-term cap: {{value}} / 5h": "Краткосрочный лимит: {{value}} / 5 ч", + "Short-term cap: {{value}} / 7d": "Краткосрочный лимит: {{value}} / 7 д", + "Short-term caps: {{fiveHour}} / 5h · {{week}} / 7d": "Краткосрочные лимиты: {{fiveHour}} / 5 ч · {{week}} / 7 д", "Show": "Показать", "Show agreement notice on sign-in and sign-up pages": "Показывать уведомление о соглашении на страницах входа и регистрации", "Show All": "Показать все", diff --git a/web/default/src/i18n/locales/vi.json b/web/default/src/i18n/locales/vi.json index 84b523e1cc2a..f2f9c43a3707 100644 --- a/web/default/src/i18n/locales/vi.json +++ b/web/default/src/i18n/locales/vi.json @@ -4208,6 +4208,9 @@ "Share your link and earn rewards": "Chia sẻ liên kết của bạn và kiếm phần thưởng", "Shared configuration for all payment gateways": "Cấu hình chung cho tất cả các cổng thanh toán", "Shorten": "Rút gọn", + "Short-term cap: {{value}} / 5h": "Hạn mức ngắn hạn: {{value}} / 5 giờ", + "Short-term cap: {{value}} / 7d": "Hạn mức ngắn hạn: {{value}} / 7 ngày", + "Short-term caps: {{fiveHour}} / 5h · {{week}} / 7d": "Hạn mức ngắn hạn: {{fiveHour}} / 5 giờ · {{week}} / 7 ngày", "Show": "Hiển thị", "Show agreement notice on sign-in and sign-up pages": "Hiển thị thông báo đồng ý trên trang đăng nhập và đăng ký", "Show All": "Hiển thị tất cả", diff --git a/web/default/src/i18n/locales/zh.json b/web/default/src/i18n/locales/zh.json index 698e896215d3..6bbd47dc21f7 100644 --- a/web/default/src/i18n/locales/zh.json +++ b/web/default/src/i18n/locales/zh.json @@ -4208,6 +4208,9 @@ "Share your link and earn rewards": "分享您的链接并赚取奖励", "Shared configuration for all payment gateways": "所有支付网关的共享配置", "Shorten": "缩词", + "Short-term cap: {{value}} / 5h": "短期上限:{{value}} / 5 小时", + "Short-term cap: {{value}} / 7d": "短期上限:{{value}} / 7 天", + "Short-term caps: {{fiveHour}} / 5h · {{week}} / 7d": "短期上限:{{fiveHour}} / 5 小时 · {{week}} / 7 天", "Show": "显示", "Show agreement notice on sign-in and sign-up pages": "在登录和注册页显示协议提示", "Show All": "显示全部",