Skip to content

chore(clerk-js): Split <PlanDetails/> and <SubcriptionDetails/> #6148

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged

Conversation

panteliselef
Copy link
Member

@panteliselef panteliselef commented Jun 18, 2025

Description

This PR introduces a significant architectural improvement by separating the plan details and subscription details functionality into distinct components. The previously combined functionality has been split into dedicated PlanDetails and SubscriptionDetails components, each with their own responsibilities. The PlanDetails component now focuses solely on displaying plan information, while the new SubscriptionDetails component handles subscription management, including viewing active subscriptions, cancellation flows, and confirmation processes.

The separation of PlanDetails and SubscriptionDetails components provides developers with more granular control over billing-related UI elements, enabling them to implement either plan browsing or subscription management independently.

With upcoming plan

Before

Screen.Recording.2025-07-02.at.4.29.27.PM.mov

After

Screen.Recording.2025-07-02.at.4.30.04.PM.mov

With a active ongoing plan

Before

Screen.Recording.2025-07-02.at.4.27.40.PM.mov

After

Screen.Recording.2025-07-02.at.4.27.04.PM.mov

Checklist

  • pnpm test runs as expected.
  • pnpm build runs as expected.
  • (If applicable) JSDoc comments have been added or updated for any package exports
  • (If applicable) Documentation has been updated

Type of change

  • 🐛 Bug fix
  • 🌟 New feature
  • 🔨 Breaking change
  • 📖 Refactoring / dependency upgrade / documentation
  • other:

Summary by CodeRabbit

  • New Features

    • Introduced a Subscription Details drawer, allowing users to view and manage subscription information in a dedicated UI.
    • Added new UI components and appearance customization options for subscription details.
    • Enhanced localization with additional subscription-related labels and messages.
  • Improvements

    • Simplified plan details view by focusing it solely on plan information, with subscription management moved to the new drawer.
    • Updated subscription management buttons for more consistent access to subscription details.
  • Bug Fixes

    • Improved loading and error handling states for subscription and plan details.
  • Tests

    • Added comprehensive tests for Subscription Details and Plan Details components to verify rendering and user interactions.
  • Documentation

    • Updated localization resources to include new subscription-related entries.
  • Chores

    • Increased maximum allowed bundle sizes to accommodate new features.

Copy link

changeset-bot bot commented Jun 18, 2025

🦋 Changeset detected

Latest commit: 86de684

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 22 packages
Name Type
@clerk/localizations Minor
@clerk/clerk-js Minor
@clerk/clerk-react Minor
@clerk/types Minor
@clerk/chrome-extension Patch
@clerk/clerk-expo Patch
@clerk/elements Patch
@clerk/nextjs Patch
@clerk/react-router Patch
@clerk/remix Patch
@clerk/tanstack-react-start Patch
@clerk/agent-toolkit Patch
@clerk/astro Patch
@clerk/backend Patch
@clerk/expo-passkeys Patch
@clerk/express Patch
@clerk/fastify Patch
@clerk/nuxt Patch
@clerk/shared Patch
@clerk/testing Patch
@clerk/themes Patch
@clerk/vue Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

Copy link

vercel bot commented Jun 18, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
clerk-js-sandbox ✅ Ready (Inspect) Visit Preview 💬 Add feedback Jul 14, 2025 4:18pm

…-and-subscriptiondetails

# Conflicts:
#	packages/clerk-js/src/ui/components/Plans/PlanDetails.tsx
…-and-subscriptiondetails

# Conflicts:
#	packages/clerk-js/src/core/resources/CommerceSubscription.ts
#	packages/clerk-js/src/ui/components/Plans/PlanDetails.tsx
#	packages/clerk-js/src/ui/contexts/components/Plans.tsx
#	packages/types/src/commerce.ts
@panteliselef panteliselef force-pushed the elef/com-835-split-up-plandetails-and-subscriptiondetails branch from fd6f2e9 to 1c161cc Compare July 13, 2025 18:17
Copy link
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: 0

