Skip to content

Fix: change-plan from account route #1777

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

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 17 additions & 5 deletions src/lib/components/support.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,29 @@
import { isSupportOnline, showSupportModal } from '$routes/(console)/wizard/support/store';
import { trackEvent } from '$lib/actions/analytics';
import { localeShortTimezoneName, utcHourToLocaleHour } from '$lib/helpers/date';
import { upgradeURL } from '$lib/stores/billing';
import { plansInfo } from '$lib/stores/billing';
import { Card } from '$lib/components/index';
import { app } from '$lib/stores/app';
import { currentPlan } from '$lib/stores/organization';
import { currentPlan, type Organization, organizationList } from '$lib/stores/organization';
import { isCloud } from '$lib/system';
import { base } from '$app/paths';

export let show = false;

export let showHeader = true;

$: hasPremiumSupport = $currentPlan?.premiumSupport ?? false;
$: hasPremiumSupport = $currentPlan?.premiumSupport ?? allOrgsHavePremiumSupport ?? false;

$: allOrgsHavePremiumSupport = $organizationList.teams.every(
(team) => $plansInfo.get((team as Organization).billingPlan)?.premiumSupport
);
Comment on lines +19 to +23
Copy link
Contributor

Choose a reason for hiding this comment

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

I'd recommend allowing premiums support if they have at least 1 org with premium support.

Copy link
Member Author

Choose a reason for hiding this comment

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

We actually cannot/should not.

The issue is that we have a very different flow on Project > Support & Account > Support.

  1. On project or Org routes, we know what to check for premium support checks
  2. On others where Org can be multiple and no access to them, we don't have a way to use that org for premium support because an issue could be tied to some other Project's org.

I'd recommend allowing premiums support if they have at least 1 org with premium support.

But then, if they have an issue with another organization, those projects won't show in the dropdown.


I'd rather suggest something like this if we don't want this -

  1. Have Project or Org access > Show normal flow > Premium support or Get premium support
  2. No access to Project or Org. > Show an Org selector dropdown > Based on selected Org, check if they have premium support > Support OR Get premium support.

WDYT?

Copy link
Contributor

Choose a reason for hiding this comment

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

On others where Org can be multiple and no access to them

What do you mean? Don't we have the list of the user's orgs here:

organizations: isCloud
? await sdk.forConsole.billing.listOrganization()
: await sdk.forConsole.teams.list()
};

Can't we filter that to check if there are any orgs that have support enabled?

Also, right now, the project list just fetches the 1st 25 projects irrespective of the org:

const projectList = await sdk.forConsole.projects.list();
options = projectList.projects.map((project) => ({
value: project.$id,
label: project.name
}));

I plan on changing the support form anyway so I'll take care of adding an org dropdown and filtering by project.

Copy link
Member Author

@ItzNotABug ItzNotABug Apr 12, 2025

Choose a reason for hiding this comment

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

What do you mean? Don't we have the list of the user's orgs here:

We do, but assume that a user has an issue with a Project XYZ in Org 1, but premium is only on Org 2. If we allow premium support, projects from Org 1 won't show in the dropdown, right?

Copy link
Contributor

Choose a reason for hiding this comment

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

We do, but assume that a user has an issue with a Project XYZ in Org 1, but premium is only on Org 2. If we allow premium support, projects from Org 1 won't show in the dropdown, right?

@ItzNotABug, that's not how it works today. I can tweak it later to filter the projects. It's fine if they submit a ticket for a project they don't have the pro plan for. We'll address it in the support ticket.


// there can only be one free organization
$: freeOrganization = $organizationList.teams.find(
(team) => !$plansInfo.get((team as Organization).billingPlan)?.premiumSupport
);

$: upgradeURL = `${base}/organization-${freeOrganization.$id}/change-plan`;

$: supportTimings = `${utcHourToLocaleHour('16:00')} - ${utcHourToLocaleHour('00:00')} ${localeShortTimezoneName()}`;

Expand Down Expand Up @@ -54,7 +66,7 @@
}
];

