web/satellite: CreditCardContainer and billing Overview migrated to use composition api

Change-Id: I8e0a027671aa996f42edf916c9b0434e773de618
This commit is contained in:
NickolaiYurchenko 2023-01-23 12:36:37 +02:00 committed by Storj Robot
parent b86ce0d527
commit bf5b378836
2 changed files with 116 additions and 146 deletions

View File

@ -15,12 +15,12 @@
<div class="payment-methods-container__card-container__info-area__info-container">
<img src="@/../static/images/payments/cardStars.png" alt="Hidden card digits stars image" class="payment-methods-container__card-container__info-area__info-container__image">
{{ creditCard.last4 }}
{{ props.creditCard.last4 }}
</div>
<div class="payment-methods-container__card-container__info-area__expire-container">
{{ creditCard.expMonth }}/{{ creditCard.expYear }}
{{ props.creditCard.expMonth }}/{{ props.creditCard.expYear }}
</div>
<div v-if="creditCard.isDefault" class="payment-methods-container__card-container__default-area">
<div v-if="props.creditCard.isDefault" class="payment-methods-container__card-container__default-area">
<div class="payment-methods-container__card-container__default-text">Default</div>
</div>
<div class="payment-methods-container__card-container__function-buttons">
@ -31,14 +31,12 @@
</div>
</template>
<script lang="ts">
import Vue, { VueConstructor } from 'vue';
import { Component, Prop } from 'vue-property-decorator';
<script setup lang="ts">
import { computed, ref } from 'vue';
import { PAYMENTS_ACTIONS } from '@/store/modules/payments';
import { CreditCard } from '@/types/payments';
import CardDialog from '@/components/account/billing/paymentMethods/CardDialog.vue';
import { useStore } from '@/utils/hooks';
import AmericanExpressIcon from '@/../static/images/payments/cardIcons/americanexpress.svg';
import DefaultIcon from '@/../static/images/payments/cardIcons/default.svg';
@ -49,63 +47,43 @@ import MastercardIcon from '@/../static/images/payments/cardIcons/smallmastercar
import UnionPayIcon from '@/../static/images/payments/cardIcons/smallunionpay.svg';
import VisaIcon from '@/../static/images/payments/cardIcons/visa.svg';
const {
TOGGLE_CARD_SELECTION,
} = PAYMENTS_ACTIONS;
const icons = {
'jcb': JCBIcon,
'diners': DinersIcon,
'mastercard': MastercardIcon,
'amex': AmericanExpressIcon,
'discover': DiscoverIcon,
'unionpay': UnionPayIcon,
'visa': VisaIcon,
};
// @vue/component
@Component({
components: {
CardDialog,
JCBIcon,
DinersIcon,
MastercardIcon,
AmericanExpressIcon,
DiscoverIcon,
UnionPayIcon,
VisaIcon,
DefaultIcon,
},
})
export default class CardComponent extends Vue {
@Prop({ default: () => new CreditCard() })
private readonly creditCard: CreditCard;
public isEditPaymentMethodsModalOpen = false;
const props = withDefaults(defineProps<{
creditCard?: CreditCard;
}>(), {
creditCard: () => new CreditCard(),
});
public edit(): void {
this.$emit('edit', this.creditCard);
}
const store = useStore();
public remove(): void {
this.$emit('remove', this.creditCard);
}
public get cardIcon(): VueConstructor<Vue> {
switch (this.creditCard.brand) {
case 'jcb':
return JCBIcon;
case 'diners':
return DinersIcon;
case 'mastercard':
return MastercardIcon;
case 'amex':
return AmericanExpressIcon;
case 'discover':
return DiscoverIcon;
case 'unionpay':
return UnionPayIcon;
case 'visa':
return VisaIcon;
default:
return DefaultIcon;
}
}
const emit = defineEmits(['edit', 'remove']);
/**
* Toggle card selection dialog.
*/
public toggleSelection(): void {
this.$store.dispatch(TOGGLE_CARD_SELECTION, this.creditCard.id);
}
const cardIcon = computed(() => {
return icons[props.creditCard.brand] || DefaultIcon;
});
function edit(): void {
emit('edit', props.creditCard);
}
function remove(): void {
emit('remove', props.creditCard);
}
/**
* Toggle card selection dialog.
*/
function toggleSelection(): void {
store.dispatch(PAYMENTS_ACTIONS.TOGGLE_CARD_SELECTION, props.creditCard.id);
}
</script>

View File

@ -16,6 +16,7 @@
Total Estimated Charges
<img
src="@/../static/images/common/smallGreyWhiteInfo.png"
alt="info icon"
@mouseenter="showChargesTooltip = true"
@mouseleave="showChargesTooltip = false"
>
@ -83,8 +84,8 @@
</div>
</template>
<script lang="ts">
import { Component, Vue } from 'vue-property-decorator';
<script setup lang="ts">
import { computed, onMounted, ref } from 'vue';
import { RouteConfig } from '@/router';
import { SHORT_MONTHS_NAMES } from '@/utils/constants/date';
@ -93,6 +94,7 @@ import { PAYMENTS_ACTIONS } from '@/store/modules/payments';
import { PROJECTS_ACTIONS } from '@/store/modules/projects';
import { AnalyticsHttpApi } from '@/api/analytics';
import { AnalyticsErrorEventSource, AnalyticsEvent } from '@/utils/constants/analyticsEventNames';
import { useNotify, useRouter, useStore } from '@/utils/hooks';
import UsageAndChargesItem2 from '@/components/account/billing/estimatedCostsAndCredits/UsageAndChargesItem2.vue';
import VButton from '@/components/common/VButton.vue';
@ -101,97 +103,87 @@ import EstimatedChargesIcon from '@/../static/images/account/billing/totalEstima
import AvailableBalanceIcon from '@/../static/images/account/billing/availableBalanceIcon.svg';
import CalendarIcon from '@/../static/images/account/billing/calendar-icon.svg';
// @vue/component
@Component({
components: {
EstimatedChargesIcon,
AvailableBalanceIcon,
UsageAndChargesItem2,
CalendarIcon,
VButton,
},
})
export default class BillingArea extends Vue {
public showChargesTooltip = false;
public isDataFetching = true;
public currentDate = '';
const analytics: AnalyticsHttpApi = new AnalyticsHttpApi();
private readonly analytics: AnalyticsHttpApi = new AnalyticsHttpApi();
const store = useStore();
const notify = useNotify();
const router = useRouter();
/**
* Lifecycle hook after initial render.
* Fetches projects and usage rollup.
*/
public async mounted(): Promise<void> {
try {
await this.$store.dispatch(PROJECTS_ACTIONS.FETCH);
} catch (error) {
await this.$notify.error(error.message, AnalyticsErrorEventSource.BILLING_OVERVIEW_TAB);
this.isDataFetching = false;
return;
}
const showChargesTooltip = ref<boolean>(false);
const isDataFetching = ref<boolean>(true);
const currentDate = ref<string>('');
try {
await this.$store.dispatch(PAYMENTS_ACTIONS.GET_PROJECT_USAGE_AND_CHARGES_CURRENT_ROLLUP);
await this.$store.dispatch(PAYMENTS_ACTIONS.GET_PROJECT_USAGE_PRICE_MODEL);
/**
* Returns account balance from store.
*/
const balance = computed((): AccountBalance => {
return store.state.paymentsModule.balance;
});
this.isDataFetching = false;
} catch (error) {
await this.$notify.error(error.message, AnalyticsErrorEventSource.BILLING_OVERVIEW_TAB);
this.isDataFetching = false;
}
/**
* Returns whether the user's STORJ balance is empty.
*/
const hasZeroCoins = computed((): boolean => {
return balance.value.coins === 0;
});
const rawDate = new Date();
let currentYear = rawDate.getFullYear();
this.currentDate = `${SHORT_MONTHS_NAMES[rawDate.getMonth()]} ${currentYear}`;
}
/**
* projectUsageAndCharges is an array of all stored ProjectUsageAndCharges.
*/
const projectUsageAndCharges = computed((): ProjectUsageAndCharges[] => {
return store.state.paymentsModule.usageAndCharges;
});
/**
* Returns account balance from store.
*/
public get balance(): AccountBalance {
return this.$store.state.paymentsModule.balance;
}
/**
* Returns whether the user's STORJ balance is empty.
*/
public get hasZeroCoins(): boolean {
return this.balance.coins === 0;
}
/**
* projectUsageAndCharges is an array of all stored ProjectUsageAndCharges.
*/
public get projectUsageAndCharges(): ProjectUsageAndCharges[] {
return this.$store.state.paymentsModule.usageAndCharges;
}
/**
* priceSummary returns price summary of usages for all the projects.
*/
public get priceSummary(): number {
return this.$store.state.paymentsModule.priceSummary;
}
public routeToBillingHistory(): void {
this.analytics.eventTriggered(AnalyticsEvent.SEE_PAYMENTS_CLICKED);
this.$router.push(RouteConfig.Account.with(RouteConfig.Billing).with(RouteConfig.BillingHistory2).path);
}
public routeToPaymentMethods(): void {
this.analytics.eventTriggered(AnalyticsEvent.EDIT_PAYMENT_METHOD_CLICKED);
this.$router.push(RouteConfig.Account.with(RouteConfig.Billing).with(RouteConfig.BillingPaymentMethods).path);
}
public balanceClicked(): void {
this.$router.push({
name: RouteConfig.Account.with(RouteConfig.Billing).with(RouteConfig.BillingPaymentMethods).name,
params: { action: this.hasZeroCoins ? 'add tokens' : 'token history' },
});
}
/**
* priceSummary returns price summary of usages for all the projects.
*/
const priceSummary = computed((): number => {
return store.state.paymentsModule.priceSummary;
});
function routeToBillingHistory(): void {
analytics.eventTriggered(AnalyticsEvent.SEE_PAYMENTS_CLICKED);
router.push(RouteConfig.Account.with(RouteConfig.Billing).with(RouteConfig.BillingHistory2).path);
}
function routeToPaymentMethods(): void {
analytics.eventTriggered(AnalyticsEvent.EDIT_PAYMENT_METHOD_CLICKED);
router.push(RouteConfig.Account.with(RouteConfig.Billing).with(RouteConfig.BillingPaymentMethods).path);
}
function balanceClicked(): void {
router.push({
name: RouteConfig.Account.with(RouteConfig.Billing).with(RouteConfig.BillingPaymentMethods).name,
params: { action: hasZeroCoins.value ? 'add tokens' : 'token history' },
});
}
/**
* Lifecycle hook after initial render.
* Fetches projects and usage rollup.
*/
onMounted(async () => {
try {
await store.dispatch(PROJECTS_ACTIONS.FETCH);
} catch (error) {
await notify.error(error.message, AnalyticsErrorEventSource.BILLING_OVERVIEW_TAB);
isDataFetching.value = false;
return;
}
try {
await store.dispatch(PAYMENTS_ACTIONS.GET_PROJECT_USAGE_AND_CHARGES_CURRENT_ROLLUP);
await store.dispatch(PAYMENTS_ACTIONS.GET_PROJECT_USAGE_PRICE_MODEL);
} catch (error) {
await notify.error(error.message, AnalyticsErrorEventSource.BILLING_OVERVIEW_TAB);
}
isDataFetching.value = false;
const rawDate = new Date();
let currentYear = rawDate.getFullYear();
currentDate.value = `${SHORT_MONTHS_NAMES[rawDate.getMonth()]} ${currentYear}`;
});
</script>
<style scoped lang="scss">