♻️ Duplicate comments (1)
packages/clerk-js/src/ui/components/SubscriptionDetails/__tests__/SubscriptionDetails.test.tsx (1)

494-494: Remove the focused test to ensure all tests run.

The .only method prevents other tests from executing, which could mask issues in the test suite.

Apply this fix:

-  it.only('allows cancelling a subscription of a monthly plan', async () => {
+  it('allows cancelling a subscription of a monthly plan', async () => {
🧹 Nitpick comments (1)
packages/clerk-js/src/ui/components/SubscriptionDetails/__tests__/SubscriptionDetails.test.tsx (1)

1-732: Consider refactoring for better maintainability.

The test file is comprehensive but could benefit from several improvements:

  1. Extract mock data helpers: The mock subscription and plan objects are repeated across tests with slight variations. Consider creating factory functions.

  2. Split into smaller test suites: At 730+ lines, this file is quite large. Consider grouping related tests into separate files (e.g., single subscription tests, multiple subscription tests, interaction tests).

  3. Improve test names: Some test names could be more descriptive of the specific behavior being tested.

Example refactor for mock data:

// Create a test helper file
const createMockPlan = (overrides = {}) => ({
  id: 'plan_123',
  name: 'Test Plan',
  amount: 1000,
  amountFormatted: '10.00',
  // ... other default properties
  ...overrides
});

const createMockSubscription = (planOverrides = {}, subscriptionOverrides = {}) => ({
  id: 'sub_123',
  plan: createMockPlan(planOverrides),
  createdAt: new Date('2021-01-01'),
  // ... other default properties
  ...subscriptionOverrides
});
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 38fa5f6 and 5421403.

📒 Files selected for processing (1)
  • packages/clerk-js/src/ui/components/SubscriptionDetails/__tests__/SubscriptionDetails.test.tsx (1 hunks)
🧰 Additional context used
📓 Path-based instructions (12)
**/*.{js,jsx,ts,tsx}

Instructions used from:

Sources:
📄 CodeRabbit Inference Engine

  • .cursor/rules/development.mdc
**/{__tests__,**/__tests__}/**/*.{js,jsx,ts,tsx}

Instructions used from:

Sources:
📄 CodeRabbit Inference Engine

  • .cursor/rules/development.mdc
packages/**/*.{ts,tsx,d.ts}

Instructions used from:

Sources:
📄 CodeRabbit Inference Engine

  • .cursor/rules/development.mdc
**/*.{ts,tsx}

Instructions used from:

Sources:
📄 CodeRabbit Inference Engine

  • .cursor/rules/development.mdc
  • .cursor/rules/typescript.mdc
**/*.{tsx,jsx}

Instructions used from:

Sources:
📄 CodeRabbit Inference Engine

  • .cursor/rules/development.mdc
**/*.{test,spec}.{js,ts,tsx}

Instructions used from:

Sources:
📄 CodeRabbit Inference Engine

  • .cursor/rules/monorepo.mdc
packages/{clerk-js,elements,themes}/**/*

Instructions used from:

Sources:
📄 CodeRabbit Inference Engine

  • .cursor/rules/monorepo.mdc
**/*.{jsx,tsx}

Instructions used from:

Sources:
📄 CodeRabbit Inference Engine

  • .cursor/rules/react.mdc
**/*.tsx

Instructions used from:

Sources:
📄 CodeRabbit Inference Engine

  • .cursor/rules/react.mdc
**/*.test.{jsx,tsx}

Instructions used from:

Sources:
📄 CodeRabbit Inference Engine

  • .cursor/rules/react.mdc
**/__tests__/**/*.{ts,tsx}

Instructions used from:

Sources:
📄 CodeRabbit Inference Engine

  • .cursor/rules/typescript.mdc
**/*

Instructions used from:

Sources:
⚙️ CodeRabbit Configuration File

🧠 Learnings (2)
📓 Common learnings
Learnt from: dstaley
PR: clerk/javascript#6116
File: .changeset/tangy-garlics-say.md:1-2
Timestamp: 2025-06-13T16:09:53.061Z
Learning: In the Clerk JavaScript repository, contributors create intentionally empty changeset files (containing only the YAML delimiters) when a PR touches only non-published parts of the codebase (e.g., sandbox assets). This signals that no package release is required, so such changesets should not be flagged as missing content.
Learnt from: CR
PR: clerk/javascript#0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-06-30T10:32:37.848Z
Learning: Applies to **/*.{jsx,tsx} : Implement proper subscription cleanup
Learnt from: panteliselef
PR: clerk/javascript#6097
File: packages/clerk-js/src/ui/elements/LineItems.tsx:89-89
Timestamp: 2025-06-10T09:38:56.214Z
Learning: In packages/clerk-js/src/ui/elements/LineItems.tsx, the Title component's React.forwardRef should use HTMLTableCellElement as the generic type parameter, even though it renders a Dt element. This is the correct implementation according to the codebase maintainer.
Learnt from: CR
PR: clerk/javascript#0
File: .cursor/rules/monorepo.mdc:0-0
Timestamp: 2025-06-30T10:30:56.197Z
Learning: Applies to packages/clerk-react/**/*.{test,spec}.{js,ts,tsx} : Component testing should use React Testing Library.
packages/clerk-js/src/ui/components/SubscriptionDetails/__tests__/SubscriptionDetails.test.tsx (14)
Learnt from: CR
PR: clerk/javascript#0
File: .cursor/rules/monorepo.mdc:0-0
Timestamp: 2025-06-30T10:30:56.197Z
Learning: Applies to packages/clerk-react/**/*.{test,spec}.{js,ts,tsx} : Component testing should use React Testing Library.
Learnt from: CR
PR: clerk/javascript#0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-06-30T10:32:37.848Z
Learning: Applies to **/*.test.{jsx,tsx} : Test component interactions
Learnt from: CR
PR: clerk/javascript#0
File: .cursor/rules/monorepo.mdc:0-0
Timestamp: 2025-06-30T10:30:56.197Z
Learning: Applies to packages/{clerk-js,elements,themes}/**/* : Visual regression testing should be performed for UI components.
Learnt from: CR
PR: clerk/javascript#0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-06-30T10:32:37.848Z
Learning: Applies to **/*.{jsx,tsx} : Implement proper subscription cleanup
Learnt from: CR
PR: clerk/javascript#0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-06-30T10:32:37.848Z
Learning: Applies to **/*.test.{jsx,tsx} : Test component behavior, not implementation
Learnt from: CR
PR: clerk/javascript#0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-06-30T10:32:37.848Z
Learning: Applies to **/*.test.{jsx,tsx} : Implement proper test setup
Learnt from: CR
PR: clerk/javascript#0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-06-30T10:32:37.848Z
Learning: Applies to **/*.test.{jsx,tsx} : Implement proper test assertions
Learnt from: CR
PR: clerk/javascript#0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-06-30T10:32:37.848Z
Learning: Applies to **/*.test.{jsx,tsx} : Implement proper test isolation
Learnt from: CR
PR: clerk/javascript#0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-06-30T10:32:37.848Z
Learning: Applies to **/*.test.{jsx,tsx} : Use proper test data
Learnt from: CR
PR: clerk/javascript#0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-06-30T10:32:37.848Z
Learning: Applies to **/*.test.{jsx,tsx} : Use proper test queries
Learnt from: LauraBeatris
PR: clerk/javascript#6117
File: packages/clerk-js/src/ui/components/SessionTasks/index.tsx:64-83
Timestamp: 2025-06-18T16:33:36.764Z
Learning: In SessionTasks component at packages/clerk-js/src/ui/components/SessionTasks/index.tsx, the useEffect that checks for pending tasks should only run on mount (not react to currentTask/status changes) to handle browser back navigation edge cases without interfering with normal task completion flow managed by nextTask().
Learnt from: CR
PR: clerk/javascript#0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-06-30T10:32:37.848Z
Learning: Applies to **/*.test.{jsx,tsx} : Use proper test cleanup
Learnt from: CR
PR: clerk/javascript#0
File: .cursor/rules/development.mdc:0-0
Timestamp: 2025-06-30T10:29:42.997Z
Learning: Integration tests using Playwright for E2E scenarios
Learnt from: CR
PR: clerk/javascript#0
File: .cursor/rules/development.mdc:0-0
Timestamp: 2025-06-30T10:29:42.997Z
Learning: React Testing Library for component testing
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: Build Packages
  • GitHub Check: Formatting | Dedupe | Changeset
  • GitHub Check: semgrep-cloud-platform/scan
  • GitHub Check: semgrep/ci
  • GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (5)
packages/clerk-js/src/ui/components/SubscriptionDetails/__tests__/SubscriptionDetails.test.tsx (5)

25-28: Good use of proper test queries and assertions.

The test properly uses React Testing Library's waitFor and semantic queries to test the loading state. The spinner is identified correctly by its aria-live attribute.


77-99: Comprehensive UI state verification.

The test thoroughly verifies all expected UI elements are rendered for an active monthly subscription, including proper date formatting and pricing display.


101-108: Proper user interaction testing.

The test correctly simulates user interactions with the menu button and verifies the menu options are displayed. Good use of user events and waitFor.


544-572: Excellent cancellation flow testing.

The test properly simulates the complete cancellation flow including:

  • Opening the menu
  • Clicking cancel option
  • Verifying confirmation dialog
  • Confirming cancellation
  • Asserting the cancel method was called

This demonstrates good testing of component behavior rather than implementation details.


723-730: Proper mock verification for billing period switching.

The test correctly verifies that the checkout is opened with the expected parameters when switching from annual to monthly billing. Good use of expect.objectContaining for partial object matching.

Copy link
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

🔭 Outside diff range comments (1)
packages/clerk-js/src/ui/components/SubscriptionDetails/index.tsx (1)

1-558: Add tests for the new SubscriptionDetails component

No tests were added for this new component. Please add comprehensive tests covering:

  • Different subscription states (active, upcoming, canceled)
  • Permission checks for billing management
  • User interactions (cancellation flow, plan switching)
  • Error handling scenarios

Would you like me to help generate the test suite for this component?

♻️ Duplicate comments (2)
packages/clerk-js/src/ui/components/SubscriptionDetails/index.tsx (2)

1-558: Split this large component file into smaller, focused modules

This file exceeds the recommended 150-200 line limit for components. Consider splitting it into separate files for better maintainability and single responsibility.


436-436: Use a more generalized shadow token name

As mentioned in previous reviews, using tableBodyShadow outside of table context is not ideal. Consider using a more generic shadow token.

🧹 Nitpick comments (1)
packages/clerk-js/src/ui/components/SubscriptionDetails/index.tsx (1)

43-43: Fix typo in comment

-// We cannot derive the state of confrimation modal from the existance subscription, as it will make the animation laggy when the confimation closes.
+// We cannot derive the state of confirmation modal from the existence subscription, as it will make the animation laggy when the confirmation closes.
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6f01802 and 86de684.

📒 Files selected for processing (5)
  • packages/clerk-js/src/ui/components/Plans/PlanDetails.tsx (3 hunks)
  • packages/clerk-js/src/ui/components/SubscriptionDetails/index.tsx (1 hunks)
  • packages/clerk-js/src/ui/customizables/elementDescriptors.ts (2 hunks)
  • packages/clerk-js/src/ui/elements/LineItems.tsx (2 hunks)
  • packages/types/src/appearance.ts (3 hunks)
✅ Files skipped from review due to trivial changes (1)
  • packages/clerk-js/src/ui/customizables/elementDescriptors.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • packages/clerk-js/src/ui/components/Plans/PlanDetails.tsx
  • packages/types/src/appearance.ts
🧰 Additional context used
📓 Path-based instructions (8)
**/*.{js,jsx,ts,tsx}

Instructions used from:

Sources:
📄 CodeRabbit Inference Engine

  • .cursor/rules/development.mdc
packages/**/*.{ts,tsx,d.ts}

Instructions used from:

Sources:
📄 CodeRabbit Inference Engine

  • .cursor/rules/development.mdc
**/*.{ts,tsx}

Instructions used from:

Sources:
📄 CodeRabbit Inference Engine

  • .cursor/rules/development.mdc
  • .cursor/rules/typescript.mdc
**/*.{tsx,jsx}

Instructions used from:

Sources:
📄 CodeRabbit Inference Engine

  • .cursor/rules/development.mdc
packages/{clerk-js,elements,themes}/**/*

Instructions used from:

Sources:
📄 CodeRabbit Inference Engine

  • .cursor/rules/monorepo.mdc
**/*.{jsx,tsx}

Instructions used from:

Sources:
📄 CodeRabbit Inference Engine

  • .cursor/rules/react.mdc
**/*.tsx

Instructions used from:

Sources:
📄 CodeRabbit Inference Engine

  • .cursor/rules/react.mdc
**/*

Instructions used from:

Sources:
⚙️ CodeRabbit Configuration File

🧠 Learnings (3)
📓 Common learnings
Learnt from: dstaley
PR: clerk/javascript#6116
File: .changeset/tangy-garlics-say.md:1-2
Timestamp: 2025-06-13T16:09:53.061Z
Learning: In the Clerk JavaScript repository, contributors create intentionally empty changeset files (containing only the YAML delimiters) when a PR touches only non-published parts of the codebase (e.g., sandbox assets). This signals that no package release is required, so such changesets should not be flagged as missing content.
Learnt from: CR
PR: clerk/javascript#0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-06-30T10:32:37.848Z
Learning: Applies to **/*.{jsx,tsx} : Implement proper subscription cleanup
packages/clerk-js/src/ui/elements/LineItems.tsx (14)
Learnt from: panteliselef
PR: clerk/javascript#6097
File: packages/clerk-js/src/ui/elements/LineItems.tsx:89-89
Timestamp: 2025-06-10T09:38:56.214Z
Learning: In packages/clerk-js/src/ui/elements/LineItems.tsx, the Title component's React.forwardRef should use HTMLTableCellElement as the generic type parameter, even though it renders a Dt element. This is the correct implementation according to the codebase maintainer.
Learnt from: CR
PR: clerk/javascript#0
File: .cursor/rules/monorepo.mdc:0-0
Timestamp: 2025-06-30T10:30:56.197Z
Learning: Applies to packages/clerk-react/**/*.{test,spec}.{js,ts,tsx} : Component testing should use React Testing Library.
Learnt from: CR
PR: clerk/javascript#0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-06-30T10:32:37.848Z
Learning: Applies to **/*.tsx : Use proper type definitions for props and state
Learnt from: CR
PR: clerk/javascript#0
File: .cursor/rules/monorepo.mdc:0-0
Timestamp: 2025-06-30T10:30:56.197Z
Learning: Applies to packages/{clerk-js,elements,themes}/**/* : Visual regression testing should be performed for UI components.
Learnt from: CR
PR: clerk/javascript#0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-06-30T10:32:37.848Z
Learning: Applies to **/*.{jsx,tsx} : Use proper prop naming
Learnt from: CR
PR: clerk/javascript#0
File: .cursor/rules/typescript.mdc:0-0
Timestamp: 2025-06-30T10:33:45.961Z
Learning: Applies to **/*.{ts,tsx} : Use optional chaining and nullish coalescing for safe property access
Learnt from: CR
PR: clerk/javascript#0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-06-30T10:32:37.848Z
Learning: Applies to **/*.tsx : Use proper type guards for conditional rendering
Learnt from: dstaley
PR: clerk/javascript#6116
File: .changeset/tangy-garlics-say.md:1-2
Timestamp: 2025-06-13T16:09:53.061Z
Learning: In the Clerk JavaScript repository, contributors create intentionally empty changeset files (containing only the YAML delimiters) when a PR touches only non-published parts of the codebase (e.g., sandbox assets). This signals that no package release is required, so such changesets should not be flagged as missing content.
Learnt from: CR
PR: clerk/javascript#0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-06-30T10:32:37.848Z
Learning: Applies to **/*.{jsx,tsx} : Use proper component naming
Learnt from: CR
PR: clerk/javascript#0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-06-30T10:32:37.848Z
Learning: Applies to **/*.{jsx,tsx} : Implement proper state naming
Learnt from: CR
PR: clerk/javascript#0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-06-30T10:32:37.848Z
Learning: Applies to **/*.{jsx,tsx} : Implement proper ARIA attributes
Learnt from: CR
PR: clerk/javascript#0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-06-30T10:32:37.848Z
Learning: Applies to **/*.{jsx,tsx} : Use proper button types
Learnt from: CR
PR: clerk/javascript#0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-06-30T10:32:37.848Z
Learning: Applies to **/*.{jsx,tsx} : Use proper heading hierarchy
Learnt from: CR
PR: clerk/javascript#0
File: .cursor/rules/nextjs.mdc:0-0
Timestamp: 2025-06-30T10:31:43.578Z
Learning: Applies to {app/**/*.tsx,pages/**/*.{js,ts,jsx,tsx}} : Add alt text to all images for accessibility and SEO
packages/clerk-js/src/ui/components/SubscriptionDetails/index.tsx (17)
Learnt from: CR
PR: clerk/javascript#0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-06-30T10:32:37.848Z
Learning: Applies to **/*.{jsx,tsx} : Implement proper subscription cleanup
Learnt from: CR
PR: clerk/javascript#0
File: .cursor/rules/monorepo.mdc:0-0
Timestamp: 2025-06-30T10:30:56.197Z
Learning: Applies to packages/clerk-react/**/*.{test,spec}.{js,ts,tsx} : Component testing should use React Testing Library.
Learnt from: panteliselef
PR: clerk/javascript#6097
File: packages/clerk-js/src/ui/elements/LineItems.tsx:89-89
Timestamp: 2025-06-10T09:38:56.214Z
Learning: In packages/clerk-js/src/ui/elements/LineItems.tsx, the Title component's React.forwardRef should use HTMLTableCellElement as the generic type parameter, even though it renders a Dt element. This is the correct implementation according to the codebase maintainer.
Learnt from: CR
PR: clerk/javascript#0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-06-30T10:32:37.848Z
Learning: Applies to **/*.{jsx,tsx} : Keep components focused on a single responsibility - split large components
Learnt from: CR
PR: clerk/javascript#0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-06-30T10:32:37.848Z
Learning: Applies to **/*.{jsx,tsx} : Implement proper component structure
Learnt from: CR
PR: clerk/javascript#0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-06-30T10:32:37.848Z
Learning: Applies to **/*.tsx : Use proper type definitions for props and state
Learnt from: CR
PR: clerk/javascript#0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-06-30T10:32:37.848Z
Learning: Applies to **/*.{jsx,tsx} : Implement proper virtualization for lists
Learnt from: CR
PR: clerk/javascript#0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-06-30T10:32:37.848Z
Learning: Applies to **/*.{jsx,tsx} : Export components as named exports for better tree-shaking
Learnt from: CR
PR: clerk/javascript#0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-06-30T10:32:37.848Z
Learning: Applies to **/*.test.{jsx,tsx} : Test component interactions
Learnt from: CR
PR: clerk/javascript#0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-06-30T10:32:37.848Z
Learning: Applies to **/*.{jsx,tsx} : Implement proper state selectors
Learnt from: CR
PR: clerk/javascript#0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-06-30T10:32:37.848Z
Learning: Applies to **/*.{jsx,tsx} : Limit component size to 150-200 lines; extract logic into custom hooks
Learnt from: CR
PR: clerk/javascript#0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-06-30T10:32:37.848Z
Learning: Applies to **/*.{jsx,tsx} : Use composition over inheritance - prefer smaller, composable components
Learnt from: CR
PR: clerk/javascript#0
File: .cursor/rules/typescript.mdc:0-0
Timestamp: 2025-06-30T10:33:45.961Z
Learning: Applies to **/index.ts : Avoid barrel files (index.ts re-exports) as they can cause circular dependencies
Learnt from: CR
PR: clerk/javascript#0
File: .cursor/rules/nextjs.mdc:0-0
Timestamp: 2025-06-30T10:31:43.578Z
Learning: Applies to app/**/layout.tsx : Use layout.tsx for shared UI that wraps multiple pages in the App Router
Learnt from: CR
PR: clerk/javascript#0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-06-30T10:32:37.848Z
Learning: Applies to **/*.{jsx,tsx} : Use proper component naming
Learnt from: CR
PR: clerk/javascript#0
File: .cursor/rules/development.mdc:0-0
Timestamp: 2025-06-30T10:29:42.997Z
Learning: Maintain consistency in naming and patterns across framework integrations
Learnt from: CR
PR: clerk/javascript#0
File: .cursor/rules/react.mdc:0-0
Timestamp: 2025-06-30T10:32:37.848Z
Learning: Applies to **/*.{jsx,tsx} : Use proper button types
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: semgrep-cloud-platform/scan
  • GitHub Check: Formatting | Dedupe | Changeset
  • GitHub Check: Build Packages
  • GitHub Check: semgrep/ci
  • GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (1)
packages/clerk-js/src/ui/elements/LineItems.tsx (1)

84-84: LGTM! Good improvement for component flexibility.

Making the title optional and adding conditional rendering is a sensible change that increases the component's reusability. The implementation correctly handles the optional title prop.

Also applies to: 107-124

Comment on lines +186 to +200
await subscription
.cancel({ orgId: subscriberType === 'org' ? organization?.id : undefined })
.then(() => {
onSubscriptionCancel?.();
if (setIsOpen) {
setIsOpen(false);
}
})
.catch(error => {
handleError(error, [], setError);
})
.finally(() => {
setIdle();
});
}, [subscription, setError, setLoading, subscriberType, organization?.id, onSubscriptionCancel, setIsOpen, setIdle]);
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Security: Tag clerk security team for billing management changes

This code handles subscription cancellation which involves billing permissions and could impact security. The permission check using useProtect is good, but the billing flow changes should be reviewed by the security team.

@clerk/security - Please review the subscription cancellation flow and permission checks.

🤖 Prompt for AI Agents
In packages/clerk-js/src/ui/components/SubscriptionDetails/index.tsx around
lines 186 to 200, the subscription cancellation flow involves billing
permissions and security-sensitive operations. Ensure that the security team is
tagged for review by adding a comment or notification explicitly mentioning
@clerk/security in the code or PR description to prompt their review of
permission checks and billing flow changes.

Comment on lines +95 to +96
activeSubscription: activeSubscription as any, // Type is correct due to the throw above
anySubscription: (upcomingSubscription || activeSubscription) as any,
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Avoid using as any - use proper type assertions

Using as any bypasses TypeScript's type checking. Consider using proper type guards or narrowing the types correctly.

-    activeSubscription: activeSubscription as any, // Type is correct due to the throw above
-    anySubscription: (upcomingSubscription || activeSubscription) as any,
+    activeSubscription: activeSubscription!, // Non-null assertion is safe due to the throw above
+    anySubscription: (upcomingSubscription || activeSubscription)!,
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
activeSubscription: activeSubscription as any, // Type is correct due to the throw above
anySubscription: (upcomingSubscription || activeSubscription) as any,
activeSubscription: activeSubscription!, // Non-null assertion is safe due to the throw above
anySubscription: (upcomingSubscription || activeSubscription)!,
🤖 Prompt for AI Agents
In packages/clerk-js/src/ui/components/SubscriptionDetails/index.tsx around
lines 95 to 96, the use of 'as any' disables TypeScript's type checking and
should be avoided. Instead, implement proper type guards or type narrowing to
ensure the variables activeSubscription and anySubscription have the correct and
safe types without resorting to 'any'. Adjust the code to explicitly check and
assert the types based on the logic above to maintain type safety.

Comment on lines +259 to +261
// @ts-expect-error this will always be defined in this state
date: subscription.periodEndDate,
})
Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Address the TypeScript error instead of suppressing it

