web/satellite/vuetify-poc: unmock total cost, token balance, coupon

This change replaces mock data for the total cost, STORJ token balance,
and coupon information in the Vuetify project's billing overview with
real data.

Resolves #6095

Change-Id: Iad1c5141065f8761d7d13140d42871018fa9aca4
This commit is contained in:
Jeremy Wharton 2023-08-17 01:17:04 -05:00 committed by Storj Robot
parent f0afe0d2ea
commit 2b278bb05f

View File

@ -37,9 +37,20 @@
<v-window-item>
<v-row>
<v-col cols="12" sm="4">
<v-card title="Total Cost" subtitle="Estimated for June 2023" variant="flat" :border="true" rounded="xlg">
<v-card
title="Total Cost"
:subtitle="`Estimated for ${new Date().toLocaleString('en-US', { month: 'long', year: 'numeric' })}`"
variant="flat"
:border="true"
rounded="xlg"
>
<v-card-text>
<v-chip rounded color="success" variant="outlined" class="font-weight-bold mb-2">$24</v-chip>
<div v-if="isLoading" class="pb-2 text-center">
<v-progress-circular class="ma-0" color="primary" size="30" indeterminate />
</div>
<v-chip v-else rounded color="success" variant="outlined" class="font-weight-bold mb-2">
{{ centsToDollars(priceSummary) }}
</v-chip>
<v-divider class="my-4" />
<v-btn variant="outlined" color="default" size="small" class="mr-2">View Billing History</v-btn>
<!-- <v-btn variant="tonal" color="default" size="small" class="mr-2">Payment Methods</v-btn> -->
@ -50,7 +61,12 @@
<v-col cols="12" sm="4">
<v-card title="STORJ Token Balance" subtitle="Your STORJ Token Wallet" variant="flat" :border="true" rounded="xlg">
<v-card-text>
<v-chip rounded color="success" variant="outlined" class="font-weight-bold mb-2">$5,284</v-chip>
<div v-if="isLoading" class="pb-2 text-center">
<v-progress-circular class="ma-0" color="primary" size="30" indeterminate />
</div>
<v-chip v-else rounded color="success" variant="outlined" class="font-weight-bold mb-2">
{{ formattedTokenBalance }}
</v-chip>
<v-divider class="my-4" />
<v-btn variant="outlined" color="default" size="small" class="mr-2">+ Add STORJ Tokens</v-btn>
<!-- <v-btn variant="tonal" color="default" size="small" class="mr-2">View Transactions</v-btn> -->
@ -59,13 +75,47 @@
</v-col>
<v-col cols="12" sm="4">
<v-card title="Coupon / Free Usage" subtitle="Active / No Expiration" variant="flat" :border="true" rounded="xlg">
<v-card
v-if="isLoading"
class="d-flex align-center justify-center"
height="200"
rounded="xlg"
border
>
<v-progress-circular color="primary" size="48" indeterminate />
</v-card>
<v-card
v-else-if="coupon"
:title="`Coupon / ${coupon.name}`"
:subtitle="`${isCouponActive ? 'Active' : 'Expired'} / ${couponExpiration}`"
rounded="xlg"
border
>
<v-card-text>
<v-chip rounded color="success" variant="outlined" class="font-weight-bold mb-2">$1.65 off</v-chip>
<v-chip
:color="isCouponActive ? 'success' : 'error'"
variant="outlined"
class="font-weight-bold mb-2"
rounded
>
{{ couponDiscount }}
</v-chip>
<v-divider class="my-4" />
<v-btn variant="outlined" color="default" size="small" class="mr-2">+ Add Coupon</v-btn>
</v-card-text>
</v-card>
<v-card
v-else
class="billing__new-coupon-card d-flex align-center justify-center"
color="primary"
variant="text"
height="200"
link
border
>
<v-icon icon="mdi-plus" class="mr-1" size="small" />
<span class="text-decoration-underline mr-1">Apply New Coupon</span>
</v-card>
</v-col>
</v-row>
@ -242,12 +292,18 @@ import {
VExpansionPanels,
VExpansionPanel,
VTextField,
VProgressCircular,
VIcon,
} from 'vuetify/components';
import { VDataTable } from 'vuetify/labs/components';
import { useLoading } from '@/composables/useLoading';
import { useNotify } from '@/utils/hooks';
import { useBillingStore } from '@/store/modules/billingStore';
import { CreditCard } from '@/types/payments';
import { 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 CreditCardComponent from '@poc/components/CreditCardComponent.vue';
import AddCreditCardComponent from '@poc/components/AddCreditCardComponent.vue';
@ -259,6 +315,7 @@ const selected = ref([]);
const billingStore = useBillingStore();
const { isLoading, withLoading } = useLoading();
const notify = useNotify();
const creditCards = computed((): CreditCard[] => {
return billingStore.state.creditCards;
@ -292,6 +349,63 @@ const invoices = [
},
];
/**
* Returns price summary of all project usages.
*/
const priceSummary = computed((): number => {
return billingStore.state.projectCharges.getPrice();
});
/**
* Returns STORJ token balance from store.
*/
const formattedTokenBalance = computed((): string => {
return billingStore.state.balance.formattedCoins;
});
/**
* Returns the coupon applied to the user's account.
*/
const coupon = computed((): Coupon | null => {
return billingStore.state.coupon;
});
/**
* Returns the expiration date of the coupon.
*/
const couponExpiration = computed((): string => {
const c = coupon.value;
if (!c) return '';
const exp = c.expiresAt;
if (!exp || c.duration === CouponDuration.Forever) {
return 'No Expiration';
}
return `Expires on ${exp.getDate()} ${SHORT_MONTHS_NAMES[exp.getMonth()]} ${exp.getFullYear()}`;
});
/**
* Returns the coupon's discount amount.
*/
const couponDiscount = computed((): string => {
const c = coupon.value;
if (!c) return '';
if (c.percentOff !== 0) {
return `${parseFloat(c.percentOff.toFixed(2)).toString()}% off`;
}
return `$${(c.amountOff / 100).toFixed(2).replace('.00', '')} off`;
});
/**
* Returns the whether the coupon is active.
*/
const isCouponActive = computed((): boolean => {
const now = Date.now();
const c = coupon.value;
return !!c && (c.duration === 'forever' || (!!c.expiresAt && now < c.expiresAt.getTime()));
});
function getColor(status: string): string {
if (status === 'Paid') return 'success';
if (status === 'Pending') return 'warning';
@ -300,7 +414,24 @@ function getColor(status: string): string {
onMounted(() => {
withLoading(async () => {
await billingStore.getCreditCards();
try {
await Promise.all([
billingStore.getProjectUsageAndChargesCurrentRollup(),
billingStore.getBalance(),
billingStore.getCoupon(),
billingStore.getCreditCards(),
]);
} catch (error) {
notify.notifyError(error, AnalyticsErrorEventSource.BILLING_AREA);
}
});
});
</script>
</script>
<style scoped lang="scss">
.billing__new-coupon-card {
border-width: 2px;
border-style: dashed;
box-shadow: none !important;
}
</style>