Skip to content

Updated copy for once offers in Portal account page#26636

Merged
sagzy merged 1 commit intomainfrom
unify-account-page-copy
Mar 5, 2026
Merged

Updated copy for once offers in Portal account page#26636
sagzy merged 1 commit intomainfrom
unify-account-page-copy

Conversation

@sagzy
Copy link
Copy Markdown
Contributor

@sagzy sagzy commented Mar 2, 2026

closes https://linear.app/ghost/issue/BER-3393

  • aligned the copy for once offers with the repeating / free months offers:
    • Before "$4.00 - Next payment"
    • After: "$4.00/month - Ends {date}"
CleanShot 2026-03-02 at 11 50 53@2x

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Mar 2, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Bumps apps/portal/package.json version 2.64.16 → 2.64.17. Updates PaidAccountActions: getOfferLabel signature now accepts currentPeriodEnd and call sites pass subscription.current_period_end. Once-duration discount labeling now derives an end date from currentPeriodEnd; repeating discounts continue to use discount.end when present. Displayed price always includes the interval. Unit test updated to include currentPeriodEnd and assert the revised discounted label. Removes the "Next payment" translation key (empty string) from many portal locale JSON files.

Possibly related PRs

Suggested reviewers

  • mike182uk
  • cmraible
🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The PR title accurately reflects the primary change: updating the copy/messaging for once offers in the Portal account page to align with repeating offers.
Description check ✅ Passed The PR description is directly related to the changeset, explaining the specific copy updates (from 'Next payment' to 'Ends {date}') and their alignment across offer types.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch unify-account-page-copy

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.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 99aab91f16

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

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: 3

🧹 Nitpick comments (1)
apps/portal/test/unit/components/pages/AccountHomePage/paid-account-actions.test.js (1)

333-377: Add a fallback test when currentPeriodEnd is missing.

Given the new dependency on current_period_end, add one case with it unset and assert no invalid end-date text is rendered.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@apps/portal/test/unit/components/pages/AccountHomePage/paid-account-actions.test.js`
around lines 333 - 377, Add a new test case alongside the existing "displays
discounted price with 'Ends {date}' for once offers" that builds the same
product/member/subscription fixture but leaves currentPeriodEnd undefined (omit
the currentPeriodEnd field or set it to null) on the subscription and on the
discount end value, then render via setup({site, member}) and assert that the
discounted price is shown but no "Ends" text is present (e.g.,
queryByText(/Ends/) returns null or queryByTestId('offer-label') exists while
queryByText(/Ends \d+/) does not). Use the same helpers (getProductsData,
getSiteData, getMemberData, getSubscriptionData, getNextPaymentData,
getDiscountData, setup) so the new test mirrors the original except for the
missing currentPeriodEnd.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@apps/portal/src/components/pages/AccountHomePage/components/paid-account-actions.js`:
- Around line 62-65: The call to getOfferLabel dereferences
subscription.current_period_end without ensuring subscription exists (affecting
offerLabelStr); update the code that sets offerLabelStr to guard subscription
(e.g., use optional chaining or a fallback) so you pass a safe value for
currentPeriodEnd to getOfferLabel (or skip calling getOfferLabel when
subscription is falsy), and ensure any downstream use of offerLabelStr or
PlanLabel handles the no-subscription case consistently.
- Line 239: The offer label currently concatenates raw English interval strings
into displayedPrice (const displayedPrice =
`${formattedPrice}/${nextPayment.interval}`), which breaks localization; update
the construction of displayedPrice to use the translated interval instead of
nextPayment.interval (e.g., call your locale function/translator like t or
formatMessage with a key for the interval such as billing.interval.month/year or
similar) so formattedPrice is combined with the translated interval string
returned from the i18n helper used across the app.
- Around line 233-236: The duration label logic for discount.duration === 'once'
assumes currentPeriodEnd exists and calls getDateString(currentPeriodEnd), which
can produce an invalid date UI when currentPeriodEnd is missing; update the
branch in the component where durationLabel is set (referencing
discount.duration, currentPeriodEnd, durationLabel, getDateString and t) to
guard against a falsy currentPeriodEnd — e.g., if currentPeriodEnd is present
use t('Ends {offerEndDate}', {offerEndDate: getDateString(currentPeriodEnd)})
else use a safe fallback like t('Ends soon') (or another neutral string) so the
UI never shows an invalid date.

---

Nitpick comments:
In
`@apps/portal/test/unit/components/pages/AccountHomePage/paid-account-actions.test.js`:
- Around line 333-377: Add a new test case alongside the existing "displays
discounted price with 'Ends {date}' for once offers" that builds the same
product/member/subscription fixture but leaves currentPeriodEnd undefined (omit
the currentPeriodEnd field or set it to null) on the subscription and on the
discount end value, then render via setup({site, member}) and assert that the
discounted price is shown but no "Ends" text is present (e.g.,
queryByText(/Ends/) returns null or queryByTestId('offer-label') exists while
queryByText(/Ends \d+/) does not). Use the same helpers (getProductsData,
getSiteData, getMemberData, getSubscriptionData, getNextPaymentData,
getDiscountData, setup) so the new test mirrors the original except for the
missing currentPeriodEnd.

ℹ️ Review info

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1d29c50 and 99aab91f1646ff68ee3bb50d072541ce15832b24.