The @ts-expect-error comment suggests there's a type issue that should be fixed rather than ignored.

Can you verify why periodEndDate might be undefined here? Based on the conditional check at line 511, it seems periodEndDate can be null for free plans. Consider updating the types or adding a proper null check:

-                      // @ts-expect-error this will always be defined in this state
-                      date: subscription.periodEndDate,
+                      date: subscription.periodEndDate || '',

🏁 Script executed:

#!/bin/bash
# Find occurrences of periodEndDate in the component
rg --line-number "periodEndDate" packages/clerk-js/src/ui/components/SubscriptionDetails/index.tsx

# Show lines around the date assignment (around 259)
sed -n '230,300p' packages/clerk-js/src/ui/components/SubscriptionDetails/index.tsx

# Show the conditional logic at line 511 to understand when periodEndDate may be null
sed -n '480,550p' packages/clerk-js/src/ui/components/SubscriptionDetails/index.tsx

Length of output: 5442


🏁 Script executed:

#!/bin/bash
# Show the top of the SubscriptionDetails component to identify the source of `subscription`
sed -n '1,200p' packages/clerk-js/src/ui/components/SubscriptionDetails/index.tsx

# Search for the SubscriptionDetails component definition
rg --line-number "function SubscriptionDetails" packages/clerk-js/src/ui/components/SubscriptionDetails/index.tsx

