-
Notifications
You must be signed in to change notification settings - Fork 386
/
StorjTokenCardComponent.vue
182 lines (161 loc) · 6.03 KB
/
StorjTokenCardComponent.vue
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
// Copyright (C) 2023 Storj Labs, Inc.
// See LICENSE for copying information.
<template>
<v-card title="STORJ Token" variant="flat" border rounded="xlg">
<v-card-text>
<v-row class="ma-0 align-center">
<v-chip rounded color="default" variant="tonal" class="font-weight-bold mr-2">STORJ</v-chip>
<v-chip rounded color="info" variant="tonal" class="font-weight-bold">
Default
<span class="d-inline-flex ml-1">
<v-icon class="text-cursor-pointer" :icon="mdiInformationOutline" />
<v-tooltip
class="text-center"
activator="parent"
location="top"
max-width="300px"
open-delay="150"
close-delay="150"
>
If the STORJ token balance runs out, the default credit card will be charged.
<a class="link" href="https://docs.storj.io/support/account-management-billing/payment-methods" target="_blank" rel="noopener noreferrer">
Learn more
</a>
</v-tooltip>
</span>
</v-chip>
</v-row>
<v-divider class="my-4" />
<p>Deposit Address</p>
<v-chip rounded color="default" variant="text" class="font-weight-bold mt-2 px-0" @click="copyAddress">
{{ shortAddress || '-------' }}
<v-tooltip
v-if="wallet.address"
activator="parent"
location="top"
>
{{ wallet.address }}
</v-tooltip>
</v-chip>
<v-divider class="my-4" />
<p>Total Balance</p>
<v-chip rounded color="green" variant="outlined" class="font-weight-bold mt-2">{{ balance || '------' }}</v-chip>
<v-divider class="my-4" />
<v-btn v-if="wallet.address" variant="flat" color="success" size="small" :loading="isLoading" class="mr-2" @click="onAddTokens">+ Add STORJ Tokens</v-btn>
<v-btn v-else variant="flat" color="success" size="small" :loading="isLoading" @click="claimWalletClick">Create New Wallet</v-btn>
<v-btn v-if="wallet.address" variant="outlined" color="default" size="small" :loading="isLoading" @click="emit('historyClicked')">View Transactions</v-btn>
</v-card-text>
</v-card>
<AddTokensDialog v-model="isAddTokenDialogOpen" />
</template>
<script setup lang="ts">
import { VBtn, VCard, VCardText, VChip, VDivider, VTooltip, VRow, VIcon } from 'vuetify/components';
import { computed, onMounted, ref } from 'vue';
import { mdiInformationOutline } from '@mdi/js';
import { Wallet } from '@/types/payments';
import { useLoading } from '@/composables/useLoading';
import { useBillingStore } from '@/store/modules/billingStore';
import { AnalyticsErrorEventSource, AnalyticsEvent } from '@/utils/constants/analyticsEventNames';
import { useNotify } from '@/utils/hooks';
import { useAppStore } from '@poc/store/appStore';
import { useAnalyticsStore } from '@/store/modules/analyticsStore';
import AddTokensDialog from '@poc/components/dialogs/AddTokensDialog.vue';
const analyticsStore = useAnalyticsStore();
const appStore = useAppStore();
const billingStore = useBillingStore();
const notify = useNotify();
const { isLoading, withLoading } = useLoading();
const isAddTokenDialogOpen = ref<boolean>(false);
const emit = defineEmits(['historyClicked']);
/**
* Returns shortened wallet address.
*/
const shortAddress = computed((): string => {
if (!wallet.value.address) {
return '';
}
const addr = wallet.value.address;
return `${addr.substring(0, 6)} . . . ${addr.substring(addr.length - 4, addr.length)}`;
});
/**
* Returns a formatted wallet balance from store.
*/
const balance = computed((): string => {
if (!wallet.value.address) {
return '';
}
return '$' + wallet.value.balance.value.toLocaleString();
});
/**
* Returns wallet from store.
*/
const wallet = computed((): Wallet => {
return billingStore.state.wallet as Wallet;
});
/**
* Copies the wallet address.
*/
function copyAddress(): void {
if (!wallet.value.address) {
return;
}
navigator.clipboard.writeText(wallet.value.address);
}
/**
* getWallet tries to get an existing wallet for this user. this will not claim a wallet.
*/
function getWallet(): void {
if (wallet.value.address) {
return;
}
withLoading(async () => {
await billingStore.getWallet().catch(_ => {});
});
}
/**
* claimWallet claims a wallet for the current account.
*/
async function claimWallet(): Promise<void> {
if (wallet.value.address) {
return;
}
await billingStore.claimWallet();
}
/**
* Called when "Create New Wallet" button is clicked.
*/
function claimWalletClick(): void {
withLoading(async () => {
try {
await claimWallet();
notify.success('Wallet created successfully.');
} catch (error) {
notify.notifyError(error, AnalyticsErrorEventSource.BILLING_STORJ_TOKEN_CONTAINER);
}
});
}
/**
* Open the add tokens step of the upgrade modal
* Conditionally claim a wallet before that.
*/
function onAddTokens(): void {
analyticsStore.eventTriggered(AnalyticsEvent.ADD_FUNDS_CLICKED);
withLoading(async () => {
if (!wallet.value.address) {
// not possible from this component
// but this function is exported and used Billing.vue
try {
await billingStore.claimWallet();
} catch (error) {
notify.notifyError(error, AnalyticsErrorEventSource.BILLING_STORJ_TOKEN_CONTAINER);
return;
}
}
isAddTokenDialogOpen.value = true;
});
}
defineExpose({ onAddTokens });
onMounted(() => {
getWallet();
});
</script>