jcloud/dashboard/src2/views/billing/AccountBillingCards.vue

201 lines
5.2 KiB
Vue

<template>
<Card title="Payment methods" :subtitle="subtitle">
<template #actions>
<Button @click="showAddCardDialog = true"> Add Card </Button>
<Dialog :options="{ title: 'Add new card' }" v-model="showAddCardDialog">
<template v-slot:body-content>
<StripeCard
class="mb-1"
v-if="showAddCardDialog"
@complete="
showAddCardDialog = false;
$resources.paymentMethods.reload();
"
/>
</template>
</Dialog>
</template>
<div class="space-y-3">
<div
class="flex items-center justify-between rounded-lg border p-5"
v-for="card in $resources.paymentMethods.data"
:key="card.name"
>
<div class="flex">
<component
class="mr-6 w-12 h-12"
:is="cardBrand[card.brand]"
v-if="card.brand"
/>
<component class="mr-6 w-12 h-12" :is="cardBrand['generic']" v-else />
<div class="my-auto">
<div class="text-lg font-medium text-gray-900">
{{ card.name_on_card }} <span class="text-gray-500"></span>
{{ card.last_4 }}
<Badge v-if="card.is_default" label="Default" />
</div>
<div class="mt-1 text-sm text-gray-600">
<span>
Valid till {{ card.expiry_month }}/{{ card.expiry_year }}
</span>
·
<span>Added on {{ $date(card.creation).toLocaleString() }}</span>
</div>
</div>
</div>
<Dropdown :options="dropdownItems(card)" right>
<template v-slot="{ open }">
<Button icon="more-horizontal" />
</template>
</Dropdown>
</div>
</div>
</Card>
<FinalizeInvoicesDialog v-model="showFinalizeDialog" />
<Dialog
:options="{
title: 'Remove Payment Method',
actions: [
{
label: 'Remove',
variant: 'solid',
theme: 'red',
onClick: () => {
$resources.remove.submit({ name: cardToRemove.name }).then(() => {
$resources.paymentMethods.reload();
this.showRemoveCardDialog = false;
});
}
},
{
label: 'Cancel',
onClick: () => (this.showRemoveCardDialog = false)
}
]
}"
v-model="showRemoveCardDialog"
>
<template v-slot:body-content>
<span>Are you sure you want to remove this payment method?</span>
<br /><br />
<span v-if="$resources.paymentMethods.data.length === 1">
If you intend to close your account please check the docs for
<Link
target="_blank"
href="https://jingrow.com/docs/billing/disable-account"
>cancelling subscription.</Link
>
今果 Jingrow is not responsible for any refund if the account is not
closed properly.
</span>
</template>
</Dialog>
</template>
<script>
import { defineAsyncComponent } from 'vue';
import Link from '@/components/Link.vue';
import FinalizeInvoicesDialog from './FinalizeInvoicesDialog.vue';
export default {
name: 'AccountBillingCards',
data() {
return {
showAddCardDialog: false,
showRemoveCardDialog: false,
showFinalizeDialog: false,
cardToRemove: null
};
},
resources: {
paymentMethods: {
url: 'jcloud.api.billing.get_payment_methods',
auto: true
},
setAsDefault: {
url: 'jcloud.api.billing.set_as_default'
},
remove() {
return {
url: 'jcloud.api.billing.remove_payment_method',
onSuccess: data => {
if (data === 'Unpaid Invoices') {
this.showFinalizeDialog = true;
}
}
};
}
},
components: {
StripeCard: defineAsyncComponent(() =>
import('@/components/StripeCard.vue')
),
FinalizeInvoicesDialog
},
computed: {
subtitle() {
if (
this.$resources.paymentMethods.loading ||
this.$resources.paymentMethods.data?.length > 0
) {
return 'Cards you have added for automatic billing';
}
return "You haven't added any cards yet";
},
cardBrand() {
return {
mastercard: defineAsyncComponent(() =>
import('@/components/icons/cards/MasterCard.vue')
),
visa: defineAsyncComponent(() =>
import('@/components/icons/cards/Visa.vue')
),
amex: defineAsyncComponent(() =>
import('@/components/icons/cards/Amex.vue')
),
jcb: defineAsyncComponent(() =>
import('@/components/icons/cards/JCB.vue')
),
generic: defineAsyncComponent(() =>
import('@/components/icons/cards/Generic.vue')
),
'union-pay': defineAsyncComponent(() =>
import('@/components/icons/cards/UnionPay.vue')
)
};
}
},
methods: {
dropdownItems(card) {
return [
!card.is_default && {
label: 'Set as default',
onClick: () => this.confirmSetAsDefault(card)
},
{
label: 'Remove',
onClick: () => {
this.cardToRemove = card;
this.showRemoveCardDialog = true;
}
}
];
},
confirmSetAsDefault(card) {
this.$confirm({
title: 'Set as default',
message: 'Set this card as the default payment method?',
actionLabel: 'Set as default',
resource: this.$resources.setAsDefault,
action: closeDialog => {
this.$resources.setAsDefault.submit({ name: card.name }).then(() => {
this.$resources.paymentMethods.reload();
closeDialog();
});
}
});
}
}
};
</script>