# Find where `subscription` is coming from in this component
rg --line-number "const { subscription" -n packages/clerk-js/src/ui/components/SubscriptionDetails/index.tsx

Length of output: 7147


🏁 Script executed:

#!/bin/bash
# Find the SubscriptionCard component definition
rg --context 3 --line-number "SubscriptionCard" -n packages/clerk-js/src/ui/components/SubscriptionDetails

Length of output: 3070


🏁 Script executed:

#!/bin/bash
# Show the implementation of SubscriptionCardActions to see if free plans can trigger cancellation
sed -n '318,380p' packages/clerk-js/src/ui/components/SubscriptionDetails/index.tsx

Length of output: 2425


Remove the @ts-expect-error and assert periodEndDate is non-null

You’ve already branched on subscription.status === 'upcoming', so in the “Access until” case periodEndDate will always be defined at runtime. Rather than suppressing the error, let TypeScript know that it’s non-null:

• File: packages/clerk-js/src/ui/components/SubscriptionDetails/index.tsx
• Around lines 256–261

-                      // @ts-expect-error this will always be defined in this state
-                      date: subscription.periodEndDate,
+                      date: subscription.periodEndDate!,

If you’d rather provide a fallback instead of an assertion, you could use:

date: subscription.periodEndDate || '',
🤖 Prompt for AI Agents
In packages/clerk-js/src/ui/components/SubscriptionDetails/index.tsx around
lines 256 to 261, remove the @ts-expect-error comment before accessing
subscription.periodEndDate and instead assert that periodEndDate is non-null
using the non-null assertion operator (!). This change informs TypeScript that
periodEndDate is definitely defined in this context, eliminating the need to
suppress the error. Alternatively, you can provide a fallback value like an
empty string if you prefer not to use an assertion.

@panteliselef panteliselef merged commit b96114e into main Jul 14, 2025
36 checks passed
@panteliselef panteliselef deleted the elef/com-835-split-up-plandetails-and-subscriptiondetails branch July 14, 2025 16:36
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.

5 participants
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy