From c8ec325b44456ca6e16089b94d2ea663464af2bd Mon Sep 17 00:00:00 2001 From: rudransh2003 Date: Fri, 10 Oct 2025 18:02:46 +0530 Subject: [PATCH 01/18] feat:downgrade feature for users to downgrade from higher to lower plans[2164] --- src/assets/icons/ErrorCircleIcon.svelte | 7 + .../ChooseActiveMembersModal.svelte | 232 ++++++++++++++++++ .../ChooseActiveWorkspaceModal.svelte | 228 +++++++++++++++++ .../DowngradePlan/DowngradePlanModal.svelte | 149 +++++++++++ .../ReviewScheduledDowngradeModal.svelte | 106 ++++++++ src/components/Modal/Modal.svelte | 2 +- src/pages/Payment/Overview/Overview.svelte | 67 +++-- .../PaymentInformation/ChangePlanPage.svelte | 223 ++++++++++++++++- .../DowngradeModalButtons.svelte | 63 +++++ 9 files changed, 1039 insertions(+), 38 deletions(-) create mode 100644 src/assets/icons/ErrorCircleIcon.svelte create mode 100644 src/components/DowngradePlan/ChooseActiveMembersModal.svelte create mode 100644 src/components/DowngradePlan/ChooseActiveWorkspaceModal.svelte create mode 100644 src/components/DowngradePlan/DowngradePlanModal.svelte create mode 100644 src/components/DowngradePlan/ReviewScheduledDowngradeModal.svelte create mode 100644 src/ui/DowngradeModalButtons/DowngradeModalButtons.svelte diff --git a/src/assets/icons/ErrorCircleIcon.svelte b/src/assets/icons/ErrorCircleIcon.svelte new file mode 100644 index 00000000..4007810f --- /dev/null +++ b/src/assets/icons/ErrorCircleIcon.svelte @@ -0,0 +1,7 @@ + + + + diff --git a/src/components/DowngradePlan/ChooseActiveMembersModal.svelte b/src/components/DowngradePlan/ChooseActiveMembersModal.svelte new file mode 100644 index 00000000..682b6312 --- /dev/null +++ b/src/components/DowngradePlan/ChooseActiveMembersModal.svelte @@ -0,0 +1,232 @@ + + + +{#if isOpen} + + +{/if} diff --git a/src/components/DowngradePlan/ChooseActiveWorkspaceModal.svelte b/src/components/DowngradePlan/ChooseActiveWorkspaceModal.svelte new file mode 100644 index 00000000..5313e846 --- /dev/null +++ b/src/components/DowngradePlan/ChooseActiveWorkspaceModal.svelte @@ -0,0 +1,228 @@ + + +{#if isOpen} + +{/if} \ No newline at end of file diff --git a/src/components/DowngradePlan/DowngradePlanModal.svelte b/src/components/DowngradePlan/DowngradePlanModal.svelte new file mode 100644 index 00000000..509b48c6 --- /dev/null +++ b/src/components/DowngradePlan/DowngradePlanModal.svelte @@ -0,0 +1,149 @@ + + +
+
+

+ Downgrade to {selectedPlan === 'community' ? 'Community Edition' : `${selectedPlan} Plan`} +

+ +
+ + +
+
+

Hub Name

+

{hubName}

+
+ +
+

Current Plan

+

{currentPlan}

+
+
+ + +

+ Are you sure you want to downgrade your plan from + {currentPlan} to + {selectedPlan}? Some features and access will + change after the downgrade. +

+ + +

+ Here's the major limitations compared to {currentPlan}: +

+ + + +

+ Not sure what's included in each plan? Take a quick look to + + compare plans + + before downgrading. +

+ + + {#if currentPlan !== 'Enterprise'} +
+
+
+ +
+

+ You're downgrading '{hubName}'. Paid features stay active + until + {expiryDate}, after which your hub will move + to the {selectedPlan} plan. +

+
+ {/if} + console.log('Support clicked')} + class="mt-3" + /> +
diff --git a/src/components/DowngradePlan/ReviewScheduledDowngradeModal.svelte b/src/components/DowngradePlan/ReviewScheduledDowngradeModal.svelte new file mode 100644 index 00000000..b19b37b0 --- /dev/null +++ b/src/components/DowngradePlan/ReviewScheduledDowngradeModal.svelte @@ -0,0 +1,106 @@ + + +{#if isOpen} +
+ +
+

+ Please Review Your Scheduled Downgrade +

+ +
+ + +

+ You are about to schedule your downgrade plan from + {currentPlan} edition to + {selectedPlan} edition for + {expiryDate}. + Please review the changes below before you confirm. You can go back to make changes. +

+ + +
+

Active Workspaces

+
+ {#each selectedWorkspaces as ws} + • {ws.name || ws} + {/each} +
+
+ + + {#if selectedPlan?.toLowerCase() === 'community'} +
+

Active Members

+
+ {#each selectedMembers as member} + • {member.email || member} + {/each} +
+
+ {/if} + + +
+

Share Feedback

+ +

{feedback.length}/{maxChars}

+
+ + +
+ window.open('mailto:contactus@sparrowapp.dev', '_blank')} + /> +
+
+{/if} \ No newline at end of file diff --git a/src/components/Modal/Modal.svelte b/src/components/Modal/Modal.svelte index b8f9ae47..b7bca190 100644 --- a/src/components/Modal/Modal.svelte +++ b/src/components/Modal/Modal.svelte @@ -18,7 +18,7 @@ }); -
+
diff --git a/src/pages/Payment/Overview/Overview.svelte b/src/pages/Payment/Overview/Overview.svelte index 9d71a893..5a0c52e1 100644 --- a/src/pages/Payment/Overview/Overview.svelte +++ b/src/pages/Payment/Overview/Overview.svelte @@ -294,6 +294,21 @@ status: subscriptionStatus, userCount: userCount.toString(), inTrial: $hubData?.data?.billing?.in_trial ? 'true' : 'false', + mode: 'upgrade-only', + }); + + navigate(`/billing/billingInformation/changePlan/${hubId}?${searchParams.toString()}`); + } + + function handleChangePlanClick() { + const searchParams = new URLSearchParams({ + currentPlan, + currentBillingCycle, + subscriptionId: subscriptionId || '', + status: subscriptionStatus, + userCount: userCount.toString(), + inTrial: $hubData?.data?.billing?.in_trial ? 'true' : 'false', + mode: 'full-access', }); navigate(`/billing/billingInformation/changePlan/${hubId}?${searchParams.toString()}`); @@ -436,7 +451,7 @@
{/if} -{#if $hubData?.data} +{#if $hubData?.data && currentHubData}
@@ -530,21 +545,27 @@
{#if !isScheduledDowngrade} - {#if subscriptionId && subscriptionData?.status === 'active' && !subscriptionData?.cancel_at_period_end} - - {/if} - {#if subscriptionId && subscriptionData?.cancel_at_period_end} - + {#if currentPlan !== 'Community'} + {#if subscriptionId && subscriptionData?.status === 'active' && !subscriptionData?.cancel_at_period_end} + + {/if} + {#if subscriptionId && subscriptionData?.cancel_at_period_end} + + {/if} + {:else} + + Community plan — upgrade to unlock premium features + {/if} {/if}
@@ -592,14 +613,12 @@

- {#if !isScheduledDowngrade && subscriptionData?.cancel_at_period_end && subscriptionData?.status === 'canceled'} - - {/if} +
diff --git a/src/pages/Payment/PaymentInformation/ChangePlanPage.svelte b/src/pages/Payment/PaymentInformation/ChangePlanPage.svelte index 4e4078ab..45c72a8b 100644 --- a/src/pages/Payment/PaymentInformation/ChangePlanPage.svelte +++ b/src/pages/Payment/PaymentInformation/ChangePlanPage.svelte @@ -7,9 +7,10 @@ // Components import Breadcrumbs from '@/components/Breadcrumbs/Breadcrumbs.svelte'; + import { hubsService } from '@/services/hubs.service'; import Tag from '@/ui/Tag/Tag.svelte'; import Button from '@/ui/Button/Button.svelte'; - + import Modal from '@/components/Modal/Modal.svelte'; // Icons import CheckIcon from '@/assets/icons/Check.svelte'; @@ -25,6 +26,12 @@ type BillingCycleType, } from '@/utils/pricing'; import { captureEvent } from '@/utils/posthogConfig'; + import DowngradePlan from '@/components/DowngradePlan/DowngradePlanModal.svelte'; + import { createQuery } from '@/services/api.common'; + import DowngradePlanModal from '@/components/DowngradePlan/DowngradePlanModal.svelte'; + import ChooseActiveWorkspaceModal from '@/components/DowngradePlan/ChooseActiveWorkspaceModal.svelte'; + import ChooseActiveMembersModal from '@/components/DowngradePlan/ChooseActiveMembersModal.svelte'; + import ReviewScheduledDowngradeModal from '@/components/DowngradePlan/ReviewScheduledDowngradeModal.svelte'; const location = useLocation(); @@ -64,6 +71,33 @@ let subscriptionStatus: string = ''; let userCount: number = 1; let inTrial: boolean = false; + let downgradeModal: boolean = false; + let allowDowngrade: boolean = false; + let selectedPlan: string = ''; + let hubName: string = ''; + let hubWorkspaces: []; + let mode: string = 'upgrade-only'; + let createdAt: string; + let hubUsers:[]; + let downgradeFlow = { + downgradeModal: false, + chooseWorkspaceModal: false, + chooseMembersModal: false, + reviewModal: false, + }; + + + let downgradeData = { + selectedWorkspaces: [], + unselectedWorkspaces: [], + selectedMembers: [], + feedback: '', + }; + + $: { + const searchParams = new URLSearchParams($location?.search || ''); + mode = searchParams.get('mode') || 'upgrade-only'; + } // URL parsing $: { @@ -95,8 +129,26 @@ onMount(async () => { await initializePlanDetails(); planDetails = getCurrentPlanDetails(); + if (hubId) await getHubName(hubId); }); + async function getHubName(hubId: string) { + try { + const response = await hubsService.getHubDetails(hubId); + if (response?.data) { + const data = response.data; + console.log(data); + hubName = data.name || ' '; + hubWorkspaces = data.workspaces; + hubUsers = data.users; + createdAt = data.createdAt; + console.log(hubUsers); + } + } catch (error) { + console.log(error); + } + } + // State let billingCycle: BillingCycleType = currentBillingCycle; @@ -118,6 +170,7 @@ // Handle plan selection function selectPlan(plan) { + selectedPlan = plan; if (plan === 'enterprise') { captureUserPlanUpgradeClick(currentPlan, plan); // Open contact form in a new tab @@ -141,7 +194,10 @@ billingCycle, ); - if (!isDowngradeChange) { + if (isDowngradeChange) { + downgradeFlow.downgradeModal = true; + return; + } else { captureUserPlanUpgradeClick(currentPlan, plan); } @@ -170,10 +226,23 @@ } } - // Check if a plan is selectable based on current plan and billing cycle function isPlanSelectable(plan) { - return checkPlanSelectable(currentPlanLower, plan, billingCycle, currentBillingCycle); + const canSelect = checkPlanSelectable( + currentPlanLower, + plan, + billingCycle, + currentBillingCycle, + ); + + // If mode = 'full-access', allow all plans + if (mode === 'full-access') return true; + + // If mode = 'upgrade-only', disallow downgrades + const currentValue = getPlanValue(currentPlanLower, currentBillingCycle); + const targetValue = getPlanValue(plan, billingCycle); + return targetValue > currentValue; // only higher plans allowed } + // console.log('mode:', mode, 'plan:', plan, 'selectable:', isPlanSelectable(plan)); // Get button text for a plan function getButtonText(plan) { @@ -194,7 +263,7 @@ if (targetPlanValue > currentPlanValue) { return 'Upgrade'; } else if (targetPlanValue < currentPlanValue) { - return 'Downgrade'; + return 'Select Plan'; } else { return 'Your plan'; } @@ -259,6 +328,33 @@ }; captureEvent('admin_plan_upgraded', eventProperties); }; + + function getExpiryDate(createdAt: string): string { + if (!createdAt) return '-'; + const created = new Date(createdAt); + const expiry = new Date(created); + expiry.setDate(expiry.getDate() + 30); + + // Format like "28 Aug 2025, 10:00 AM UTC" + const options: Intl.DateTimeFormatOptions = { + day: '2-digit', + month: 'short', + year: 'numeric', + hour: '2-digit', + minute: '2-digit', + hour12: true, + timeZone: 'UTC', + }; + + // Calculate days left + const now = new Date(); + const diffInMs = expiry.getTime() - now.getTime(); + const daysLeft = Math.max(Math.ceil(diffInMs / (1000 * 60 * 60 * 24)), 0); // avoid negative + + const formattedExpiry = expiry.toLocaleString('en-GB', options) + ' UTC'; + return `${formattedExpiry} (${daysLeft} day${daysLeft !== 1 ? 's' : ''} left)`; + } + $: expiryDate = getExpiryDate(createdAt);
{#each planValues as { plan, planName, isCurrentPlan, planPrice, planUnit, buttonText, hasDiscount, discount }, index}
handleCardHover(index, true)} + class={`overflow-hidden rounded-[10px] border-2 transition-all duration-200 + ${isCurrentPlan ? 'border-neutral-50' : 'border-surface-500'} + ${!isPlanSelectable(plan) && !isCurrentPlan ? 'cursor-not-allowed opacity-40' : 'hover:bg-surface-600 hover:border-surface-50'} + `} + style="transform: scale({hoveredCardIndex === index ? $cardScale : 1});" + on:mouseenter={() => isPlanSelectable(plan) && handleCardHover(index, true)} on:mouseleave={() => handleCardHover(index, false)} > @@ -367,8 +463,14 @@ {:else} @@ -456,6 +558,101 @@
+{#if downgradeFlow.downgradeModal} + (downgradeFlow.downgradeModal = false)}> + (downgradeFlow.downgradeModal = false)} + on:cancel={() => (downgradeFlow.downgradeModal = false)} + on:continue={() => { + downgradeFlow.downgradeModal = false; + downgradeFlow.chooseWorkspaceModal = true; + }} + /> + +{/if} + +{#if downgradeFlow.chooseWorkspaceModal} + { + downgradeFlow.chooseWorkspaceModal = false; + downgradeFlow.downgradeModal = true; // go back to downgrade modal + }} + on:next={(e) => { + downgradeData.selectedWorkspaces = e.detail.selected; + downgradeFlow.chooseWorkspaceModal = false; + + // Skip Active Members step for Standard downgrade + if (selectedPlan?.toLowerCase() === 'standard') { + downgradeFlow.reviewModal = true; + } else { + downgradeFlow.chooseMembersModal = true; + } + }} + /> +{/if} + +{#if downgradeFlow.chooseMembersModal} + u.role === 'owner')} + users={hubUsers} + on:close={() => { + downgradeFlow.chooseMembersModal = false; + downgradeFlow.chooseWorkspaceModal = true; // go back to workspace selection + }} + on:next={(e) => { + downgradeData.selectedMembers = e.detail.selected; + downgradeFlow.chooseMembersModal = false; + downgradeFlow.reviewModal = true; + }} + /> +{/if} + +{#if downgradeFlow.reviewModal} + (downgradeFlow.reviewModal = false)}> + { + downgradeFlow.reviewModal = false; + // Backtrack logic + if (selectedPlan?.toLowerCase() === 'standard') { + downgradeFlow.chooseWorkspaceModal = true; // skip members + } else { + downgradeFlow.chooseMembersModal = true; + } + }} + on:confirm={(e) => { + downgradeData.feedback = e.detail.feedback; + console.log('Final downgrade data:', downgradeData); + downgradeFlow.reviewModal = false; + }} + /> + +{/if} + + From 6e6948f9648eec611f4a8b01d601a97a3f1b927b Mon Sep 17 00:00:00 2001 From: rudransh2003 Date: Mon, 13 Oct 2025 13:17:11 +0530 Subject: [PATCH 02/18] feat:downgrade modals for downgrade from higher to lower plans[2164] --- .../ChooseActiveMembersModal.svelte | 2 - .../ChooseActiveWorkspaceModal.svelte | 9 +++- .../DowngradePlan/DowngradePlanModal.svelte | 1 - src/pages/Payment/Overview/Overview.svelte | 20 +++++---- .../PaymentInformation/ChangePlanPage.svelte | 41 +++++++------------ 5 files changed, 35 insertions(+), 38 deletions(-) diff --git a/src/components/DowngradePlan/ChooseActiveMembersModal.svelte b/src/components/DowngradePlan/ChooseActiveMembersModal.svelte index 682b6312..c9a340c6 100644 --- a/src/components/DowngradePlan/ChooseActiveMembersModal.svelte +++ b/src/components/DowngradePlan/ChooseActiveMembersModal.svelte @@ -11,7 +11,6 @@ const dispatch = createEventDispatcher(); let selected = new Set(); - // ✅ Filter out hub owner $: filteredUsers = Array.isArray(users) ? users.filter((u) => (u.id || u._id) !== (hubOwner?.id || hubOwner?._id)) : []; @@ -46,7 +45,6 @@ } }; - // ✅ Helper: Extract only first name function getFirstName(fullNameOrEmail: string): string { if (!fullNameOrEmail) return ''; if (fullNameOrEmail.includes('@')) { diff --git a/src/components/DowngradePlan/ChooseActiveWorkspaceModal.svelte b/src/components/DowngradePlan/ChooseActiveWorkspaceModal.svelte index 5313e846..1a5e6236 100644 --- a/src/components/DowngradePlan/ChooseActiveWorkspaceModal.svelte +++ b/src/components/DowngradePlan/ChooseActiveWorkspaceModal.svelte @@ -51,8 +51,13 @@ id: ws.id, name: ws.name, })); - - dispatch('next', { selected: selectedWorkspaces }); + const unselectedWorkspaces = workspaces + .filter((ws) => !selected.has(ws.id)) + .map((ws) => ({ + id: ws.id, + name: ws.name, + })); + dispatch('next', { selected: selectedWorkspaces, unselected: unselectedWorkspaces }); }; diff --git a/src/components/DowngradePlan/DowngradePlanModal.svelte b/src/components/DowngradePlan/DowngradePlanModal.svelte index 509b48c6..719144c1 100644 --- a/src/components/DowngradePlan/DowngradePlanModal.svelte +++ b/src/components/DowngradePlan/DowngradePlanModal.svelte @@ -59,7 +59,6 @@ } function handleContinueDowngrade() { - // Simply dispatch 'continue' - let the parent handle opening the next modal dispatch('continue'); } diff --git a/src/pages/Payment/Overview/Overview.svelte b/src/pages/Payment/Overview/Overview.svelte index 5a0c52e1..b98165bf 100644 --- a/src/pages/Payment/Overview/Overview.svelte +++ b/src/pages/Payment/Overview/Overview.svelte @@ -82,6 +82,7 @@ let showResubscribeModal = false; let resubscribeInProgress = false; + // Animation stores for cards const cardOpacity = tweened(0, { duration: 600, @@ -294,13 +295,23 @@ status: subscriptionStatus, userCount: userCount.toString(), inTrial: $hubData?.data?.billing?.in_trial ? 'true' : 'false', - mode: 'upgrade-only', + mode: 'upgrade', }); navigate(`/billing/billingInformation/changePlan/${hubId}?${searchParams.toString()}`); } function handleChangePlanClick() { + captureUserClickUpgradePlan(); + if (planStatus === 'payment_failed' || planStatus === 'action_required') { + if (isRedirecting) { + isRedirecting = false; + return; + } else { + notification.error('Please resolve the payment issue before changing your plan.'); + } + return; + } const searchParams = new URLSearchParams({ currentPlan, currentBillingCycle, @@ -308,7 +319,7 @@ status: subscriptionStatus, userCount: userCount.toString(), inTrial: $hubData?.data?.billing?.in_trial ? 'true' : 'false', - mode: 'full-access', + mode: 'change-plan', }); navigate(`/billing/billingInformation/changePlan/${hubId}?${searchParams.toString()}`); @@ -640,11 +651,6 @@ on:click={handleUpgradeClick} disabled={isScheduledDowngrade || (subscriptionData?.cancel_at_period_end && subscriptionData?.status !== 'canceled')} - tooltipText={isScheduledDowngrade - ? `Scheduled plan change. Your subscription will downgrade on ${nextBillingDate}. Plan changes are locked until then.` - : ''} - tooltipPosition="bottom" - tooltipDelay={100} > Upgrade diff --git a/src/pages/Payment/PaymentInformation/ChangePlanPage.svelte b/src/pages/Payment/PaymentInformation/ChangePlanPage.svelte index 45c72a8b..1721444f 100644 --- a/src/pages/Payment/PaymentInformation/ChangePlanPage.svelte +++ b/src/pages/Payment/PaymentInformation/ChangePlanPage.svelte @@ -76,7 +76,7 @@ let selectedPlan: string = ''; let hubName: string = ''; let hubWorkspaces: []; - let mode: string = 'upgrade-only'; + let mode: string = 'change-plan'; let createdAt: string; let hubUsers:[]; let downgradeFlow = { @@ -96,9 +96,15 @@ $: { const searchParams = new URLSearchParams($location?.search || ''); - mode = searchParams.get('mode') || 'upgrade-only'; + mode = searchParams.get('mode') || 'change-plan'; } + $: pageHeading = mode === 'upgrade' ? 'Upgrade Plan' : 'Change Your Plan'; + $: pageDescription = + mode === 'upgrade' + ? "You're ready for the next level. Upgrade to access more and features. You can switch plans at any time." + : 'Select a different plan that fits your needs. Your current plan is highlighted below. The new plan will take effect immediately or at the start of your next billing cycle depending on your billing terms.'; + // URL parsing $: { const url = $location?.pathname || ''; @@ -227,20 +233,7 @@ } function isPlanSelectable(plan) { - const canSelect = checkPlanSelectable( - currentPlanLower, - plan, - billingCycle, - currentBillingCycle, - ); - - // If mode = 'full-access', allow all plans - if (mode === 'full-access') return true; - - // If mode = 'upgrade-only', disallow downgrades - const currentValue = getPlanValue(currentPlanLower, currentBillingCycle); - const targetValue = getPlanValue(plan, billingCycle); - return targetValue > currentValue; // only higher plans allowed + return true; } // console.log('mode:', mode, 'plan:', plan, 'selectable:', isPlanSelectable(plan)); @@ -269,10 +262,10 @@ } } - // Prepare breadcrumb navigation + $: breadcrumbLabel = mode === 'upgrade' ? 'Upgrade Plan' : 'Change Plan'; $: breadcrumbItems = [ { label: 'Billing', path: `/billing/billingOverview/${hubId}` }, - { label: 'Change Plan', path: '' }, + { label: breadcrumbLabel, path: '' }, ]; // Make plan values reactive @@ -364,11 +357,8 @@
-

Upgrade Plan

-

- You're ready for the next level. Upgrade to access more and features. You can switch plans at - any time. -

+

{pageHeading}

+

{pageDescription}

@@ -590,9 +580,9 @@ }} on:next={(e) => { downgradeData.selectedWorkspaces = e.detail.selected; + downgradeData.unselectedWorkspaces = e.detail.unselected; downgradeFlow.chooseWorkspaceModal = false; - // Skip Active Members step for Standard downgrade if (selectedPlan?.toLowerCase() === 'standard') { downgradeFlow.reviewModal = true; } else { @@ -636,9 +626,8 @@ selectedMembers={downgradeData.selectedMembers} on:close={() => { downgradeFlow.reviewModal = false; - // Backtrack logic if (selectedPlan?.toLowerCase() === 'standard') { - downgradeFlow.chooseWorkspaceModal = true; // skip members + downgradeFlow.chooseWorkspaceModal = true; } else { downgradeFlow.chooseMembersModal = true; } From de4091ffecd826726caef9d0773eedf9bff5f252 Mon Sep 17 00:00:00 2001 From: rudransh2003 Date: Tue, 14 Oct 2025 15:10:04 +0530 Subject: [PATCH 03/18] feat: Selection of members as per selected workspaces when downgrading to community[2164/2545] --- .../ChooseActiveMembersModal.svelte | 379 ++++++++---------- .../ChooseActiveWorkspaceModal.svelte | 364 ++++++++--------- .../Common/TableModalCommonLayout.svelte | 106 +++++ .../DowngradePlan/DowngradePlanModal.svelte | 85 ++-- .../ReviewScheduledDowngradeModal.svelte | 36 +- .../WorkSpaceOverview/BottomWorkspace.svelte | 2 +- .../WorkSpaceOverview.svelte | 1 - .../PaymentInformation/ChangePlanPage.svelte | 80 ++-- 8 files changed, 557 insertions(+), 496 deletions(-) create mode 100644 src/components/DowngradePlan/Common/TableModalCommonLayout.svelte diff --git a/src/components/DowngradePlan/ChooseActiveMembersModal.svelte b/src/components/DowngradePlan/ChooseActiveMembersModal.svelte index c9a340c6..45f343b1 100644 --- a/src/components/DowngradePlan/ChooseActiveMembersModal.svelte +++ b/src/components/DowngradePlan/ChooseActiveMembersModal.svelte @@ -1,230 +1,175 @@ - + return fullNameOrEmail.split(' ')[0]; + } -{#if isOpen} - -