web/satellite: Billing history and Coupons components migrated to use composition api

Change-Id: I589af5376af5d94a15069c1d6ff4fbe2ce1c6fb0
This commit is contained in:
NickolaiYurchenko 2023-01-19 17:20:18 +02:00 committed by Storj Robot
parent 984da95543
commit 5a4f089750
4 changed files with 117 additions and 149 deletions

View File

@ -22,49 +22,38 @@
</div>
</template>
<script lang="ts">
import { Component, Vue } from 'vue-property-decorator';
<script setup lang="ts">
import { computed, onMounted } from 'vue';
import { PaymentsHistoryItem, PaymentsHistoryItemType } from '@/types/payments';
import { PAYMENTS_ACTIONS } from '@/store/modules/payments';
import { AnalyticsErrorEventSource } from '@/utils/constants/analyticsEventNames';
import { useNotify, useStore } from '@/utils/hooks';
import BillingHistoryHeader from '@/components/account/billing/billingTabs/BillingHistoryHeader.vue';
import BillingHistoryItem from '@/components/account/billing/billingTabs/BillingHistoryItem.vue';
import VTable from '@/components/common/VTable.vue';
const {
GET_PAYMENTS_HISTORY,
} = PAYMENTS_ACTIONS;
const store = useStore();
const notify = useNotify();
// @vue/component
@Component({
components: {
BillingHistoryItem,
VTable,
BillingHistoryHeader,
},
})
export default class BillingHistory extends Vue {
mounted(): void {
this.fetchHistory();
}
public async fetchHistory(): Promise<void> {
try {
await this.$store.dispatch(GET_PAYMENTS_HISTORY);
} catch (error) {
await this.$notify.error(error.message, AnalyticsErrorEventSource.BILLING_HISTORY_TAB);
}
}
public get historyItems(): PaymentsHistoryItem[] {
return this.$store.state.paymentsModule.paymentsHistory.filter((item: PaymentsHistoryItem) => {
return item.status !== 'draft' && item.status !== '' && (item.type === PaymentsHistoryItemType.Invoice || item.type === PaymentsHistoryItemType.Charge);
});
async function fetchHistory(): Promise<void> {
try {
await store.dispatch(PAYMENTS_ACTIONS.GET_PAYMENTS_HISTORY);
} catch (error) {
await notify.error(error.message, AnalyticsErrorEventSource.BILLING_HISTORY_TAB);
}
}
const historyItems = computed((): PaymentsHistoryItem[] => {
return store.state.paymentsModule.paymentsHistory.filter((item: PaymentsHistoryItem) => {
return item.status !== 'draft' && item.status !== '' && (item.type === PaymentsHistoryItemType.Invoice || item.type === PaymentsHistoryItemType.Charge);
});
});
onMounted(() => {
fetchHistory();
});
</script>
<style scoped lang="scss">

View File

@ -2,23 +2,14 @@
// See LICENSE for copying information.
<template>
<fragment>
<v-fragment>
<th class="align-left">DATE</th>
<th class="align-left">STATUS</th>
<th class="align-left">AMOUNT</th>
<th class="align-left">DOWNLOAD</th>
</fragment>
</v-fragment>
</template>
<script lang="ts">
import { Component, Vue } from 'vue-property-decorator';
import { Fragment } from 'vue-fragment';
// @vue/component
@Component({
components: {
Fragment,
},
})
export default class BillingHistoryHeader extends Vue {}
<script setup lang="ts">
import { Fragment as VFragment } from 'vue-fragment';
</script>

View File

@ -18,7 +18,7 @@
</p>
</div>
</th>
<fragment>
<v-fragment>
<th class="align-left data tablet-laptop">
<p class="date">
<span><Calendar /></span>
@ -39,43 +39,36 @@
<th class="align-left data tablet-laptop">
<a :href="item.link" download>Invoice PDF</a>
</th>
</fragment>
</v-fragment>
</tr>
</template>
<script lang="ts">
import { Component, Prop } from 'vue-property-decorator';
import { Fragment } from 'vue-fragment';
<script setup lang="ts">
import { Fragment as VFragment } from 'vue-fragment';
import { PaymentsHistoryItem } from '@/types/payments';
import { AnalyticsHttpApi } from '@/api/analytics';
import { AnalyticsEvent } from '@/utils/constants/analyticsEventNames';
import Resizable from '@/components/common/Resizable.vue';
import { useResize } from '@/composables/resize';
import CheckIcon from '@/../static/images/billing/check-green-circle.svg';
import Calendar from '@/../static/images/billing/calendar.svg';
// @vue/component
@Component({
components: {
Calendar,
CheckIcon,
Fragment,
},
})
export default class BillingHistoryItem extends Resizable {
@Prop({ default: new PaymentsHistoryItem('', '', 0, 0, '', '', new Date(), new Date(), 0, 0) })
private readonly item: PaymentsHistoryItem;
const analytics: AnalyticsHttpApi = new AnalyticsHttpApi();
private readonly analytics: AnalyticsHttpApi = new AnalyticsHttpApi();
const props = withDefaults(defineProps<{
item: PaymentsHistoryItem;
}>(), {
item: () => new PaymentsHistoryItem('', '', 0, 0, '', '', new Date(), new Date(), 0, 0),
});
public downloadInvoice() {
this.analytics.eventTriggered(AnalyticsEvent.INVOICE_DOWNLOADED);
const { isMobile, isTablet } = useResize();
if (this.isMobile || this.isTablet)
window.open(this.item.link, '_blank', 'noreferrer');
}
function downloadInvoice() {
analytics.eventTriggered(AnalyticsEvent.INVOICE_DOWNLOADED);
if (isMobile || isTablet)
window.open(props.item.link, '_blank', 'noreferrer');
}
</script>

View File

@ -46,107 +46,102 @@
</div>
</template>
<script lang="ts">
import { Component, Vue } from 'vue-property-decorator';
<script setup lang="ts">
import { computed, onMounted, ref } from 'vue';
import { PAYMENTS_ACTIONS } from '@/store/modules/payments';
import { Coupon } from '@/types/payments';
import { AnalyticsHttpApi } from '@/api/analytics';
import { AnalyticsErrorEventSource, AnalyticsEvent } from '@/utils/constants/analyticsEventNames';
import { APP_STATE_MUTATIONS } from '@/store/mutationConstants';
import { useNotify, useStore } from '@/utils/hooks';
import VLoader from '@/components/common/VLoader.vue';
// @vue/component
@Component({
components: {
VLoader,
},
})
export default class Coupons extends Vue {
public isCouponFetching = true;
const analytics: AnalyticsHttpApi = new AnalyticsHttpApi();
private readonly analytics: AnalyticsHttpApi = new AnalyticsHttpApi();
const store = useStore();
const notify = useNotify();
/**
* Lifecycle hook after initial render.
* Fetches coupon.
*/
public async mounted(): Promise<void> {
try {
await this.$store.dispatch(PAYMENTS_ACTIONS.GET_COUPON);
this.isCouponFetching = false;
} catch (error) {
await this.$notify.error(error.message, AnalyticsErrorEventSource.BILLING_COUPONS_TAB);
this.isCouponFetching = false;
}
const isCouponFetching = ref<boolean>(true);
/**
* Returns the coupon applied to the user's account.
*/
const coupon = computed((): Coupon | null => {
return store.state.paymentsModule.coupon;
});
/**
* Returns the expiration date of the coupon.
*/
const expiration = computed((): string => {
if (!coupon.value) {
return '';
}
/**
* Opens Add Coupon modal.
*/
public toggleCreateModal(): void {
this.analytics.eventTriggered(AnalyticsEvent.APPLY_NEW_COUPON_CLICKED);
this.$store.commit(APP_STATE_MUTATIONS.TOGGLE_NEW_BILLING_ADD_COUPON_MODAL_SHOWN);
if (coupon.value?.expiresAt) {
return 'Expires ' + coupon.value?.expiresAt.toLocaleDateString('en-US', { month: 'long', day: 'numeric', year: 'numeric' });
} else {
return 'Unknown expiration';
}
});
/**
* Returns the whether the coupon is active or not.
*/
const status = computed((): string => {
if (!coupon.value) {
return '';
}
/**
* Returns the coupon applied to the user's account.
*/
public get coupon(): Coupon | null {
return this.$store.state.paymentsModule.coupon;
const today = new Date();
if ((coupon.value.duration === 'forever' || coupon.value.duration === 'once') || (coupon.value.expiresAt && today.getTime() < coupon.value.expiresAt.getTime())) {
return 'active';
} else {
return 'inactive';
}
});
/**
* Returns the whether the coupon is active or not.
*/
const expirationHelper = computed((): string => {
if (!coupon.value) {
return '';
}
/**
* Returns the expiration date of the coupon.
*/
public get expiration(): string {
if (!this.coupon) {
return '';
}
if (this.coupon.expiresAt) {
return 'Expires ' + this.coupon.expiresAt.toLocaleDateString('en-US', { month: 'long', day: 'numeric', year: 'numeric' });
} else {
return 'Unknown expiration';
}
}
/**
* Returns the whether the coupon is active or not.
*/
public get status(): string {
if (!this.coupon) {
return '';
}
const today = new Date();
if ((this.coupon.duration === 'forever' || this.coupon.duration === 'once') || (this.coupon.expiresAt && today.getTime() < this.coupon.expiresAt.getTime())) {
return 'active';
} else {
return 'inactive';
}
}
/**
* Returns the whether the coupon is active or not.
*/
public get expirationHelper(): string {
if (!this.coupon) {
return '';
}
switch (this.coupon.duration) {
case 'once':
return 'Expires after first use';
case 'forever':
return 'No expiration';
default:
return this.expiration;
}
switch (coupon.value.duration) {
case 'once':
return 'Expires after first use';
case 'forever':
return 'No expiration';
default:
return expiration.value;
}
});
/**
* Opens Add Coupon modal.
*/
function toggleCreateModal(): void {
analytics.eventTriggered(AnalyticsEvent.APPLY_NEW_COUPON_CLICKED);
store.commit(APP_STATE_MUTATIONS.TOGGLE_NEW_BILLING_ADD_COUPON_MODAL_SHOWN);
}
/**
* Lifecycle hook after initial render.
* Fetches coupon.
*/
onMounted(async () => {
try {
await store.dispatch(PAYMENTS_ACTIONS.GET_COUPON);
} catch (error) {
await notify.error(error.message, AnalyticsErrorEventSource.BILLING_COUPONS_TAB);
}
isCouponFetching.value = false;
});
</script>
<style scoped lang="scss">