satellite/{web,console}: enable/disable billing features depending on config value
Added client side logic to disable billing features depending on config value. Disabled billing endpoints if billing is disabled. Issue: https://github.com/storj/storj-private/issues/464 Change-Id: I6e70dc5e2372953b613ddab9f19cb94f008935ce
This commit is contained in:
parent
bce022ea7a
commit
6ae28e2306
@ -336,29 +336,31 @@ func NewServer(logger *zap.Logger, config Config, service *console.Service, oidc
|
||||
abRouter.Handle("/hit/{action}", http.HandlerFunc(abController.SendHit)).Methods(http.MethodPost, http.MethodOptions)
|
||||
}
|
||||
|
||||
paymentController := consoleapi.NewPayments(logger, service, accountFreezeService, packagePlans)
|
||||
paymentsRouter := router.PathPrefix("/api/v0/payments").Subrouter()
|
||||
paymentsRouter.Use(server.withCORS)
|
||||
paymentsRouter.Use(server.withAuth)
|
||||
paymentsRouter.Handle("/cards", server.userIDRateLimiter.Limit(http.HandlerFunc(paymentController.AddCreditCard))).Methods(http.MethodPost, http.MethodOptions)
|
||||
paymentsRouter.HandleFunc("/cards", paymentController.MakeCreditCardDefault).Methods(http.MethodPatch, http.MethodOptions)
|
||||
paymentsRouter.HandleFunc("/cards", paymentController.ListCreditCards).Methods(http.MethodGet, http.MethodOptions)
|
||||
paymentsRouter.HandleFunc("/cards/{cardId}", paymentController.RemoveCreditCard).Methods(http.MethodDelete, http.MethodOptions)
|
||||
paymentsRouter.HandleFunc("/account/charges", paymentController.ProjectsCharges).Methods(http.MethodGet, http.MethodOptions)
|
||||
paymentsRouter.HandleFunc("/account/balance", paymentController.AccountBalance).Methods(http.MethodGet, http.MethodOptions)
|
||||
paymentsRouter.HandleFunc("/account", paymentController.SetupAccount).Methods(http.MethodPost, http.MethodOptions)
|
||||
paymentsRouter.HandleFunc("/wallet", paymentController.GetWallet).Methods(http.MethodGet, http.MethodOptions)
|
||||
paymentsRouter.HandleFunc("/wallet", paymentController.ClaimWallet).Methods(http.MethodPost, http.MethodOptions)
|
||||
paymentsRouter.HandleFunc("/wallet/payments", paymentController.WalletPayments).Methods(http.MethodGet, http.MethodOptions)
|
||||
paymentsRouter.HandleFunc("/wallet/payments-with-confirmations", paymentController.WalletPaymentsWithConfirmations).Methods(http.MethodGet, http.MethodOptions)
|
||||
paymentsRouter.HandleFunc("/billing-history", paymentController.BillingHistory).Methods(http.MethodGet, http.MethodOptions)
|
||||
paymentsRouter.HandleFunc("/invoice-history", paymentController.InvoiceHistory).Methods(http.MethodGet, http.MethodOptions)
|
||||
paymentsRouter.Handle("/coupon/apply", server.userIDRateLimiter.Limit(http.HandlerFunc(paymentController.ApplyCouponCode))).Methods(http.MethodPatch, http.MethodOptions)
|
||||
paymentsRouter.HandleFunc("/coupon", paymentController.GetCoupon).Methods(http.MethodGet, http.MethodOptions)
|
||||
paymentsRouter.HandleFunc("/pricing", paymentController.GetProjectUsagePriceModel).Methods(http.MethodGet, http.MethodOptions)
|
||||
if config.PricingPackagesEnabled {
|
||||
paymentsRouter.HandleFunc("/purchase-package", paymentController.PurchasePackage).Methods(http.MethodPost, http.MethodOptions)
|
||||
paymentsRouter.HandleFunc("/package-available", paymentController.PackageAvailable).Methods(http.MethodGet, http.MethodOptions)
|
||||
if config.BillingFeaturesEnabled {
|
||||
paymentController := consoleapi.NewPayments(logger, service, accountFreezeService, packagePlans)
|
||||
paymentsRouter := router.PathPrefix("/api/v0/payments").Subrouter()
|
||||
paymentsRouter.Use(server.withCORS)
|
||||
paymentsRouter.Use(server.withAuth)
|
||||
paymentsRouter.Handle("/cards", server.userIDRateLimiter.Limit(http.HandlerFunc(paymentController.AddCreditCard))).Methods(http.MethodPost, http.MethodOptions)
|
||||
paymentsRouter.HandleFunc("/cards", paymentController.MakeCreditCardDefault).Methods(http.MethodPatch, http.MethodOptions)
|
||||
paymentsRouter.HandleFunc("/cards", paymentController.ListCreditCards).Methods(http.MethodGet, http.MethodOptions)
|
||||
paymentsRouter.HandleFunc("/cards/{cardId}", paymentController.RemoveCreditCard).Methods(http.MethodDelete, http.MethodOptions)
|
||||
paymentsRouter.HandleFunc("/account/charges", paymentController.ProjectsCharges).Methods(http.MethodGet, http.MethodOptions)
|
||||
paymentsRouter.HandleFunc("/account/balance", paymentController.AccountBalance).Methods(http.MethodGet, http.MethodOptions)
|
||||
paymentsRouter.HandleFunc("/account", paymentController.SetupAccount).Methods(http.MethodPost, http.MethodOptions)
|
||||
paymentsRouter.HandleFunc("/wallet", paymentController.GetWallet).Methods(http.MethodGet, http.MethodOptions)
|
||||
paymentsRouter.HandleFunc("/wallet", paymentController.ClaimWallet).Methods(http.MethodPost, http.MethodOptions)
|
||||
paymentsRouter.HandleFunc("/wallet/payments", paymentController.WalletPayments).Methods(http.MethodGet, http.MethodOptions)
|
||||
paymentsRouter.HandleFunc("/wallet/payments-with-confirmations", paymentController.WalletPaymentsWithConfirmations).Methods(http.MethodGet, http.MethodOptions)
|
||||
paymentsRouter.HandleFunc("/billing-history", paymentController.BillingHistory).Methods(http.MethodGet, http.MethodOptions)
|
||||
paymentsRouter.HandleFunc("/invoice-history", paymentController.InvoiceHistory).Methods(http.MethodGet, http.MethodOptions)
|
||||
paymentsRouter.Handle("/coupon/apply", server.userIDRateLimiter.Limit(http.HandlerFunc(paymentController.ApplyCouponCode))).Methods(http.MethodPatch, http.MethodOptions)
|
||||
paymentsRouter.HandleFunc("/coupon", paymentController.GetCoupon).Methods(http.MethodGet, http.MethodOptions)
|
||||
paymentsRouter.HandleFunc("/pricing", paymentController.GetProjectUsagePriceModel).Methods(http.MethodGet, http.MethodOptions)
|
||||
if config.PricingPackagesEnabled {
|
||||
paymentsRouter.HandleFunc("/purchase-package", paymentController.PurchasePackage).Methods(http.MethodPost, http.MethodOptions)
|
||||
paymentsRouter.HandleFunc("/package-available", paymentController.PackageAvailable).Methods(http.MethodGet, http.MethodOptions)
|
||||
}
|
||||
}
|
||||
|
||||
bucketsController := consoleapi.NewBuckets(logger, service)
|
||||
|
@ -9,7 +9,7 @@
|
||||
<ProjectIcon />
|
||||
<h1 class="modal__header__title">Get more projects</h1>
|
||||
</div>
|
||||
<p v-if="!isPaidTier" class="modal__info">
|
||||
<p v-if="!isPaidTier && billingEnabled" class="modal__info">
|
||||
Upgrade to Pro Account to create more projects and gain access to higher limits.
|
||||
</p>
|
||||
<p v-else class="modal__info">
|
||||
@ -45,6 +45,7 @@ import { computed } from 'vue';
|
||||
import { MODALS } from '@/utils/constants/appStatePopUps';
|
||||
import { useAppStore } from '@/store/modules/appStore';
|
||||
import { useUsersStore } from '@/store/modules/usersStore';
|
||||
import { useConfigStore } from '@/store/modules/configStore';
|
||||
|
||||
import VButton from '@/components/common/VButton.vue';
|
||||
import VModal from '@/components/common/VModal.vue';
|
||||
@ -53,14 +54,20 @@ import ProjectIcon from '@/../static/images/common/blueBox.svg';
|
||||
|
||||
const appStore = useAppStore();
|
||||
const userStore = useUsersStore();
|
||||
const configStore = useConfigStore();
|
||||
|
||||
const isPaidTier = computed<boolean>(() => userStore.state.user.paidTier);
|
||||
|
||||
/**
|
||||
* Indicates if billing features are enabled.
|
||||
*/
|
||||
const billingEnabled = computed<boolean>(() => configStore.state.config.billingFeaturesEnabled);
|
||||
|
||||
/**
|
||||
* Returns button text label depending on if the user is in the free or paid tier.
|
||||
*/
|
||||
const buttonLabel = computed<string>(() => {
|
||||
return isPaidTier.value ? 'Request -->' : 'Upgrade -->';
|
||||
return !isPaidTier.value && billingEnabled.value ? 'Upgrade -->' : 'Request -->';
|
||||
});
|
||||
|
||||
/**
|
||||
@ -69,7 +76,7 @@ const buttonLabel = computed<string>(() => {
|
||||
* Redirects to upgrade modal or opens new tab to request increase project limits .
|
||||
*/
|
||||
function onClick(): void {
|
||||
if (!isPaidTier.value) {
|
||||
if (!isPaidTier.value && billingEnabled.value) {
|
||||
appStore.updateActiveModal(MODALS.upgradeAccount);
|
||||
} else {
|
||||
appStore.removeActiveModal();
|
||||
|
@ -8,8 +8,10 @@
|
||||
<AccountIcon class="account-area__wrap__left__icon" />
|
||||
<p class="account-area__wrap__left__label">My Account</p>
|
||||
<p class="account-area__wrap__left__label-small">Account</p>
|
||||
<TierBadgePro v-if="user.paidTier" class="account-area__wrap__left__tier-badge" />
|
||||
<TierBadgeFree v-else class="account-area__wrap__left__tier-badge" />
|
||||
<template v-if="billingEnabled">
|
||||
<TierBadgePro v-if="isPaidTier" class="account-area__wrap__left__tier-badge" />
|
||||
<TierBadgeFree v-else class="account-area__wrap__left__tier-badge" />
|
||||
</template>
|
||||
</div>
|
||||
<ArrowImage class="account-area__wrap__arrow" />
|
||||
</div>
|
||||
@ -31,11 +33,11 @@
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="!user.paidTier" tabindex="0" class="account-area__dropdown__item" @click="onUpgrade" @keyup.enter="onUpgrade">
|
||||
<div v-if="!isPaidTier && billingEnabled" tabindex="0" class="account-area__dropdown__item" @click="onUpgrade" @keyup.enter="onUpgrade">
|
||||
<UpgradeIcon />
|
||||
<p class="account-area__dropdown__item__label">Upgrade</p>
|
||||
</div>
|
||||
<div tabindex="0" class="account-area__dropdown__item" @click="navigateToBilling" @keyup.enter="navigateToBilling">
|
||||
<div v-if="billingEnabled" tabindex="0" class="account-area__dropdown__item" @click="navigateToBilling" @keyup.enter="navigateToBilling">
|
||||
<BillingIcon />
|
||||
<p class="account-area__dropdown__item__label">Billing</p>
|
||||
</div>
|
||||
@ -55,7 +57,6 @@
|
||||
import { computed, ref } from 'vue';
|
||||
import { useRoute, useRouter } from 'vue-router';
|
||||
|
||||
import { User } from '@/types/users';
|
||||
import { RouteConfig } from '@/types/router';
|
||||
import { AuthHttpApi } from '@/api/auth';
|
||||
import { AnalyticsErrorEventSource, AnalyticsEvent } from '@/utils/constants/analyticsEventNames';
|
||||
@ -108,6 +109,11 @@ const dropdownYPos = ref<number>(0);
|
||||
const dropdownXPos = ref<number>(0);
|
||||
const accountArea = ref<HTMLDivElement>();
|
||||
|
||||
/**
|
||||
* Indicates if billing features are enabled.
|
||||
*/
|
||||
const billingEnabled = computed<boolean>(() => configStore.state.config.billingFeaturesEnabled);
|
||||
|
||||
/**
|
||||
* Returns bottom and left position of dropdown.
|
||||
*/
|
||||
@ -130,10 +136,10 @@ const satellite = computed((): string => {
|
||||
});
|
||||
|
||||
/**
|
||||
* Returns user entity from store.
|
||||
* Indicates if user is in paid tier.
|
||||
*/
|
||||
const user = computed((): User => {
|
||||
return usersStore.state.user;
|
||||
const isPaidTier = computed((): boolean => {
|
||||
return usersStore.state.user.paidTier;
|
||||
});
|
||||
|
||||
/**
|
||||
@ -142,6 +148,8 @@ const user = computed((): User => {
|
||||
function onUpgrade(): void {
|
||||
closeDropdown();
|
||||
|
||||
if (!billingEnabled.value) return;
|
||||
|
||||
appStore.updateActiveModal(MODALS.upgradeAccount);
|
||||
}
|
||||
|
||||
@ -204,12 +212,15 @@ function toggleDropdown(): void {
|
||||
}
|
||||
|
||||
const DROPDOWN_HEIGHT = 224; // pixels
|
||||
const SIXTEEN_PIXELS = 16;
|
||||
const FIFTY_THREE_PIXELS = 53; // height of a single child element.
|
||||
const TWENTY_PIXELS = 20;
|
||||
const SEVENTY_PIXELS = 70;
|
||||
const accountContainer = accountArea.value.getBoundingClientRect();
|
||||
|
||||
dropdownYPos.value = accountContainer.bottom - DROPDOWN_HEIGHT - (usersStore.state.user.paidTier ? SIXTEEN_PIXELS : SEVENTY_PIXELS);
|
||||
if (billingEnabled.value) {
|
||||
dropdownYPos.value = accountContainer.bottom - DROPDOWN_HEIGHT - (isPaidTier.value ? 0 : FIFTY_THREE_PIXELS);
|
||||
} else {
|
||||
dropdownYPos.value = accountContainer.bottom - DROPDOWN_HEIGHT + FIFTY_THREE_PIXELS;
|
||||
}
|
||||
dropdownXPos.value = accountContainer.right - TWENTY_PIXELS;
|
||||
|
||||
appStore.toggleActiveDropdown(APP_STATE_DROPDOWNS.ACCOUNT);
|
||||
|
@ -157,8 +157,10 @@
|
||||
<AccountIcon class="account-area__wrap__left__icon" />
|
||||
<p class="account-area__wrap__left__label">My Account</p>
|
||||
<p class="account-area__wrap__left__label-small">Account</p>
|
||||
<TierBadgePro v-if="user.paidTier" class="account-area__wrap__left__tier-badge" />
|
||||
<TierBadgeFree v-else class="account-area__wrap__left__tier-badge" />
|
||||
<template v-if="billingEnabled">
|
||||
<TierBadgePro v-if="user.paidTier" class="account-area__wrap__left__tier-badge" />
|
||||
<TierBadgeFree v-else class="account-area__wrap__left__tier-badge" />
|
||||
</template>
|
||||
</div>
|
||||
<ArrowIcon class="account-area__wrap__arrow" />
|
||||
</div>
|
||||
@ -180,11 +182,11 @@
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="!user.paidTier" tabindex="0" class="account-area__dropdown__item" @click="onUpgrade" @keyup.enter="onUpgrade">
|
||||
<div v-if="!user.paidTier && billingEnabled" tabindex="0" class="account-area__dropdown__item" @click="onUpgrade" @keyup.enter="onUpgrade">
|
||||
<UpgradeIcon />
|
||||
<p class="account-area__dropdown__item__label">Upgrade</p>
|
||||
</div>
|
||||
<div class="account-area__dropdown__item" @click="navigateToBilling">
|
||||
<div v-if="billingEnabled" class="account-area__dropdown__item" @click="navigateToBilling">
|
||||
<BillingIcon />
|
||||
<p class="account-area__dropdown__item__label">Billing</p>
|
||||
</div>
|
||||
@ -294,7 +296,12 @@ const isAccountDropdownShown = ref<boolean>(false);
|
||||
const isOpened = ref<boolean>(false);
|
||||
const isLoading = ref<boolean>(false);
|
||||
|
||||
/*
|
||||
/**
|
||||
* Indicates if billing features are enabled.
|
||||
*/
|
||||
const billingEnabled = computed<boolean>(() => configStore.state.config.billingFeaturesEnabled);
|
||||
|
||||
/**
|
||||
* Whether the user is the owner of the selected project.
|
||||
*/
|
||||
const isProjectOwner = computed((): boolean => {
|
||||
@ -525,6 +532,9 @@ function onCreateLinkClick(): void {
|
||||
*/
|
||||
function onUpgrade(): void {
|
||||
isOpened.value = false;
|
||||
|
||||
if (!billingEnabled.value) return;
|
||||
|
||||
appStore.updateActiveModal(MODALS.upgradeAccount);
|
||||
}
|
||||
|
||||
@ -893,7 +903,7 @@ async function onLogout(): Promise<void> {
|
||||
|
||||
&__wrap {
|
||||
box-sizing: border-box;
|
||||
padding: 16px 32px;
|
||||
padding: 16px 32px 16px 36px;
|
||||
height: 48px;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
@ -930,7 +940,7 @@ async function onLogout(): Promise<void> {
|
||||
|
||||
&__header {
|
||||
background: var(--c-grey-1);
|
||||
padding: 16px 32px;
|
||||
padding: 16px 32px 16px 36px;
|
||||
border: 1px solid var(--c-grey-2);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@ -964,7 +974,7 @@ async function onLogout(): Promise<void> {
|
||||
&__item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 16px 32px;
|
||||
padding: 16px 32px 16px 36px;
|
||||
background: var(--c-grey-1);
|
||||
|
||||
&__label {
|
||||
|
@ -73,10 +73,11 @@ function closePicker(): void {
|
||||
|
||||
<style scoped lang="scss">
|
||||
.range-selection {
|
||||
background-color: #fff;
|
||||
background-color: var(--c-white);
|
||||
cursor: pointer;
|
||||
font-family: 'font_regular', sans-serif;
|
||||
position: relative;
|
||||
border-radius: 8px;
|
||||
|
||||
&__toggle-container {
|
||||
display: flex;
|
||||
|
@ -46,7 +46,7 @@
|
||||
'https://supportdcs.storj.io/hc/en-us/requests/new?ticket_form_id=360000683212'"
|
||||
/>
|
||||
<LimitCard
|
||||
v-if="coupon && isFreeTierCoupon"
|
||||
v-if="coupon && isFreeTierCoupon && billingEnabled"
|
||||
:icon="CheckmarkIcon"
|
||||
title="Free Tier"
|
||||
color="#091c45"
|
||||
@ -62,7 +62,7 @@
|
||||
link="https://docs.storj.io/dcs/pricing#free-tier"
|
||||
/>
|
||||
<LimitCard
|
||||
v-if="coupon && !isFreeTierCoupon"
|
||||
v-if="coupon && !isFreeTierCoupon && billingEnabled"
|
||||
:icon="CheckmarkIcon"
|
||||
title="Coupon"
|
||||
color="#091c45"
|
||||
@ -95,6 +95,7 @@ import { Coupon, ProjectCharges } from '@/types/payments';
|
||||
import { centsToDollars } from '@/utils/strings';
|
||||
import { MODALS } from '@/utils/constants/appStatePopUps';
|
||||
import { RouteConfig } from '@/types/router';
|
||||
import { useConfigStore } from '@/store/modules/configStore';
|
||||
|
||||
import LimitCard from '@/components/project/dashboard/LimitCard.vue';
|
||||
|
||||
@ -107,6 +108,8 @@ const appStore = useAppStore();
|
||||
const usersStore = useUsersStore();
|
||||
const projectsStore = useProjectsStore();
|
||||
const billingStore = useBillingStore();
|
||||
const configStore = useConfigStore();
|
||||
|
||||
const router = useRouter();
|
||||
|
||||
const props = defineProps<{
|
||||
@ -116,6 +119,11 @@ const props = defineProps<{
|
||||
const EIGHTY_PERCENT = 80;
|
||||
const HUNDRED_PERCENT = 100;
|
||||
|
||||
/**
|
||||
* Indicates if billing features are enabled.
|
||||
*/
|
||||
const billingEnabled = computed<boolean>(() => configStore.state.config.billingFeaturesEnabled);
|
||||
|
||||
/**
|
||||
* Returns coupon from store.
|
||||
*/
|
||||
@ -305,6 +313,8 @@ function usageAction(limit: LimitToChange): void {
|
||||
* Starts upgrade account flow.
|
||||
*/
|
||||
function startUpgradeFlow(): void {
|
||||
if (!billingEnabled.value) return;
|
||||
|
||||
appStore.updateActiveModal(MODALS.upgradeAccount);
|
||||
}
|
||||
|
||||
|
@ -22,7 +22,7 @@
|
||||
:toggle="toggleChartsDatePicker"
|
||||
/>
|
||||
<VButton
|
||||
v-if="!isProAccount"
|
||||
v-if="!isProAccount && billingEnabled"
|
||||
label="Upgrade Plan"
|
||||
width="114px"
|
||||
height="40px"
|
||||
@ -145,6 +145,7 @@
|
||||
</template>
|
||||
</InfoContainer>
|
||||
<InfoContainer
|
||||
v-if="billingEnabled"
|
||||
:icon="BillingIcon"
|
||||
title="Billing"
|
||||
:subtitle="status"
|
||||
@ -191,7 +192,8 @@ import { useProjectMembersStore } from '@/store/modules/projectMembersStore';
|
||||
import { useAccessGrantsStore } from '@/store/modules/accessGrantsStore';
|
||||
import { centsToDollars } from '@/utils/strings';
|
||||
import { User } from '@/types/users';
|
||||
import { ProjectRole } from '@/types/projectMembers';
|
||||
import { ProjectMembersPage, ProjectRole } from '@/types/projectMembers';
|
||||
import { AccessGrantsPage } from '@/types/accessGrants';
|
||||
import { useAnalyticsStore } from '@/store/modules/analyticsStore';
|
||||
import { useCreateProjectClickHandler } from '@/composables/useCreateProjectClickHandler';
|
||||
|
||||
@ -237,6 +239,11 @@ const isServerSideEncryptionBannerHidden = ref<boolean>(true);
|
||||
const chartWidth = ref<number>(0);
|
||||
const chartContainer = ref<HTMLDivElement>();
|
||||
|
||||
/**
|
||||
* Indicates if billing features are enabled.
|
||||
*/
|
||||
const billingEnabled = computed<boolean>(() => configStore.state.config.billingFeaturesEnabled);
|
||||
|
||||
/**
|
||||
* Indicates if charts date picker is shown.
|
||||
*/
|
||||
@ -393,6 +400,8 @@ function getDimension(dataStamps: DataStamp[]): Dimensions {
|
||||
* Holds on upgrade button click logic.
|
||||
*/
|
||||
function onUpgradeClick(): void {
|
||||
if (!billingEnabled.value) return;
|
||||
|
||||
appStore.updateActiveModal(MODALS.upgradeAccount);
|
||||
}
|
||||
|
||||
@ -472,21 +481,26 @@ onMounted(async (): Promise<void> => {
|
||||
appStore.toggleHasJustLoggedIn();
|
||||
}
|
||||
|
||||
await Promise.all([
|
||||
const promises: Promise<void | ProjectMembersPage | AccessGrantsPage>[] = [
|
||||
projectsStore.getDailyProjectData({ since: past, before: now }),
|
||||
billingStore.getCoupon(),
|
||||
pmStore.getProjectMembers(FIRST_PAGE, projectID),
|
||||
agStore.getAccessGrants(FIRST_PAGE, projectID),
|
||||
]);
|
||||
];
|
||||
|
||||
if (billingEnabled.value) promises.push(billingStore.getCoupon());
|
||||
|
||||
await Promise.all(promises);
|
||||
} catch (error) {
|
||||
notify.notifyError(error, AnalyticsErrorEventSource.PROJECT_DASHBOARD_PAGE);
|
||||
} finally {
|
||||
isDataFetching.value = false;
|
||||
}
|
||||
|
||||
billingStore.getProjectUsageAndChargesCurrentRollup().catch(error => {
|
||||
notify.notifyError(error, AnalyticsErrorEventSource.PROJECT_DASHBOARD_PAGE);
|
||||
});
|
||||
if (billingEnabled.value) {
|
||||
billingStore.getProjectUsageAndChargesCurrentRollup().catch(error => {
|
||||
notify.notifyError(error, AnalyticsErrorEventSource.PROJECT_DASHBOARD_PAGE);
|
||||
});
|
||||
}
|
||||
|
||||
try {
|
||||
await bucketsStore.getBuckets(FIRST_PAGE, projectID);
|
||||
@ -656,8 +670,7 @@ onBeforeUnmount((): void => {
|
||||
&__info {
|
||||
display: flex;
|
||||
margin-top: 16px;
|
||||
justify-content: space-between;
|
||||
align-items: stretch;
|
||||
column-gap: 10px;
|
||||
flex-wrap: wrap;
|
||||
|
||||
.info-container {
|
||||
|
@ -388,6 +388,12 @@ router.beforeEach(async (to, from, next) => {
|
||||
appStore.toggleHasJustLoggedIn(false);
|
||||
}
|
||||
|
||||
if (!configStore.state.config.billingFeaturesEnabled && to.path.includes(RouteConfig.Billing.path)) {
|
||||
next(RouteConfig.Account.with(RouteConfig.Settings).path);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (navigateToDefaultSubTab(to.matched, RouteConfig.Account)) {
|
||||
next(RouteConfig.Account.with(RouteConfig.Billing).path);
|
||||
|
||||
|
@ -73,6 +73,11 @@ const projectsStore = useProjectsStore();
|
||||
// Minimum number of recovery codes before the recovery code warning bar is shown.
|
||||
const recoveryCodeWarningThreshold = 4;
|
||||
|
||||
/**
|
||||
* Indicates if billing features are enabled.
|
||||
*/
|
||||
const billingEnabled = computed<boolean>(() => configStore.state.config.billingFeaturesEnabled);
|
||||
|
||||
const isMyProjectsPage = computed((): boolean => {
|
||||
return route.path === RouteConfig.AllProjectsDashboard.path;
|
||||
});
|
||||
@ -135,18 +140,20 @@ onMounted(async () => {
|
||||
notify.error(`Unable to set access grants wizard. ${error.message}`, AnalyticsErrorEventSource.ALL_PROJECT_DASHBOARD);
|
||||
}
|
||||
|
||||
try {
|
||||
const couponType = await billingStore.setupAccount();
|
||||
if (couponType === CouponType.NoCoupon) {
|
||||
notify.error(`The coupon code was invalid, and could not be applied to your account`, AnalyticsErrorEventSource.ALL_PROJECT_DASHBOARD);
|
||||
}
|
||||
if (billingEnabled.value) {
|
||||
try {
|
||||
const couponType = await billingStore.setupAccount();
|
||||
if (couponType === CouponType.NoCoupon) {
|
||||
notify.error(`The coupon code was invalid, and could not be applied to your account`, AnalyticsErrorEventSource.ALL_PROJECT_DASHBOARD);
|
||||
}
|
||||
|
||||
if (couponType === CouponType.SignupCoupon) {
|
||||
notify.success(`The coupon code was added successfully`);
|
||||
if (couponType === CouponType.SignupCoupon) {
|
||||
notify.success(`The coupon code was added successfully`);
|
||||
}
|
||||
} catch (error) {
|
||||
error.message = `Unable to setup account. ${error.message}`;
|
||||
notify.notifyError(error, AnalyticsErrorEventSource.ALL_PROJECT_DASHBOARD);
|
||||
}
|
||||
} catch (error) {
|
||||
error.message = `Unable to setup account. ${error.message}`;
|
||||
notify.notifyError(error, AnalyticsErrorEventSource.ALL_PROJECT_DASHBOARD);
|
||||
}
|
||||
|
||||
try {
|
||||
|
@ -10,7 +10,7 @@
|
||||
/>
|
||||
|
||||
<v-banner
|
||||
v-if="isAccountFrozen && parentRef"
|
||||
v-if="isAccountFrozen && parentRef && billingEnabled"
|
||||
class="all-dashboard-banners__freeze"
|
||||
title="Your account was frozen due to billing issues."
|
||||
message="Please update your payment information."
|
||||
@ -21,7 +21,7 @@
|
||||
/>
|
||||
|
||||
<v-banner
|
||||
v-if="isAccountWarned && parentRef"
|
||||
v-if="isAccountWarned && parentRef && billingEnabled"
|
||||
class="all-dashboard-banners__warning"
|
||||
title="Your account will be frozen soon due to billing issues."
|
||||
message="Please update your payment information."
|
||||
@ -52,6 +52,7 @@ import { MODALS } from '@/utils/constants/appStatePopUps';
|
||||
import { useAppStore } from '@/store/modules/appStore';
|
||||
import { RouteConfig } from '@/types/router';
|
||||
import { useBillingStore } from '@/store/modules/billingStore';
|
||||
import { useConfigStore } from '@/store/modules/configStore';
|
||||
|
||||
import VBanner from '@/components/common/VBanner.vue';
|
||||
import UpgradeNotification from '@/components/notifications/UpgradeNotification.vue';
|
||||
@ -61,11 +62,17 @@ const router = useRouter();
|
||||
const billingStore = useBillingStore();
|
||||
const usersStore = useUsersStore();
|
||||
const appStore = useAppStore();
|
||||
const configStore = useConfigStore();
|
||||
|
||||
const props = defineProps<{
|
||||
parentRef: HTMLElement;
|
||||
}>();
|
||||
|
||||
/**
|
||||
* Indicates if billing features are enabled.
|
||||
*/
|
||||
const billingEnabled = computed<boolean>(() => configStore.state.config.billingFeaturesEnabled);
|
||||
|
||||
/**
|
||||
* Indicates if account was frozen due to billing issues.
|
||||
*/
|
||||
@ -92,7 +99,8 @@ const isLowBalance = computed((): boolean => {
|
||||
/* whether the paid tier banner should be shown */
|
||||
const isPaidTierBannerShown = computed((): boolean => {
|
||||
return !usersStore.state.user.paidTier
|
||||
&& joinedWhileAgo.value;
|
||||
&& joinedWhileAgo.value
|
||||
&& billingEnabled.value;
|
||||
});
|
||||
|
||||
/* whether the user joined more than 7 days ago */
|
||||
@ -107,7 +115,7 @@ const joinedWhileAgo = computed((): boolean => {
|
||||
* Opens add payment method modal.
|
||||
*/
|
||||
function togglePMModal(): void {
|
||||
if (usersStore.state.user.paidTier) return;
|
||||
if (usersStore.state.user.paidTier || !billingEnabled.value) return;
|
||||
appStore.updateActiveModal(MODALS.upgradeAccount);
|
||||
}
|
||||
|
||||
|
@ -69,8 +69,10 @@
|
||||
<AccountIcon class="account-area__wrap__left__icon" />
|
||||
<p class="account-area__wrap__left__label">My Account</p>
|
||||
<p class="account-area__wrap__left__label-small">Account</p>
|
||||
<TierBadgePro v-if="user.paidTier" class="account-area__wrap__left__tier-badge" />
|
||||
<TierBadgeFree v-else class="account-area__wrap__left__tier-badge" />
|
||||
<template v-if="billingEnabled">
|
||||
<TierBadgePro v-if="user.paidTier" class="account-area__wrap__left__tier-badge" />
|
||||
<TierBadgeFree v-else class="account-area__wrap__left__tier-badge" />
|
||||
</template>
|
||||
</div>
|
||||
<ArrowIcon class="account-area__wrap__arrow" />
|
||||
</div>
|
||||
@ -92,7 +94,7 @@
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="account-area__dropdown__item" @click="navigateToBilling">
|
||||
<div v-if="billingEnabled" class="account-area__dropdown__item" @click="navigateToBilling">
|
||||
<BillingIcon />
|
||||
<p class="account-area__dropdown__item__label">Billing</p>
|
||||
</div>
|
||||
@ -177,6 +179,11 @@ const link = 'https://docs.storj.io/';
|
||||
const isAccountDropdownShown = ref(false);
|
||||
const isNavOpened = ref(false);
|
||||
|
||||
/**
|
||||
* Indicates if billing features are enabled.
|
||||
*/
|
||||
const billingEnabled = computed<boolean>(() => configStore.state.config.billingFeaturesEnabled);
|
||||
|
||||
/**
|
||||
* Returns satellite name from store.
|
||||
*/
|
||||
|
@ -32,7 +32,7 @@
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div tabindex="0" class="account-button__dropdown__item" @click.stop="navigateToBilling" @keyup.enter="navigateToBilling">
|
||||
<div v-if="billingEnabled" tabindex="0" class="account-button__dropdown__item" @click.stop="navigateToBilling" @keyup.enter="navigateToBilling">
|
||||
<BillingIcon />
|
||||
<p class="account-button__dropdown__item__label">Billing</p>
|
||||
</div>
|
||||
@ -102,6 +102,11 @@ const obStore = useObjectBrowserStore();
|
||||
|
||||
const isHoveredOver = ref(false);
|
||||
|
||||
/**
|
||||
* Indicates if billing features are enabled.
|
||||
*/
|
||||
const billingEnabled = computed<boolean>(() => configStore.state.config.billingFeaturesEnabled);
|
||||
|
||||
/**
|
||||
* Indicates if account dropdown is open.
|
||||
*/
|
||||
|
@ -26,7 +26,7 @@
|
||||
/>
|
||||
|
||||
<v-banner
|
||||
v-if="isAccountFrozen && !isLoading && dashboardContent"
|
||||
v-if="isAccountFrozen && !isLoading && dashboardContent && billingEnabled"
|
||||
title="Your account was frozen due to billing issues."
|
||||
message="Please update your payment information."
|
||||
link-text="To Billing Page"
|
||||
@ -36,7 +36,7 @@
|
||||
/>
|
||||
|
||||
<v-banner
|
||||
v-if="isAccountWarned && !isLoading && dashboardContent"
|
||||
v-if="isAccountWarned && !isLoading && dashboardContent && billingEnabled"
|
||||
title="Your account will be frozen soon due to billing issues."
|
||||
message="Please update your payment information."
|
||||
link-text="To Billing Page"
|
||||
@ -46,7 +46,7 @@
|
||||
/>
|
||||
|
||||
<limit-warning-banners
|
||||
v-if="dashboardContent"
|
||||
v-if="dashboardContent && billingEnabled"
|
||||
:reached-thresholds="reachedThresholds"
|
||||
:dashboard-ref="dashboardContent"
|
||||
:on-upgrade-click="togglePMModal"
|
||||
@ -72,7 +72,7 @@
|
||||
<p>Remaining session time: <b class="dashboard__debug-timer__bold">{{ session.debugTimerText.value }}</b></p>
|
||||
</div>
|
||||
<limit-warning-modal
|
||||
v-if="limitModalThreshold && !isLoading"
|
||||
v-if="limitModalThreshold && !isLoading && billingEnabled"
|
||||
:reached-thresholds="reachedThresholds"
|
||||
:threshold="limitModalThreshold"
|
||||
:on-close="() => limitModalThreshold = null"
|
||||
@ -146,6 +146,11 @@ const limitModalThreshold = ref<LimitThreshold | null>(null);
|
||||
|
||||
const dashboardContent = ref<HTMLElement | null>(null);
|
||||
|
||||
/**
|
||||
* Indicates if billing features are enabled.
|
||||
*/
|
||||
const billingEnabled = computed<boolean>(() => configStore.state.config.billingFeaturesEnabled);
|
||||
|
||||
/**
|
||||
* Indicates whether objects upload modal should be shown.
|
||||
*/
|
||||
@ -236,7 +241,8 @@ const isPaidTierBannerShown = computed((): boolean => {
|
||||
return !isPaidTier.value
|
||||
&& !isOnboardingTour.value
|
||||
&& joinedWhileAgo.value
|
||||
&& isDashboardPage.value;
|
||||
&& isDashboardPage.value
|
||||
&& billingEnabled.value;
|
||||
});
|
||||
|
||||
/* whether the user joined more than 7 days ago */
|
||||
@ -304,13 +310,6 @@ const isPaidTier = computed((): boolean => {
|
||||
return usersStore.state.user.paidTier;
|
||||
});
|
||||
|
||||
/**
|
||||
* Returns the URL for the general request page from the store.
|
||||
*/
|
||||
const requestURL = computed((): string => {
|
||||
return configStore.state.config.generalRequestURL;
|
||||
});
|
||||
|
||||
/**
|
||||
* Closes upload large files warning notification.
|
||||
*/
|
||||
@ -356,7 +355,7 @@ function toggleMFARecoveryModal(): void {
|
||||
* Opens add payment method modal.
|
||||
*/
|
||||
function togglePMModal(): void {
|
||||
if (isPaidTier.value) return;
|
||||
if (isPaidTier.value || !billingEnabled.value) return;
|
||||
appStore.updateActiveModal(MODALS.upgradeAccount);
|
||||
}
|
||||
|
||||
@ -404,18 +403,20 @@ onMounted(async () => {
|
||||
notify.error(`Unable to set access grants wizard. ${error.message}`, AnalyticsErrorEventSource.OVERALL_APP_WRAPPER_ERROR);
|
||||
}
|
||||
|
||||
try {
|
||||
const couponType = await billingStore.setupAccount();
|
||||
if (couponType === CouponType.NoCoupon) {
|
||||
notify.error(`The coupon code was invalid, and could not be applied to your account`, AnalyticsErrorEventSource.OVERALL_APP_WRAPPER_ERROR);
|
||||
}
|
||||
if (billingEnabled.value) {
|
||||
try {
|
||||
const couponType = await billingStore.setupAccount();
|
||||
if (couponType === CouponType.NoCoupon) {
|
||||
notify.error(`The coupon code was invalid, and could not be applied to your account`, AnalyticsErrorEventSource.OVERALL_APP_WRAPPER_ERROR);
|
||||
}
|
||||
|
||||
if (couponType === CouponType.SignupCoupon) {
|
||||
notify.success(`The coupon code was added successfully`);
|
||||
if (couponType === CouponType.SignupCoupon) {
|
||||
notify.success(`The coupon code was added successfully`);
|
||||
}
|
||||
} catch (error) {
|
||||
error.message = `Unable to setup account. ${error.message}`;
|
||||
notify.notifyError(error, AnalyticsErrorEventSource.OVERALL_APP_WRAPPER_ERROR);
|
||||
}
|
||||
} catch (error) {
|
||||
error.message = `Unable to setup account. ${error.message}`;
|
||||
notify.notifyError(error, AnalyticsErrorEventSource.OVERALL_APP_WRAPPER_ERROR);
|
||||
}
|
||||
|
||||
try {
|
||||
|
@ -32,8 +32,10 @@ if (process.env['STORJ_DEBUG_BUNDLE_SIZE']) {
|
||||
}
|
||||
|
||||
export default defineConfig(({ mode }) => {
|
||||
const isProd = mode === 'production';
|
||||
|
||||
// compress chunks only for production mode builds.
|
||||
if (mode === 'production') {
|
||||
if (isProd) {
|
||||
plugins.push(viteCompression({
|
||||
algorithm: 'brotliCompress',
|
||||
threshold: 1024,
|
||||
@ -57,6 +59,7 @@ export default defineConfig(({ mode }) => {
|
||||
build: {
|
||||
outDir: resolve(__dirname, 'dist'),
|
||||
emptyOutDir: true,
|
||||
reportCompressedSize: isProd,
|
||||
rollupOptions: {
|
||||
output: {
|
||||
experimentalMinChunkSize: 50*1024,
|
||||
|
Loading…
Reference in New Issue
Block a user