web/satellite/vuetify-poc: add low token balance banner
Added low token balance banner to vuetify app with the same logic as in main app. Issue: https://github.com/storj/storj/issues/6460 Change-Id: Ifa9af8e2179ec3a6601b5053575990b86cc8f0b5
This commit is contained in:
parent
cd8e9bd044
commit
fe890ff535
@ -0,0 +1,35 @@
|
||||
// Copyright (C) 2023 Storj Labs, Inc.
|
||||
// See LICENSE for copying information.
|
||||
|
||||
<template>
|
||||
<v-alert
|
||||
closable
|
||||
variant="tonal"
|
||||
type="warning"
|
||||
rounded="lg"
|
||||
class="mt-2 mb-4"
|
||||
border
|
||||
>
|
||||
<template #default>
|
||||
<v-row class="ma-0 flex-nowrap justify-space-between align-center">
|
||||
<p>
|
||||
Your STORJ Token balance is low. Deposit more STORJ tokens or make sure you have a credit card
|
||||
on file to avoid interruptions in service.
|
||||
</p>
|
||||
<p class="ml-2 text-cursor-pointer text-no-wrap text-decoration-underline" @click="() => emits('click')">{{ ctaLabel }}</p>
|
||||
</v-row>
|
||||
</template>
|
||||
</v-alert>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { VAlert, VRow } from 'vuetify/components';
|
||||
|
||||
const props = defineProps<{
|
||||
ctaLabel: string
|
||||
}>();
|
||||
|
||||
const emits = defineEmits<{
|
||||
click: [],
|
||||
}>();
|
||||
</script>
|
@ -3,6 +3,12 @@
|
||||
|
||||
<template>
|
||||
<v-container>
|
||||
<low-token-balance-banner
|
||||
v-if="isLowBalance"
|
||||
:cta-label="tab !== 1 ? 'Deposit' : ''"
|
||||
@click="tab = 1"
|
||||
/>
|
||||
|
||||
<v-row>
|
||||
<v-col>
|
||||
<PageTitleComponent title="Account Billing" />
|
||||
@ -228,13 +234,15 @@ import {
|
||||
import { useLoading } from '@/composables/useLoading';
|
||||
import { useNotify } from '@/utils/hooks';
|
||||
import { useBillingStore } from '@/store/modules/billingStore';
|
||||
import { Coupon, CouponDuration, CreditCard } from '@/types/payments';
|
||||
import { AccountBalance, Coupon, CouponDuration, CreditCard } from '@/types/payments';
|
||||
import { centsToDollars } from '@/utils/strings';
|
||||
import { AnalyticsErrorEventSource } from '@/utils/constants/analyticsEventNames';
|
||||
import { SHORT_MONTHS_NAMES } from '@/utils/constants/date';
|
||||
import { useProjectsStore } from '@/store/modules/projectsStore';
|
||||
import { useConfigStore } from '@/store/modules/configStore';
|
||||
import { Download } from '@/utils/download';
|
||||
import { useLowTokenBalance } from '@/composables/useLowTokenBalance';
|
||||
import { Project } from '@/types/projects';
|
||||
|
||||
import PageTitleComponent from '@poc/components/PageTitleComponent.vue';
|
||||
import CreditCardComponent from '@poc/components/CreditCardComponent.vue';
|
||||
@ -244,6 +252,7 @@ import UsageAndChargesComponent from '@poc/components/billing/UsageAndChargesCom
|
||||
import StorjTokenCardComponent from '@poc/components/StorjTokenCardComponent.vue';
|
||||
import TokenTransactionsTableComponent from '@poc/components/TokenTransactionsTableComponent.vue';
|
||||
import ApplyCouponCodeDialog from '@poc/components/dialogs/ApplyCouponCodeDialog.vue';
|
||||
import LowTokenBalanceBanner from '@poc/components/LowTokenBalanceBanner.vue';
|
||||
|
||||
const tab = ref(0);
|
||||
const billingStore = useBillingStore();
|
||||
@ -252,6 +261,7 @@ const configStore = useConfigStore();
|
||||
|
||||
const { isLoading, withLoading } = useLoading();
|
||||
const notify = useNotify();
|
||||
const isLowBalance = useLowTokenBalance();
|
||||
|
||||
const isRollupLoading = ref(true);
|
||||
const isAddCouponDialogShown = ref<boolean>(false);
|
||||
@ -341,14 +351,20 @@ function goToTransactionsTab() {
|
||||
|
||||
onMounted(async () => {
|
||||
withLoading(async () => {
|
||||
const promises: Promise<void | Project[] | AccountBalance | CreditCard[]>[] = [
|
||||
billingStore.getBalance(),
|
||||
billingStore.getCoupon(),
|
||||
billingStore.getCreditCards(),
|
||||
projectsStore.getProjects(),
|
||||
billingStore.getProjectUsagePriceModel(),
|
||||
];
|
||||
|
||||
if (configStore.state.config.nativeTokenPaymentsEnabled) {
|
||||
promises.push(billingStore.getNativePaymentsHistory());
|
||||
}
|
||||
|
||||
try {
|
||||
await Promise.all([
|
||||
billingStore.getBalance(),
|
||||
billingStore.getCoupon(),
|
||||
billingStore.getCreditCards(),
|
||||
projectsStore.getProjects(),
|
||||
billingStore.getProjectUsagePriceModel(),
|
||||
]);
|
||||
await Promise.all(promises);
|
||||
} catch (error) {
|
||||
notify.notifyError(error, AnalyticsErrorEventSource.BILLING_AREA);
|
||||
}
|
||||
|
@ -3,6 +3,11 @@
|
||||
|
||||
<template>
|
||||
<v-container>
|
||||
<low-token-balance-banner
|
||||
v-if="isLowBalance && billingEnabled"
|
||||
cta-label="Go to billing"
|
||||
@click="redirectToBilling"
|
||||
/>
|
||||
<limit-warning-banners v-if="billingEnabled" />
|
||||
<v-row v-if="promptForPassphrase && !bucketWasCreated" class="my-0">
|
||||
<v-col cols="12">
|
||||
@ -192,7 +197,18 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, onBeforeUnmount, onMounted, ref } from 'vue';
|
||||
import { VBtn, VCard, VCardTitle, VCardText, VCol, VContainer, VRow, VBadge, VIcon, VTooltip } from 'vuetify/components';
|
||||
import {
|
||||
VBtn,
|
||||
VCard,
|
||||
VCardTitle,
|
||||
VCardText,
|
||||
VCol,
|
||||
VContainer,
|
||||
VRow,
|
||||
VBadge,
|
||||
VIcon,
|
||||
VTooltip,
|
||||
} from 'vuetify/components';
|
||||
import { ComponentPublicInstance } from '@vue/runtime-core';
|
||||
import { useRouter } from 'vue-router';
|
||||
|
||||
@ -212,6 +228,9 @@ import { LocalData } from '@/utils/localData';
|
||||
import { ProjectMembersPage } from '@/types/projectMembers';
|
||||
import { AccessGrantsPage } from '@/types/accessGrants';
|
||||
import { useConfigStore } from '@/store/modules/configStore';
|
||||
import { useLowTokenBalance } from '@/composables/useLowTokenBalance';
|
||||
import { RouteName } from '@poc/router';
|
||||
import { AccountBalance, CreditCard } from '@/types/payments';
|
||||
|
||||
import PageTitleComponent from '@poc/components/PageTitleComponent.vue';
|
||||
import PageSubtitleComponent from '@poc/components/PageSubtitleComponent.vue';
|
||||
@ -226,6 +245,7 @@ import ManagePassphraseDialog from '@poc/components/dialogs/ManagePassphraseDial
|
||||
import IconCloud from '@poc/components/icons/IconCloud.vue';
|
||||
import IconArrowDown from '@poc/components/icons/IconArrowDown.vue';
|
||||
import LimitWarningBanners from '@poc/components/LimitWarningBanners.vue';
|
||||
import LowTokenBalanceBanner from '@poc/components/LowTokenBalanceBanner.vue';
|
||||
|
||||
const appStore = useAppStore();
|
||||
const usersStore = useUsersStore();
|
||||
@ -238,6 +258,7 @@ const configStore = useConfigStore();
|
||||
|
||||
const notify = useNotify();
|
||||
const router = useRouter();
|
||||
const isLowBalance = useLowTokenBalance();
|
||||
|
||||
const bucketWasCreated = !!LocalData.getBucketWasCreatedStatus();
|
||||
|
||||
@ -494,7 +515,14 @@ function onCouponCTAClicked(): void {
|
||||
return;
|
||||
}
|
||||
|
||||
router.push('/account/billing');
|
||||
redirectToBilling();
|
||||
}
|
||||
|
||||
/**
|
||||
* Redirects to Billing Page tab.
|
||||
*/
|
||||
function redirectToBilling(): void {
|
||||
router.push({ name: RouteName.Billing });
|
||||
}
|
||||
|
||||
/**
|
||||
@ -512,7 +540,7 @@ onMounted(async (): Promise<void> => {
|
||||
const past = new Date();
|
||||
past.setDate(past.getDate() - 30);
|
||||
|
||||
let promises: Promise<void | ProjectMembersPage | AccessGrantsPage>[] = [
|
||||
let promises: Promise<void | ProjectMembersPage | AccessGrantsPage | AccountBalance | CreditCard[]>[] = [
|
||||
projectsStore.getDailyProjectData({ since: past, before: now }),
|
||||
projectsStore.getProjectLimits(projectID),
|
||||
pmStore.getProjectMembers(FIRST_PAGE, projectID),
|
||||
@ -524,10 +552,16 @@ onMounted(async (): Promise<void> => {
|
||||
promises = [
|
||||
...promises,
|
||||
billingStore.getProjectUsageAndChargesCurrentRollup(),
|
||||
billingStore.getBalance(),
|
||||
billingStore.getCreditCards(),
|
||||
billingStore.getCoupon(),
|
||||
];
|
||||
}
|
||||
|
||||
if (configStore.state.config.nativeTokenPaymentsEnabled) {
|
||||
promises.push(billingStore.getNativePaymentsHistory());
|
||||
}
|
||||
|
||||
try {
|
||||
await Promise.all(promises);
|
||||
} catch (error) {
|
||||
|
@ -3,6 +3,11 @@
|
||||
|
||||
<template>
|
||||
<v-container>
|
||||
<low-token-balance-banner
|
||||
v-if="isLowBalance && billingEnabled"
|
||||
cta-label="Go to billing"
|
||||
@click="redirectToBilling"
|
||||
/>
|
||||
<PageTitleComponent title="My Projects" />
|
||||
<!-- <PageSubtitleComponent subtitle="Projects are where you and your team can upload and manage data, view usage statistics and billing."/> -->
|
||||
|
||||
@ -105,12 +110,17 @@ import {
|
||||
VBtnToggle,
|
||||
VProgressCircular,
|
||||
} from 'vuetify/components';
|
||||
import { useRouter } from 'vue-router';
|
||||
|
||||
import { ProjectItemModel } from '@poc/types/projects';
|
||||
import { useProjectsStore } from '@/store/modules/projectsStore';
|
||||
import { useUsersStore } from '@/store/modules/usersStore';
|
||||
import { ProjectRole } from '@/types/projectMembers';
|
||||
import { useAppStore } from '@/store/modules/appStore';
|
||||
import { useLowTokenBalance } from '@/composables/useLowTokenBalance';
|
||||
import { useConfigStore } from '@/store/modules/configStore';
|
||||
import { useBillingStore } from '@/store/modules/billingStore';
|
||||
import { RouteName } from '@poc/router';
|
||||
|
||||
import ProjectCard from '@poc/components/ProjectCard.vue';
|
||||
import PageTitleComponent from '@poc/components/PageTitleComponent.vue';
|
||||
@ -120,19 +130,29 @@ import CreateProjectDialog from '@poc/components/dialogs/CreateProjectDialog.vue
|
||||
import AddTeamMemberDialog from '@poc/components/dialogs/AddTeamMemberDialog.vue';
|
||||
import IconCardView from '@poc/components/icons/IconCardView.vue';
|
||||
import IconTableView from '@poc/components/icons/IconTableView.vue';
|
||||
import LowTokenBalanceBanner from '@poc/components/LowTokenBalanceBanner.vue';
|
||||
|
||||
const appStore = useAppStore();
|
||||
const projectsStore = useProjectsStore();
|
||||
const usersStore = useUsersStore();
|
||||
const configStore = useConfigStore();
|
||||
const billingStore = useBillingStore();
|
||||
|
||||
const router = useRouter();
|
||||
const isLowBalance = useLowTokenBalance();
|
||||
|
||||
const isLoading = ref<boolean>(true);
|
||||
|
||||
const joiningItem = ref<ProjectItemModel | null>(null);
|
||||
const isJoinProjectDialogShown = ref<boolean>(false);
|
||||
const isCreateProjectDialogShown = ref<boolean>(false);
|
||||
const addMemberProjectId = ref<string>('');
|
||||
const isAddMemberDialogShown = ref<boolean>(false);
|
||||
|
||||
/**
|
||||
* Indicates if billing features are enabled.
|
||||
*/
|
||||
const billingEnabled = computed<boolean>(() => configStore.state.config.billingFeaturesEnabled);
|
||||
|
||||
/**
|
||||
* Returns whether to use the table view.
|
||||
*/
|
||||
@ -176,6 +196,13 @@ const items = computed((): ProjectItemModel[] => {
|
||||
return projects;
|
||||
});
|
||||
|
||||
/**
|
||||
* Redirects to Billing Page tab.
|
||||
*/
|
||||
function redirectToBilling(): void {
|
||||
router.push({ name: RouteName.Billing });
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays the Join Project modal.
|
||||
*/
|
||||
@ -198,5 +225,13 @@ onMounted(async (): Promise<void> => {
|
||||
await projectsStore.getUserInvitations().catch(_ => {});
|
||||
|
||||
isLoading.value = false;
|
||||
|
||||
if (configStore.state.config.nativeTokenPaymentsEnabled && configStore.state.config.billingFeaturesEnabled) {
|
||||
Promise.all([
|
||||
billingStore.getBalance(),
|
||||
billingStore.getCreditCards(),
|
||||
billingStore.getNativePaymentsHistory(),
|
||||
]).catch(_ => {});
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
Loading…
Reference in New Issue
Block a user