const showCloudSupport = (index) => {
const showCloudSupport = (index: number) => {
return (index === 0 && isCloud) || index > 0;
};
</script>
Expand Down Expand Up @@ -82,7 +94,7 @@
<div class="u-flex u-gap-12 u-cross-center">
{#if !hasPremiumSupport}
<Button
href={$upgradeURL}
href={upgradeURL}
on:click={() => {
trackEvent('click_organization_upgrade', {
from: 'button',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,13 @@
WizardSecondaryFooter
} from '$lib/layout';
import { type Coupon, type PaymentList } from '$lib/sdk/billing';
import { isOrganization, plansInfo, tierToPlan, type Tier } from '$lib/stores/billing';
import { isOrganization, plansInfo, type Tier, tierToPlan } from '$lib/stores/billing';
import { addNotification } from '$lib/stores/notifications';
import {
currentPlan,
organization,
organizationList,
type Organization
type Organization,
organizationList
} from '$lib/stores/organization';
import { sdk } from '$lib/stores/sdk';
import { confirmPayment } from '$lib/stores/stripe';
Expand Down Expand Up @@ -83,8 +83,7 @@
if ($page.url.searchParams.has('code')) {
const coupon = $page.url.searchParams.get('code');
try {
const response = await sdk.forConsole.billing.getCouponAccount(coupon);
couponData = response;
couponData = await sdk.forConsole.billing.getCouponAccount(coupon);
} catch (e) {
couponData = {
code: null,
Expand Down Expand Up @@ -137,7 +136,7 @@
async function downgrade() {
try {
await sdk.forConsole.billing.updatePlan(
$organization.$id,
selectedOrg.$id,
billingPlan,
paymentMethodId,
null
Expand All @@ -155,7 +154,7 @@
reason: feedbackDowngradeOptions.find(
(option) => option.value === feedbackDowngradeReason
)?.label,
orgId: $organization.$id,
orgId: selectedOrg.$id,
userId: $user.$id,
message: feedbackMessage ?? ''
})
Expand All @@ -168,7 +167,7 @@
type: 'success',
isHtml: true,
message: `
<b>${$organization.name}</b> plan has been successfully updated.`
<b>${selectedOrg.name}</b> plan has been successfully updated.`
});

trackEvent(Submit.OrganizationDowngrade, {
Expand Down Expand Up @@ -211,7 +210,7 @@

async function upgrade() {
try {
//Add collaborators
// Add collaborators
let newCollaborators = [];
if (collaborators?.length) {
newCollaborators = collaborators.filter(
Expand All @@ -220,7 +219,7 @@
);
}
const org = await sdk.forConsole.billing.updatePlan(
$organization.$id,
selectedOrg.$id,
billingPlan,
paymentMethodId,
null,
Expand Down Expand Up @@ -274,9 +273,15 @@
}
}

$: isSamePlan = billingPlan === $currentPlan.$id;
$: isUpgrade = isSamePlan ? false : $plansInfo.get(billingPlan)?.order > $currentPlan.order;
$: isDowngrade = isSamePlan ? false : $plansInfo.get(billingPlan)?.order < $currentPlan.order;
$: selectedOrg =
$organization ??
($organizationList.teams.find(
(team) => team.$id === $page.params.organization
) as Organization);
$: currentOrgPlan = $currentPlan ?? $plansInfo.get(selectedOrg?.billingPlan);
$: isSamePlan = billingPlan === currentOrgPlan.$id;
$: isUpgrade = isSamePlan ? false : $plansInfo.get(billingPlan)?.order > currentOrgPlan.order;
$: isDowngrade = isSamePlan ? false : $plansInfo.get(billingPlan)?.order < currentOrgPlan.order;
$: if (billingPlan !== BillingPlan.FREE) {
loadPaymentMethods();
}
Expand Down Expand Up @@ -313,10 +318,10 @@
<Alert type="warning" class="u-margin-block-start-24">
<svelte:fragment slot="title">
Your organization will switch to {tierToPlan(billingPlan).name} plan on {toLocaleDate(
$organization.billingNextInvoiceDate
selectedOrg.billingNextInvoiceDate
)}.
</svelte:fragment>
You will retain access to {tierToPlan($organization.billingPlan).name} plan features
You will retain access to {tierToPlan(selectedOrg.billingPlan).name} plan features
until your billing period ends. {#if extraMembers > 0}After that,
<b
>you will be charged {formatCurrency(
Expand All @@ -328,7 +333,7 @@
{/if}
{/if}
<!-- Show email input if upgrading from free plan -->
{#if billingPlan !== BillingPlan.FREE && $organization.billingPlan !== billingPlan && $organization.billingPlan !== BillingPlan.CUSTOM && isUpgrade}
{#if billingPlan !== BillingPlan.FREE && selectedOrg.billingPlan !== billingPlan && selectedOrg.billingPlan !== BillingPlan.CUSTOM && isUpgrade}
<FormList class="u-margin-block-start-16">
<InputTags
bind:tags={collaborators}
Expand Down Expand Up @@ -369,14 +374,14 @@
{/if}
</Form>
<svelte:fragment slot="aside">
{#if billingPlan !== BillingPlan.FREE && $organization.billingPlan !== billingPlan && $organization.billingPlan !== BillingPlan.CUSTOM && isUpgrade}
{#if billingPlan !== BillingPlan.FREE && selectedOrg.billingPlan !== billingPlan && selectedOrg.billingPlan !== BillingPlan.CUSTOM && isUpgrade}
<EstimatedTotal
bind:billingBudget
bind:couponData
organizationId={$organization.$id}
organizationId={selectedOrg.$id}
{billingPlan}
{collaborators} />
{:else if $organization.billingPlan !== BillingPlan.CUSTOM}
{:else if selectedOrg.billingPlan !== BillingPlan.CUSTOM}
<PlanComparisonBox downgrade={isDowngrade} />
{/if}
</svelte:fragment>
Expand Down