From ed04215d400afb28204f223e1342e5cf06968748 Mon Sep 17 00:00:00 2001 From: Simula_r <18093452+simula-r@users.noreply.github.com> Date: Wed, 17 Dec 2025 14:07:04 -0800 Subject: [PATCH] feat: add pricing table to user popover (#7583) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary Add ability to show pricing table from user popover. Misc style changes and logic. ## Changes - **What**: CurrentUserPopover.vue - **Breaking**: - **Dependencies**: ## Screenshots (if applicable) ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-7583-feat-add-pricing-table-to-user-popover-2cc6d73d365081e1bbf1f2b351e53289) by [Unito](https://www.unito.io) --- src/components/topbar/CurrentUserButton.vue | 10 ++- .../topbar/CurrentUserPopover.test.ts | 32 +++++++ src/components/topbar/CurrentUserPopover.vue | 85 ++++++++++++------- src/locales/en/main.json | 4 + 4 files changed, 97 insertions(+), 34 deletions(-) diff --git a/src/components/topbar/CurrentUserButton.vue b/src/components/topbar/CurrentUserButton.vue index d64a6dfe2..5a21ce9c3 100644 --- a/src/components/topbar/CurrentUserButton.vue +++ b/src/components/topbar/CurrentUserButton.vue @@ -18,7 +18,15 @@ - + diff --git a/src/components/topbar/CurrentUserPopover.test.ts b/src/components/topbar/CurrentUserPopover.test.ts index 4b1cb114c..f46ae0990 100644 --- a/src/components/topbar/CurrentUserPopover.test.ts +++ b/src/components/topbar/CurrentUserPopover.test.ts @@ -85,10 +85,24 @@ const mockFetchStatus = vi.fn().mockResolvedValue(undefined) vi.mock('@/platform/cloud/subscription/composables/useSubscription', () => ({ useSubscription: vi.fn(() => ({ isActiveSubscription: { value: true }, + subscriptionTierName: { value: 'Creator' }, + subscriptionTier: { value: 'CREATOR' }, fetchStatus: mockFetchStatus })) })) +// Mock the useSubscriptionDialog composable +const mockSubscriptionDialogShow = vi.fn() +vi.mock( + '@/platform/cloud/subscription/composables/useSubscriptionDialog', + () => ({ + useSubscriptionDialog: vi.fn(() => ({ + show: mockSubscriptionDialogShow, + hide: vi.fn() + })) + }) +) + // Mock UserAvatar component vi.mock('@/components/common/UserAvatar.vue', () => ({ default: { @@ -272,4 +286,22 @@ describe('CurrentUserPopover', () => { expect(wrapper.emitted('close')).toBeTruthy() expect(wrapper.emitted('close')!.length).toBe(1) }) + + it('opens subscription dialog and emits close event when plans & pricing item is clicked', async () => { + const wrapper = mountComponent() + + const plansPricingItem = wrapper.find( + '[data-testid="plans-pricing-menu-item"]' + ) + expect(plansPricingItem.exists()).toBe(true) + + await plansPricingItem.trigger('click') + + // Verify subscription dialog show was called + expect(mockSubscriptionDialogShow).toHaveBeenCalled() + + // Verify close event was emitted + expect(wrapper.emitted('close')).toBeTruthy() + expect(wrapper.emitted('close')!.length).toBe(1) + }) }) diff --git a/src/components/topbar/CurrentUserPopover.vue b/src/components/topbar/CurrentUserPopover.vue index adad38de4..e2630c5be 100644 --- a/src/components/topbar/CurrentUserPopover.vue +++ b/src/components/topbar/CurrentUserPopover.vue @@ -21,9 +21,12 @@ {{ userEmail }} - + {{ subscriptionTierName }} - + @@ -33,11 +36,16 @@ v-if="authStore.isFetchingBalance" width="4rem" height="1.25rem" - class="flex-1" + class="w-full" /> - {{ + {{ formattedBalance }} + - - - - {{ - $t('credits.unified.message') - }} - - {{ - $t(planSettingsLabel) + $t('subscription.plansAndPricing') + }} + + {{ $t('subscription.upgrade') }} + + + + + + {{ + $t('subscription.managePlan') }} @@ -109,7 +116,7 @@ > {{ - $t('userSettings.title') + $t('userSettings.accountSettings') }} @@ -143,6 +150,7 @@ import { useExternalLink } from '@/composables/useExternalLink' import { useFeatureFlags } from '@/composables/useFeatureFlags' import SubscribeButton from '@/platform/cloud/subscription/components/SubscribeButton.vue' import { useSubscription } from '@/platform/cloud/subscription/composables/useSubscription' +import { useSubscriptionDialog } from '@/platform/cloud/subscription/composables/useSubscriptionDialog' import { isCloud } from '@/platform/distribution/types' import { useTelemetry } from '@/platform/telemetry' import { useDialogService } from '@/services/dialogService' @@ -154,17 +162,18 @@ const emit = defineEmits<{ const { buildDocsUrl } = useExternalLink() -const planSettingsLabel = isCloud - ? 'settingsCategories.PlanCredits' - : 'settingsCategories.Credits' - const { userDisplayName, userEmail, userPhotoUrl, handleSignOut } = useCurrentUser() const authActions = useFirebaseAuthActions() const authStore = useFirebaseAuthStore() const dialogService = useDialogService() -const { isActiveSubscription, subscriptionTierName, fetchStatus } = - useSubscription() +const { + isActiveSubscription, + subscriptionTierName, + subscriptionTier, + fetchStatus +} = useSubscription() +const subscriptionDialog = useSubscriptionDialog() const { flags } = useFeatureFlags() const { locale } = useI18n() @@ -181,11 +190,21 @@ const formattedBalance = computed(() => { }) }) +const canUpgrade = computed(() => { + const tier = subscriptionTier.value + return tier === 'STANDARD' || tier === 'CREATOR' +}) + const handleOpenUserSettings = () => { dialogService.showSettingsDialog('user') emit('close') } +const handleOpenPlansAndPricing = () => { + subscriptionDialog.show() + emit('close') +} + const handleOpenPlanAndCreditsSettings = () => { if (isCloud) { dialogService.showSettingsDialog('subscription') diff --git a/src/locales/en/main.json b/src/locales/en/main.json index e81191442..f6d66f3c2 100644 --- a/src/locales/en/main.json +++ b/src/locales/en/main.json @@ -1976,6 +1976,9 @@ "contactUs": "Contact us", "viewEnterprise": "View enterprise", "partnerNodesCredits": "Partner nodes pricing", + "plansAndPricing": "Plans & pricing", + "managePlan": "Manage plan", + "upgrade": "UPGRADE", "mostPopular": "Most popular", "currentPlan": "Current Plan", "subscribeTo": "Subscribe to {plan}", @@ -2000,6 +2003,7 @@ }, "userSettings": { "title": "My Account Settings", + "accountSettings": "Account settings", "name": "Name", "email": "Email", "provider": "Sign-in Provider",
{{ userEmail }}
+ {{ subscriptionTierName }} -