📒 Files selected for processing (66)
  • apps/portal/package.json
  • apps/portal/src/components/pages/AccountHomePage/components/paid-account-actions.js
  • apps/portal/test/unit/components/pages/AccountHomePage/paid-account-actions.test.js
  • ghost/i18n/locales/af/portal.json
  • ghost/i18n/locales/ar/portal.json
  • ghost/i18n/locales/bg/portal.json
  • ghost/i18n/locales/bn/portal.json
  • ghost/i18n/locales/bs/portal.json
  • ghost/i18n/locales/ca/portal.json
  • ghost/i18n/locales/context.json
  • ghost/i18n/locales/cs/portal.json
  • ghost/i18n/locales/da/portal.json
  • ghost/i18n/locales/de-CH/portal.json
  • ghost/i18n/locales/de/portal.json
  • ghost/i18n/locales/el/portal.json
  • ghost/i18n/locales/en/portal.json
  • ghost/i18n/locales/eo/portal.json
  • ghost/i18n/locales/es/portal.json
  • ghost/i18n/locales/et/portal.json
  • ghost/i18n/locales/eu/portal.json
  • ghost/i18n/locales/fa/portal.json
  • ghost/i18n/locales/fi/portal.json
  • ghost/i18n/locales/fr/portal.json
  • ghost/i18n/locales/gd/portal.json
  • ghost/i18n/locales/he/portal.json
  • ghost/i18n/locales/hi/portal.json
  • ghost/i18n/locales/hr/portal.json
  • ghost/i18n/locales/hu/portal.json
  • ghost/i18n/locales/id/portal.json
  • ghost/i18n/locales/is/portal.json
  • ghost/i18n/locales/it/portal.json
  • ghost/i18n/locales/ja/portal.json
  • ghost/i18n/locales/ko/portal.json
  • ghost/i18n/locales/kz/portal.json
  • ghost/i18n/locales/lt/portal.json
  • ghost/i18n/locales/lv/portal.json
  • ghost/i18n/locales/mk/portal.json
  • ghost/i18n/locales/mn/portal.json
  • ghost/i18n/locales/ms/portal.json
  • ghost/i18n/locales/nb/portal.json
  • ghost/i18n/locales/ne/portal.json
  • ghost/i18n/locales/nl/portal.json
  • ghost/i18n/locales/nn/portal.json
  • ghost/i18n/locales/pa/portal.json
  • ghost/i18n/locales/pl/portal.json
  • ghost/i18n/locales/pt-BR/portal.json
  • ghost/i18n/locales/pt/portal.json
  • ghost/i18n/locales/ro/portal.json
  • ghost/i18n/locales/ru/portal.json
  • ghost/i18n/locales/si/portal.json
  • ghost/i18n/locales/sk/portal.json
  • ghost/i18n/locales/sl/portal.json
  • ghost/i18n/locales/sq/portal.json
  • ghost/i18n/locales/sr-Cyrl/portal.json
  • ghost/i18n/locales/sr/portal.json
  • ghost/i18n/locales/sv/portal.json
  • ghost/i18n/locales/sw/portal.json
  • ghost/i18n/locales/ta/portal.json
  • ghost/i18n/locales/th/portal.json
  • ghost/i18n/locales/tr/portal.json
  • ghost/i18n/locales/uk/portal.json
  • ghost/i18n/locales/ur/portal.json
  • ghost/i18n/locales/uz/portal.json
  • ghost/i18n/locales/vi/portal.json
  • ghost/i18n/locales/zh-Hant/portal.json
  • ghost/i18n/locales/zh/portal.json
💤 Files with no reviewable changes (63)
  • ghost/i18n/locales/ar/portal.json
  • ghost/i18n/locales/de/portal.json
  • ghost/i18n/locales/fr/portal.json
  • ghost/i18n/locales/pl/portal.json
  • ghost/i18n/locales/nl/portal.json
  • ghost/i18n/locales/sv/portal.json
  • ghost/i18n/locales/ro/portal.json
  • ghost/i18n/locales/context.json
  • ghost/i18n/locales/hu/portal.json
  • ghost/i18n/locales/uz/portal.json
  • ghost/i18n/locales/ms/portal.json
  • ghost/i18n/locales/fa/portal.json
  • ghost/i18n/locales/kz/portal.json
  • ghost/i18n/locales/ne/portal.json
  • ghost/i18n/locales/bn/portal.json
  • ghost/i18n/locales/gd/portal.json
  • ghost/i18n/locales/lt/portal.json
  • ghost/i18n/locales/si/portal.json
  • ghost/i18n/locales/sr-Cyrl/portal.json
  • ghost/i18n/locales/tr/portal.json
  • ghost/i18n/locales/is/portal.json
  • ghost/i18n/locales/pt-BR/portal.json
  • ghost/i18n/locales/bs/portal.json
  • ghost/i18n/locales/ca/portal.json
  • ghost/i18n/locales/zh-Hant/portal.json
  • ghost/i18n/locales/ja/portal.json
  • ghost/i18n/locales/eo/portal.json
  • ghost/i18n/locales/nb/portal.json
  • ghost/i18n/locales/sk/portal.json
  • ghost/i18n/locales/ko/portal.json
  • ghost/i18n/locales/sr/portal.json
  • ghost/i18n/locales/pt/portal.json
  • ghost/i18n/locales/fi/portal.json
  • ghost/i18n/locales/hr/portal.json
  • ghost/i18n/locales/cs/portal.json
  • ghost/i18n/locales/th/portal.json
  • ghost/i18n/locales/nn/portal.json
  • ghost/i18n/locales/af/portal.json
  • ghost/i18n/locales/id/portal.json
  • ghost/i18n/locales/en/portal.json
  • ghost/i18n/locales/sw/portal.json
  • ghost/i18n/locales/ta/portal.json
  • ghost/i18n/locales/hi/portal.json
  • ghost/i18n/locales/eu/portal.json
  • ghost/i18n/locales/zh/portal.json
  • ghost/i18n/locales/es/portal.json
  • ghost/i18n/locales/it/portal.json
  • ghost/i18n/locales/mk/portal.json
  • ghost/i18n/locales/he/portal.json
  • ghost/i18n/locales/vi/portal.json
  • ghost/i18n/locales/da/portal.json
  • ghost/i18n/locales/ur/portal.json
  • ghost/i18n/locales/et/portal.json
  • ghost/i18n/locales/el/portal.json
  • ghost/i18n/locales/uk/portal.json
  • ghost/i18n/locales/de-CH/portal.json
  • ghost/i18n/locales/lv/portal.json
  • ghost/i18n/locales/sq/portal.json
  • ghost/i18n/locales/bg/portal.json
  • ghost/i18n/locales/pa/portal.json
  • ghost/i18n/locales/sl/portal.json
  • ghost/i18n/locales/ru/portal.json
  • ghost/i18n/locales/mn/portal.json

@sagzy sagzy force-pushed the unify-account-page-copy branch 2 times, most recently from d503696 to 849d8c3 Compare March 2, 2026 11:24
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.

♻️ Duplicate comments (1)
apps/portal/src/components/pages/AccountHomePage/components/paid-account-actions.js (1)

239-239: ⚠️ Potential issue | 🟡 Minor

Translate the interval for consistency with line 33.

Line 33 uses t(interval) for the regular price label, but this line uses raw nextPayment.interval. This inconsistency will show English "month"/"year" in the offer label for non-English locales.

Suggested fix
-const displayedPrice = `${formattedPrice}/${nextPayment.interval}`;
+const displayedPrice = `${formattedPrice}/${t(nextPayment.interval)}`;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@apps/portal/src/components/pages/AccountHomePage/components/paid-account-actions.js`
at line 239, The displayedPrice string uses raw nextPayment.interval causing
untranslated "month"/"year" in non-English locales; change it to use the i18n
translation function like the regular price label (e.g., use
t(nextPayment.interval) or the same interval variable used on line 33) so
displayedPrice becomes `${formattedPrice}/${t(nextPayment.interval)}` ensuring
the interval is translated consistently with the regular price label.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In
`@apps/portal/src/components/pages/AccountHomePage/components/paid-account-actions.js`:
- Line 239: The displayedPrice string uses raw nextPayment.interval causing
untranslated "month"/"year" in non-English locales; change it to use the i18n
translation function like the regular price label (e.g., use
t(nextPayment.interval) or the same interval variable used on line 33) so
displayedPrice becomes `${formattedPrice}/${t(nextPayment.interval)}` ensuring
the interval is translated consistently with the regular price label.

ℹ️ Review info

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 99aab91f1646ff68ee3bb50d072541ce15832b24 and d503696615b51d79c2a37c403d5f04c64f55f40a.

📒 Files selected for processing (66)
  • apps/portal/package.json
  • apps/portal/src/components/pages/AccountHomePage/components/paid-account-actions.js
  • apps/portal/test/unit/components/pages/AccountHomePage/paid-account-actions.test.js
  • ghost/i18n/locales/af/portal.json
  • ghost/i18n/locales/ar/portal.json
  • ghost/i18n/locales/bg/portal.json
  • ghost/i18n/locales/bn/portal.json
  • ghost/i18n/locales/bs/portal.json
  • ghost/i18n/locales/ca/portal.json
  • ghost/i18n/locales/context.json
  • ghost/i18n/locales/cs/portal.json
  • ghost/i18n/locales/da/portal.json
  • ghost/i18n/locales/de-CH/portal.json
  • ghost/i18n/locales/de/portal.json
  • ghost/i18n/locales/el/portal.json
  • ghost/i18n/locales/en/portal.json
  • ghost/i18n/locales/eo/portal.json
  • ghost/i18n/locales/es/portal.json
  • ghost/i18n/locales/et/portal.json
  • ghost/i18n/locales/eu/portal.json
  • ghost/i18n/locales/fa/portal.json
  • ghost/i18n/locales/fi/portal.json
  • ghost/i18n/locales/fr/portal.json
  • ghost/i18n/locales/gd/portal.json
  • ghost/i18n/locales/he/portal.json
  • ghost/i18n/locales/hi/portal.json
  • ghost/i18n/locales/hr/portal.json
  • ghost/i18n/locales/hu/portal.json
  • ghost/i18n/locales/id/portal.json
  • ghost/i18n/locales/is/portal.json
  • ghost/i18n/locales/it/portal.json
  • ghost/i18n/locales/ja/portal.json
  • ghost/i18n/locales/ko/portal.json
  • ghost/i18n/locales/kz/portal.json
  • ghost/i18n/locales/lt/portal.json
  • ghost/i18n/locales/lv/portal.json
  • ghost/i18n/locales/mk/portal.json
  • ghost/i18n/locales/mn/portal.json
  • ghost/i18n/locales/ms/portal.json
  • ghost/i18n/locales/nb/portal.json
  • ghost/i18n/locales/ne/portal.json
  • ghost/i18n/locales/nl/portal.json
  • ghost/i18n/locales/nn/portal.json
  • ghost/i18n/locales/pa/portal.json
  • ghost/i18n/locales/pl/portal.json
  • ghost/i18n/locales/pt-BR/portal.json
  • ghost/i18n/locales/pt/portal.json
  • ghost/i18n/locales/ro/portal.json
  • ghost/i18n/locales/ru/portal.json
  • ghost/i18n/locales/si/portal.json
  • ghost/i18n/locales/sk/portal.json
  • ghost/i18n/locales/sl/portal.json
  • ghost/i18n/locales/sq/portal.json
  • ghost/i18n/locales/sr-Cyrl/portal.json
  • ghost/i18n/locales/sr/portal.json
  • ghost/i18n/locales/sv/portal.json
  • ghost/i18n/locales/sw/portal.json
  • ghost/i18n/locales/ta/portal.json
  • ghost/i18n/locales/th/portal.json
  • ghost/i18n/locales/tr/portal.json
  • ghost/i18n/locales/uk/portal.json
  • ghost/i18n/locales/ur/portal.json
  • ghost/i18n/locales/uz/portal.json
  • ghost/i18n/locales/vi/portal.json
  • ghost/i18n/locales/zh-Hant/portal.json
  • ghost/i18n/locales/zh/portal.json
💤 Files with no reviewable changes (63)
  • ghost/i18n/locales/tr/portal.json
  • ghost/i18n/locales/nb/portal.json
  • ghost/i18n/locales/uk/portal.json
  • ghost/i18n/locales/ar/portal.json
  • ghost/i18n/locales/cs/portal.json
  • ghost/i18n/locales/sk/portal.json
  • ghost/i18n/locales/zh/portal.json
  • ghost/i18n/locales/sr/portal.json
  • ghost/i18n/locales/sl/portal.json
  • ghost/i18n/locales/bg/portal.json
  • ghost/i18n/locales/he/portal.json
  • ghost/i18n/locales/zh-Hant/portal.json
  • ghost/i18n/locales/nl/portal.json
  • ghost/i18n/locales/bs/portal.json
  • ghost/i18n/locales/pl/portal.json
  • ghost/i18n/locales/ca/portal.json
  • ghost/i18n/locales/gd/portal.json
  • ghost/i18n/locales/ur/portal.json
  • ghost/i18n/locales/mk/portal.json
  • ghost/i18n/locales/mn/portal.json
  • ghost/i18n/locales/fa/portal.json
  • ghost/i18n/locales/ru/portal.json
  • ghost/i18n/locales/si/portal.json
  • ghost/i18n/locales/is/portal.json
  • ghost/i18n/locales/sr-Cyrl/portal.json
  • ghost/i18n/locales/pt/portal.json
  • ghost/i18n/locales/ne/portal.json
  • ghost/i18n/locales/it/portal.json
  • ghost/i18n/locales/bn/portal.json
  • ghost/i18n/locales/ms/portal.json
  • ghost/i18n/locales/ta/portal.json
  • ghost/i18n/locales/da/portal.json
  • ghost/i18n/locales/ko/portal.json
  • ghost/i18n/locales/hr/portal.json
  • ghost/i18n/locales/sw/portal.json
  • ghost/i18n/locales/lt/portal.json
  • ghost/i18n/locales/pt-BR/portal.json
  • ghost/i18n/locales/af/portal.json
  • ghost/i18n/locales/de-CH/portal.json
  • ghost/i18n/locales/nn/portal.json
  • ghost/i18n/locales/uz/portal.json
  • ghost/i18n/locales/sv/portal.json
  • ghost/i18n/locales/th/portal.json
  • ghost/i18n/locales/fr/portal.json
  • ghost/i18n/locales/pa/portal.json
  • ghost/i18n/locales/vi/portal.json
  • ghost/i18n/locales/es/portal.json
  • ghost/i18n/locales/el/portal.json
  • ghost/i18n/locales/eo/portal.json
  • ghost/i18n/locales/id/portal.json
  • ghost/i18n/locales/lv/portal.json
  • ghost/i18n/locales/eu/portal.json
  • ghost/i18n/locales/ro/portal.json
  • ghost/i18n/locales/en/portal.json
  • ghost/i18n/locales/ja/portal.json
  • ghost/i18n/locales/et/portal.json
  • ghost/i18n/locales/hu/portal.json
  • ghost/i18n/locales/sq/portal.json
  • ghost/i18n/locales/context.json
  • ghost/i18n/locales/hi/portal.json
  • ghost/i18n/locales/de/portal.json
  • ghost/i18n/locales/kz/portal.json
  • ghost/i18n/locales/fi/portal.json

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.

🧹 Nitpick comments (1)
apps/portal/src/components/pages/AccountHomePage/components/paid-account-actions.js (1)

212-213: Make currentPeriodEnd optional in JSDoc.

Runtime usage treats currentPeriodEnd as optional (Line 233 guard), but docs currently mark it as required.

Suggested doc-only tweak
- * `@param` {string} currentPeriodEnd - Subscription current period end (ISO 8601 date string), needed to display the end of "once" offers
+ * `@param` {string|undefined} currentPeriodEnd - Subscription current period end (ISO 8601 date string), used to display the end of "once" offers
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@apps/portal/src/components/pages/AccountHomePage/components/paid-account-actions.js`
around lines 212 - 213, The JSDoc currently marks currentPeriodEnd as required
but the runtime treats it as optional (there's a guard checking it before use),
so update the JSDoc for currentPeriodEnd to mark it optional (e.g., use
[currentPeriodEnd] or currentPeriodEnd=undefined) and adjust its description to
indicate it may be undefined; locate the parameter in the
paid-account-actions.js component's JSDoc block where currentPeriodEnd is
documented and change the annotation and description accordingly to match the
runtime guard.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In
`@apps/portal/src/components/pages/AccountHomePage/components/paid-account-actions.js`:
- Around line 212-213: The JSDoc currently marks currentPeriodEnd as required
but the runtime treats it as optional (there's a guard checking it before use),
so update the JSDoc for currentPeriodEnd to mark it optional (e.g., use
[currentPeriodEnd] or currentPeriodEnd=undefined) and adjust its description to
indicate it may be undefined; locate the parameter in the
paid-account-actions.js component's JSDoc block where currentPeriodEnd is
documented and change the annotation and description accordingly to match the
runtime guard.

ℹ️ Review info

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d503696615b51d79c2a37c403d5f04c64f55f40a and 849d8c3bdaac23e3e08a9687a7610a72f48caeab.

📒 Files selected for processing (66)
  • apps/portal/package.json
  • apps/portal/src/components/pages/AccountHomePage/components/paid-account-actions.js
  • apps/portal/test/unit/components/pages/AccountHomePage/paid-account-actions.test.js
  • ghost/i18n/locales/af/portal.json
  • ghost/i18n/locales/ar/portal.json
  • ghost/i18n/locales/bg/portal.json
  • ghost/i18n/locales/bn/portal.json
  • ghost/i18n/locales/bs/portal.json
  • ghost/i18n/locales/ca/portal.json
  • ghost/i18n/locales/context.json
  • ghost/i18n/locales/cs/portal.json
  • ghost/i18n/locales/da/portal.json
  • ghost/i18n/locales/de-CH/portal.json
  • ghost/i18n/locales/de/portal.json
  • ghost/i18n/locales/el/portal.json
  • ghost/i18n/locales/en/portal.json
  • ghost/i18n/locales/eo/portal.json
  • ghost/i18n/locales/es/portal.json
  • ghost/i18n/locales/et/portal.json
  • ghost/i18n/locales/eu/portal.json
  • ghost/i18n/locales/fa/portal.json
  • ghost/i18n/locales/fi/portal.json
  • ghost/i18n/locales/fr/portal.json
  • ghost/i18n/locales/gd/portal.json
  • ghost/i18n/locales/he/portal.json
  • ghost/i18n/locales/hi/portal.json
  • ghost/i18n/locales/hr/portal.json
  • ghost/i18n/locales/hu/portal.json
  • ghost/i18n/locales/id/portal.json
  • ghost/i18n/locales/is/portal.json
  • ghost/i18n/locales/it/portal.json
  • ghost/i18n/locales/ja/portal.json
  • ghost/i18n/locales/ko/portal.json
  • ghost/i18n/locales/kz/portal.json
  • ghost/i18n/locales/lt/portal.json
  • ghost/i18n/locales/lv/portal.json
  • ghost/i18n/locales/mk/portal.json
  • ghost/i18n/locales/mn/portal.json
  • ghost/i18n/locales/ms/portal.json
  • ghost/i18n/locales/nb/portal.json
  • ghost/i18n/locales/ne/portal.json
  • ghost/i18n/locales/nl/portal.json
  • ghost/i18n/locales/nn/portal.json
  • ghost/i18n/locales/pa/portal.json
  • ghost/i18n/locales/pl/portal.json
  • ghost/i18n/locales/pt-BR/portal.json
  • ghost/i18n/locales/pt/portal.json
  • ghost/i18n/locales/ro/portal.json
  • ghost/i18n/locales/ru/portal.json
  • ghost/i18n/locales/si/portal.json
  • ghost/i18n/locales/sk/portal.json
  • ghost/i18n/locales/sl/portal.json
  • ghost/i18n/locales/sq/portal.json
  • ghost/i18n/locales/sr-Cyrl/portal.json
  • ghost/i18n/locales/sr/portal.json
  • ghost/i18n/locales/sv/portal.json
  • ghost/i18n/locales/sw/portal.json
  • ghost/i18n/locales/ta/portal.json
  • ghost/i18n/locales/th/portal.json
  • ghost/i18n/locales/tr/portal.json
  • ghost/i18n/locales/uk/portal.json
  • ghost/i18n/locales/ur/portal.json
  • ghost/i18n/locales/uz/portal.json
  • ghost/i18n/locales/vi/portal.json
  • ghost/i18n/locales/zh-Hant/portal.json
  • ghost/i18n/locales/zh/portal.json
💤 Files with no reviewable changes (63)
  • ghost/i18n/locales/uk/portal.json
  • ghost/i18n/locales/fr/portal.json
  • ghost/i18n/locales/de/portal.json
  • ghost/i18n/locales/da/portal.json
  • ghost/i18n/locales/ru/portal.json
  • ghost/i18n/locales/hu/portal.json
  • ghost/i18n/locales/pt/portal.json
  • ghost/i18n/locales/nl/portal.json
  • ghost/i18n/locales/ms/portal.json
  • ghost/i18n/locales/pt-BR/portal.json
  • ghost/i18n/locales/bg/portal.json
  • ghost/i18n/locales/th/portal.json
  • ghost/i18n/locales/ko/portal.json
  • ghost/i18n/locales/mn/portal.json
  • ghost/i18n/locales/lt/portal.json
  • ghost/i18n/locales/sq/portal.json
  • ghost/i18n/locales/cs/portal.json
  • ghost/i18n/locales/el/portal.json
  • ghost/i18n/locales/sv/portal.json
  • ghost/i18n/locales/uz/portal.json
  • ghost/i18n/locales/de-CH/portal.json
  • ghost/i18n/locales/vi/portal.json
  • ghost/i18n/locales/gd/portal.json
  • ghost/i18n/locales/bs/portal.json
  • ghost/i18n/locales/fa/portal.json
  • ghost/i18n/locales/hi/portal.json
  • ghost/i18n/locales/sk/portal.json
  • ghost/i18n/locales/he/portal.json
  • ghost/i18n/locales/nn/portal.json
  • ghost/i18n/locales/es/portal.json
  • ghost/i18n/locales/ne/portal.json
  • ghost/i18n/locales/en/portal.json
  • ghost/i18n/locales/ar/portal.json
  • ghost/i18n/locales/hr/portal.json
  • ghost/i18n/locales/fi/portal.json
  • ghost/i18n/locales/sr/portal.json
  • ghost/i18n/locales/pa/portal.json
  • ghost/i18n/locales/ta/portal.json
  • ghost/i18n/locales/it/portal.json
  • ghost/i18n/locales/ja/portal.json
  • ghost/i18n/locales/tr/portal.json
  • ghost/i18n/locales/ur/portal.json
  • ghost/i18n/locales/mk/portal.json
  • ghost/i18n/locales/context.json
  • ghost/i18n/locales/kz/portal.json
  • ghost/i18n/locales/zh/portal.json
  • ghost/i18n/locales/ro/portal.json
  • ghost/i18n/locales/ca/portal.json
  • ghost/i18n/locales/pl/portal.json
  • ghost/i18n/locales/is/portal.json
  • ghost/i18n/locales/id/portal.json
  • ghost/i18n/locales/eu/portal.json
  • ghost/i18n/locales/zh-Hant/portal.json
  • ghost/i18n/locales/lv/portal.json
  • ghost/i18n/locales/sl/portal.json
  • ghost/i18n/locales/af/portal.json
  • ghost/i18n/locales/bn/portal.json
  • ghost/i18n/locales/eo/portal.json
  • ghost/i18n/locales/et/portal.json
  • ghost/i18n/locales/si/portal.json
  • ghost/i18n/locales/sr-Cyrl/portal.json
  • ghost/i18n/locales/sw/portal.json
  • ghost/i18n/locales/nb/portal.json
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/portal/package.json

} else {
displayedPrice = `${formattedPrice}/${nextPayment.interval}`;
}
const displayedPrice = `${formattedPrice}/${t(nextPayment.interval)}`;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Possible values of interval are 'year' and 'month', correct? Those are already picked up elsewhere, but if there are any others, you'd need to enumerate them as a comment, like:

// t('month')
// t('year') 

That allows the language parser to pick them up. Any time you're plugging in a variable for t, enumerating the possibilities somewhere in the same i18n namespace is necessary. [And twice is much better than 0 times.]

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Ah 💡 I took the existing pattern, but was wondering how that worked! Thanks, adding comments

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

updated

@sagzy sagzy force-pushed the unify-account-page-copy branch 2 times, most recently from 8e392cc to 947b0a5 Compare March 2, 2026 21: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.

🧹 Nitpick comments (1)
apps/portal/src/components/pages/AccountHomePage/components/paid-account-actions.js (1)

212-213: JSDoc type for currentPeriodEnd should reflect optionality.

Line 212 documents currentPeriodEnd as required string, but Line 64 passes undefined when subscription is absent. Consider @param {string|undefined} currentPeriodEnd (or optional param syntax) to keep docs accurate.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@apps/portal/src/components/pages/AccountHomePage/components/paid-account-actions.js`
around lines 212 - 213, Update the JSDoc for the parameter currentPeriodEnd in
the paid-account-actions component to reflect that it can be undefined; change
the param type to either "string|undefined" or use the optional param syntax
(e.g. {string} [currentPeriodEnd]) so the documentation matches how
currentPeriodEnd is passed (see usages around where subscription may be absent
and undefined is supplied).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In
`@apps/portal/src/components/pages/AccountHomePage/components/paid-account-actions.js`:
- Around line 212-213: Update the JSDoc for the parameter currentPeriodEnd in
the paid-account-actions component to reflect that it can be undefined; change
the param type to either "string|undefined" or use the optional param syntax
(e.g. {string} [currentPeriodEnd]) so the documentation matches how
currentPeriodEnd is passed (see usages around where subscription may be absent
and undefined is supplied).

ℹ️ Review info

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 849d8c3bdaac23e3e08a9687a7610a72f48caeab and 8e392cc91d834f8ca1accd53646b9d05871eb47a.

📒 Files selected for processing (66)
  • apps/portal/package.json
  • apps/portal/src/components/pages/AccountHomePage/components/paid-account-actions.js
  • apps/portal/test/unit/components/pages/AccountHomePage/paid-account-actions.test.js
  • ghost/i18n/locales/af/portal.json
  • ghost/i18n/locales/ar/portal.json
  • ghost/i18n/locales/bg/portal.json
  • ghost/i18n/locales/bn/portal.json
  • ghost/i18n/locales/bs/portal.json
  • ghost/i18n/locales/ca/portal.json
  • ghost/i18n/locales/context.json
  • ghost/i18n/locales/cs/portal.json
  • ghost/i18n/locales/da/portal.json
  • ghost/i18n/locales/de-CH/portal.json
  • ghost/i18n/locales/de/portal.json
  • ghost/i18n/locales/el/portal.json
  • ghost/i18n/locales/en/portal.json
  • ghost/i18n/locales/eo/portal.json
  • ghost/i18n/locales/es/portal.json
  • ghost/i18n/locales/et/portal.json
  • ghost/i18n/locales/eu/portal.json
  • ghost/i18n/locales/fa/portal.json
  • ghost/i18n/locales/fi/portal.json
  • ghost/i18n/locales/fr/portal.json
  • ghost/i18n/locales/gd/portal.json
  • ghost/i18n/locales/he/portal.json
  • ghost/i18n/locales/hi/portal.json
  • ghost/i18n/locales/hr/portal.json
  • ghost/i18n/locales/hu/portal.json
  • ghost/i18n/locales/id/portal.json
  • ghost/i18n/locales/is/portal.json
  • ghost/i18n/locales/it/portal.json
  • ghost/i18n/locales/ja/portal.json
  • ghost/i18n/locales/ko/portal.json
  • ghost/i18n/locales/kz/portal.json
  • ghost/i18n/locales/lt/portal.json
  • ghost/i18n/locales/lv/portal.json
  • ghost/i18n/locales/mk/portal.json
  • ghost/i18n/locales/mn/portal.json
  • ghost/i18n/locales/ms/portal.json
  • ghost/i18n/locales/nb/portal.json
  • ghost/i18n/locales/ne/portal.json
  • ghost/i18n/locales/nl/portal.json
  • ghost/i18n/locales/nn/portal.json
  • ghost/i18n/locales/pa/portal.json
  • ghost/i18n/locales/pl/portal.json
  • ghost/i18n/locales/pt-BR/portal.json
  • ghost/i18n/locales/pt/portal.json
  • ghost/i18n/locales/ro/portal.json
  • ghost/i18n/locales/ru/portal.json
  • ghost/i18n/locales/si/portal.json
  • ghost/i18n/locales/sk/portal.json
  • ghost/i18n/locales/sl/portal.json
  • ghost/i18n/locales/sq/portal.json
  • ghost/i18n/locales/sr-Cyrl/portal.json
  • ghost/i18n/locales/sr/portal.json
  • ghost/i18n/locales/sv/portal.json
  • ghost/i18n/locales/sw/portal.json
  • ghost/i18n/locales/ta/portal.json
  • ghost/i18n/locales/th/portal.json
  • ghost/i18n/locales/tr/portal.json
  • ghost/i18n/locales/uk/portal.json
  • ghost/i18n/locales/ur/portal.json
  • ghost/i18n/locales/uz/portal.json
  • ghost/i18n/locales/vi/portal.json
  • ghost/i18n/locales/zh-Hant/portal.json
  • ghost/i18n/locales/zh/portal.json
💤 Files with no reviewable changes (63)
  • ghost/i18n/locales/ca/portal.json
  • ghost/i18n/locales/lv/portal.json
  • ghost/i18n/locales/ja/portal.json
  • ghost/i18n/locales/kz/portal.json
  • ghost/i18n/locales/nn/portal.json
  • ghost/i18n/locales/pl/portal.json
  • ghost/i18n/locales/lt/portal.json
  • ghost/i18n/locales/bs/portal.json
  • ghost/i18n/locales/sr-Cyrl/portal.json
  • ghost/i18n/locales/pt/portal.json
  • ghost/i18n/locales/pt-BR/portal.json
  • ghost/i18n/locales/ro/portal.json
  • ghost/i18n/locales/es/portal.json
  • ghost/i18n/locales/fa/portal.json
  • ghost/i18n/locales/zh/portal.json
  • ghost/i18n/locales/fr/portal.json
  • ghost/i18n/locales/th/portal.json
  • ghost/i18n/locales/tr/portal.json
  • ghost/i18n/locales/it/portal.json
  • ghost/i18n/locales/hr/portal.json
  • ghost/i18n/locales/sw/portal.json
  • ghost/i18n/locales/de/portal.json
  • ghost/i18n/locales/hu/portal.json
  • ghost/i18n/locales/ur/portal.json
  • ghost/i18n/locales/ms/portal.json
  • ghost/i18n/locales/af/portal.json
  • ghost/i18n/locales/uk/portal.json
  • ghost/i18n/locales/en/portal.json
  • ghost/i18n/locales/ru/portal.json
  • ghost/i18n/locales/id/portal.json
  • ghost/i18n/locales/ar/portal.json
  • ghost/i18n/locales/bg/portal.json
  • ghost/i18n/locales/sv/portal.json
  • ghost/i18n/locales/bn/portal.json
  • ghost/i18n/locales/eo/portal.json
  • ghost/i18n/locales/eu/portal.json
  • ghost/i18n/locales/cs/portal.json
  • ghost/i18n/locales/et/portal.json
  • ghost/i18n/locales/sl/portal.json
  • ghost/i18n/locales/si/portal.json
  • ghost/i18n/locales/he/portal.json
  • ghost/i18n/locales/mn/portal.json
  • ghost/i18n/locales/el/portal.json
  • ghost/i18n/locales/da/portal.json
  • ghost/i18n/locales/ko/portal.json
  • ghost/i18n/locales/de-CH/portal.json
  • ghost/i18n/locales/sr/portal.json
  • ghost/i18n/locales/ne/portal.json
  • ghost/i18n/locales/fi/portal.json
  • ghost/i18n/locales/sk/portal.json
  • ghost/i18n/locales/ta/portal.json
  • ghost/i18n/locales/uz/portal.json
  • ghost/i18n/locales/pa/portal.json
  • ghost/i18n/locales/mk/portal.json
  • ghost/i18n/locales/nl/portal.json
  • ghost/i18n/locales/zh-Hant/portal.json
  • ghost/i18n/locales/is/portal.json
  • ghost/i18n/locales/hi/portal.json
  • ghost/i18n/locales/vi/portal.json
  • ghost/i18n/locales/gd/portal.json
  • ghost/i18n/locales/nb/portal.json
  • ghost/i18n/locales/context.json
  • ghost/i18n/locales/sq/portal.json
🚧 Files skipped from review as they are similar to previous changes (2)
  • apps/portal/package.json
  • apps/portal/test/unit/components/pages/AccountHomePage/paid-account-actions.test.js

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.

🧹 Nitpick comments (1)
apps/portal/src/components/pages/AccountHomePage/components/paid-account-actions.js (1)

212-213: Make currentPeriodEnd optional in JSDoc to match actual usage.

The implementation accepts missing currentPeriodEnd, but the current param doc marks it as required string. Marking it optional will keep the contract accurate.

Proposed doc update
- * `@param` {string} currentPeriodEnd - Subscription current period end (ISO 8601 date string), needed to display the end of "once" offers
+ * `@param` {string|undefined} [currentPeriodEnd] - Subscription current period end (ISO 8601 date string), used to display the end of "once" offers when available

Also applies to: 216-216

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@apps/portal/src/components/pages/AccountHomePage/components/paid-account-actions.js`
around lines 212 - 213, The JSDoc for the parameter currentPeriodEnd in
paid-account-actions.js incorrectly marks it as required string; update the
JSDoc for the function that accepts this param (search for currentPeriodEnd in
the file, e.g., the function/component containing the param) to mark it optional
(use {string=} or {string|undefined} or square-bracket param syntax) so the doc
matches the implementation that allows a missing currentPeriodEnd; ensure any
duplicate JSDoc entries (the other occurrence noted) are updated the same way.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In
`@apps/portal/src/components/pages/AccountHomePage/components/paid-account-actions.js`:
- Around line 212-213: The JSDoc for the parameter currentPeriodEnd in
paid-account-actions.js incorrectly marks it as required string; update the
JSDoc for the function that accepts this param (search for currentPeriodEnd in
the file, e.g., the function/component containing the param) to mark it optional
(use {string=} or {string|undefined} or square-bracket param syntax) so the doc
matches the implementation that allows a missing currentPeriodEnd; ensure any
duplicate JSDoc entries (the other occurrence noted) are updated the same way.

ℹ️ Review info

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8e392cc91d834f8ca1accd53646b9d05871eb47a and 947b0a52d90402daf158157848ba8da2674b4aa6.

📒 Files selected for processing (66)
  • apps/portal/package.json
  • apps/portal/src/components/pages/AccountHomePage/components/paid-account-actions.js
  • apps/portal/test/unit/components/pages/AccountHomePage/paid-account-actions.test.js
  • ghost/i18n/locales/af/portal.json
  • ghost/i18n/locales/ar/portal.json
  • ghost/i18n/locales/bg/portal.json
  • ghost/i18n/locales/bn/portal.json
  • ghost/i18n/locales/bs/portal.json
  • ghost/i18n/locales/ca/portal.json
  • ghost/i18n/locales/context.json
  • ghost/i18n/locales/cs/portal.json
  • ghost/i18n/locales/da/portal.json
  • ghost/i18n/locales/de-CH/portal.json
  • ghost/i18n/locales/de/portal.json
  • ghost/i18n/locales/el/portal.json
  • ghost/i18n/locales/en/portal.json
  • ghost/i18n/locales/eo/portal.json
  • ghost/i18n/locales/es/portal.json
  • ghost/i18n/locales/et/portal.json
  • ghost/i18n/locales/eu/portal.json
  • ghost/i18n/locales/fa/portal.json
  • ghost/i18n/locales/fi/portal.json
  • ghost/i18n/locales/fr/portal.json
  • ghost/i18n/locales/gd/portal.json
  • ghost/i18n/locales/he/portal.json
  • ghost/i18n/locales/hi/portal.json
  • ghost/i18n/locales/hr/portal.json
  • ghost/i18n/locales/hu/portal.json
  • ghost/i18n/locales/id/portal.json
  • ghost/i18n/locales/is/portal.json
  • ghost/i18n/locales/it/portal.json
  • ghost/i18n/locales/ja/portal.json
  • ghost/i18n/locales/ko/portal.json
  • ghost/i18n/locales/kz/portal.json
  • ghost/i18n/locales/lt/portal.json
  • ghost/i18n/locales/lv/portal.json
  • ghost/i18n/locales/mk/portal.json
  • ghost/i18n/locales/mn/portal.json
  • ghost/i18n/locales/ms/portal.json
  • ghost/i18n/locales/nb/portal.json
  • ghost/i18n/locales/ne/portal.json
  • ghost/i18n/locales/nl/portal.json
  • ghost/i18n/locales/nn/portal.json
  • ghost/i18n/locales/pa/portal.json
  • ghost/i18n/locales/pl/portal.json
  • ghost/i18n/locales/pt-BR/portal.json
  • ghost/i18n/locales/pt/portal.json
  • ghost/i18n/locales/ro/portal.json
  • ghost/i18n/locales/ru/portal.json
  • ghost/i18n/locales/si/portal.json
  • ghost/i18n/locales/sk/portal.json
  • ghost/i18n/locales/sl/portal.json
  • ghost/i18n/locales/sq/portal.json
  • ghost/i18n/locales/sr-Cyrl/portal.json
  • ghost/i18n/locales/sr/portal.json
  • ghost/i18n/locales/sv/portal.json
  • ghost/i18n/locales/sw/portal.json
  • ghost/i18n/locales/ta/portal.json
  • ghost/i18n/locales/th/portal.json
  • ghost/i18n/locales/tr/portal.json
  • ghost/i18n/locales/uk/portal.json
  • ghost/i18n/locales/ur/portal.json
  • ghost/i18n/locales/uz/portal.json
  • ghost/i18n/locales/vi/portal.json
  • ghost/i18n/locales/zh-Hant/portal.json
  • ghost/i18n/locales/zh/portal.json
💤 Files with no reviewable changes (63)
  • ghost/i18n/locales/ur/portal.json
  • ghost/i18n/locales/sk/portal.json
  • ghost/i18n/locales/de-CH/portal.json
  • ghost/i18n/locales/sr-Cyrl/portal.json
  • ghost/i18n/locales/mn/portal.json
  • ghost/i18n/locales/ar/portal.json
  • ghost/i18n/locales/context.json
  • ghost/i18n/locales/ko/portal.json
  • ghost/i18n/locales/sr/portal.json
  • ghost/i18n/locales/bs/portal.json
  • ghost/i18n/locales/sv/portal.json
  • ghost/i18n/locales/cs/portal.json
  • ghost/i18n/locales/pt-BR/portal.json
  • ghost/i18n/locales/hr/portal.json
  • ghost/i18n/locales/pl/portal.json
  • ghost/i18n/locales/et/portal.json
  • ghost/i18n/locales/en/portal.json
  • ghost/i18n/locales/is/portal.json
  • ghost/i18n/locales/sq/portal.json
  • ghost/i18n/locales/fi/portal.json
  • ghost/i18n/locales/zh-Hant/portal.json
  • ghost/i18n/locales/lt/portal.json
  • ghost/i18n/locales/es/portal.json
  • ghost/i18n/locales/af/portal.json
  • ghost/i18n/locales/uz/portal.json
  • ghost/i18n/locales/eo/portal.json
  • ghost/i18n/locales/de/portal.json
  • ghost/i18n/locales/ru/portal.json
  • ghost/i18n/locales/vi/portal.json
  • ghost/i18n/locales/bg/portal.json
  • ghost/i18n/locales/ne/portal.json
  • ghost/i18n/locales/tr/portal.json
  • ghost/i18n/locales/ca/portal.json
  • ghost/i18n/locales/fa/portal.json
  • ghost/i18n/locales/ms/portal.json
  • ghost/i18n/locales/da/portal.json
  • ghost/i18n/locales/nn/portal.json
  • ghost/i18n/locales/kz/portal.json
  • ghost/i18n/locales/ro/portal.json
  • ghost/i18n/locales/pt/portal.json
  • ghost/i18n/locales/bn/portal.json
  • ghost/i18n/locales/hi/portal.json
  • ghost/i18n/locales/lv/portal.json
  • ghost/i18n/locales/pa/portal.json
  • ghost/i18n/locales/it/portal.json
  • ghost/i18n/locales/sw/portal.json
  • ghost/i18n/locales/gd/portal.json
  • ghost/i18n/locales/ta/portal.json
  • ghost/i18n/locales/ja/portal.json
  • ghost/i18n/locales/fr/portal.json
  • ghost/i18n/locales/uk/portal.json
  • ghost/i18n/locales/th/portal.json
  • ghost/i18n/locales/nl/portal.json
  • ghost/i18n/locales/id/portal.json
  • ghost/i18n/locales/el/portal.json
  • ghost/i18n/locales/mk/portal.json
  • ghost/i18n/locales/nb/portal.json
  • ghost/i18n/locales/hu/portal.json
  • ghost/i18n/locales/si/portal.json
  • ghost/i18n/locales/zh/portal.json
  • ghost/i18n/locales/eu/portal.json
  • ghost/i18n/locales/he/portal.json
  • ghost/i18n/locales/sl/portal.json
🚧 Files skipped from review as they are similar to previous changes (2)
  • apps/portal/package.json
  • apps/portal/test/unit/components/pages/AccountHomePage/paid-account-actions.test.js

@sagzy sagzy force-pushed the unify-account-page-copy branch from 947b0a5 to 1a89da2 Compare March 4, 2026 14:48
@ErisDS
Copy link
Copy Markdown
Member

ErisDS commented Mar 4, 2026

🤖 Velo CI Failure Analysis

Classification: 🟠 SOFT FAIL

  • Workflow: CI
  • Failed Step: Run Playwright tests locally
  • Run: View failed run
    What failed: Playwright tests failed with exit code 1
    Why: The logs indicate that the Playwright tests failed with an exit code of 1, which is a common sign of a code issue rather than an infrastructure problem. The failure is likely due to a test assertion failure or some other issue in the application code being tested.
    Action:
    The author should review the test failures and fix any issues in the application code that are causing the tests to fail.

closes https://linear.app/ghost/issue/BER-3393

- aligned the copy for once offers with the repeating / free months offers:
    - Before "$4.00 - Next payment"
    - After: "$4.00/month - Ends {date}"
@sagzy sagzy force-pushed the unify-account-page-copy branch from 1a89da2 to 68a8476 Compare March 5, 2026 07:16
@sagzy sagzy enabled auto-merge (squash) March 5, 2026 07:16
@sagzy sagzy merged commit 53e1e64 into main Mar 5, 2026
32 checks passed
@sagzy sagzy deleted the unify-account-page-copy branch March 5, 2026 07:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants