add Bitcoin wallet status tab in CMS.
This commit is contained in:
@@ -0,0 +1,93 @@
|
|||||||
|
<template>
|
||||||
|
<div v-loading="loading" class="detail-loading-host" element-loading-text="Loading wallet…">
|
||||||
|
<el-empty v-if="!loading && loadError" description="Failed to load wallet status" />
|
||||||
|
|
||||||
|
<template v-if="!loading && !loadError && walletStatus">
|
||||||
|
<div v-if="walletStatus.syncStatus !== WalletSyncStatus.Synced" class="mb-16">
|
||||||
|
<el-alert type="warning" :closable="false" show-icon title="Wallet is syncing. Please wait." />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<el-card shadow="never">
|
||||||
|
<template #header>
|
||||||
|
<div class="flex items-center justify-between gap-16">
|
||||||
|
<span>Status</span>
|
||||||
|
<el-button type="default" :loading="refreshing" @click="refreshStatus">Refresh</el-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<el-descriptions :column="1" border>
|
||||||
|
<el-descriptions-item label="Network">{{ walletStatus.network }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="RPC version">{{ walletStatus.rpcVersion }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="Block height">
|
||||||
|
{{ walletStatus.blockHeight ?? 'Unavailable' }}
|
||||||
|
</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="Server height">
|
||||||
|
{{ walletStatus.serverHeight ?? 'Unavailable' }}
|
||||||
|
</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="Sync">
|
||||||
|
<el-tag :type="resolveWalletSyncStatusTagType(walletStatus.syncStatus)" size="small">
|
||||||
|
{{ resolveWalletSyncStatusLabel(walletStatus.syncStatus) }}
|
||||||
|
</el-tag>
|
||||||
|
</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="Total balance">{{ walletStatus.balanceBtc }} BTC</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="Confirmed balance">
|
||||||
|
{{ walletStatus.confirmedBalanceBtc }} BTC
|
||||||
|
</el-descriptions-item>
|
||||||
|
</el-descriptions>
|
||||||
|
</el-card>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ElMessage } from 'element-plus';
|
||||||
|
import { onBeforeMount, ref } from 'vue';
|
||||||
|
import { storeToRefs } from 'pinia';
|
||||||
|
import { WalletSyncStatus } from '@/types/wallet/WalletSyncStatus';
|
||||||
|
import { useBitcoinWalletStore } from '@/stores/bitcoinWallet';
|
||||||
|
import { resolveAxiosErrorMessage } from '@/utils/resolveAxiosErrorMessage';
|
||||||
|
import { resolveWalletSyncStatusLabel } from '@/utils/wallet/resolveWalletSyncStatusLabel';
|
||||||
|
import { resolveWalletSyncStatusTagType } from '@/utils/wallet/resolveWalletSyncStatusTagType';
|
||||||
|
|
||||||
|
const bitcoinWalletStore = useBitcoinWalletStore();
|
||||||
|
|
||||||
|
const { status: walletStatus } = storeToRefs(bitcoinWalletStore);
|
||||||
|
|
||||||
|
const { fetchStatus } = bitcoinWalletStore;
|
||||||
|
|
||||||
|
const loading = ref(true);
|
||||||
|
const loadError = ref(false);
|
||||||
|
const refreshing = ref(false);
|
||||||
|
|
||||||
|
onBeforeMount(async () => {
|
||||||
|
loading.value = true;
|
||||||
|
|
||||||
|
await loadWalletStatus();
|
||||||
|
|
||||||
|
loading.value = false;
|
||||||
|
});
|
||||||
|
|
||||||
|
const loadWalletStatus = async (): Promise<void> => {
|
||||||
|
loadError.value = false;
|
||||||
|
|
||||||
|
try {
|
||||||
|
await fetchStatus();
|
||||||
|
} catch (error) {
|
||||||
|
loadError.value = true;
|
||||||
|
|
||||||
|
ElMessage.error(resolveAxiosErrorMessage(error, 'Failed to load wallet status'));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const refreshStatus = async (): Promise<void> => {
|
||||||
|
refreshing.value = true;
|
||||||
|
|
||||||
|
try {
|
||||||
|
await loadWalletStatus();
|
||||||
|
|
||||||
|
ElMessage.success('Wallet status refreshed');
|
||||||
|
} finally {
|
||||||
|
refreshing.value = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
import { defineStore } from 'pinia';
|
||||||
|
import { ref } from 'vue';
|
||||||
|
import { api } from '@/plugins/axios';
|
||||||
|
import type { BitcoinWalletStatus } from '@/types/bitcoinWallet/BitcoinWalletStatus';
|
||||||
|
|
||||||
|
export const useBitcoinWalletStore = defineStore('bitcoinWallet', () => {
|
||||||
|
const status = ref<BitcoinWalletStatus | null>(null);
|
||||||
|
|
||||||
|
const fetchStatus = async (): Promise<BitcoinWalletStatus> => {
|
||||||
|
const { data } = await api.get<BitcoinWalletStatus>('/bitcoin-wallet');
|
||||||
|
|
||||||
|
status.value = data;
|
||||||
|
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
status,
|
||||||
|
fetchStatus
|
||||||
|
};
|
||||||
|
});
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
export type BitcoinNetwork = 'mainnet' | 'testnet4';
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
import type { BitcoinNetwork } from './BitcoinNetwork';
|
||||||
|
import type { WalletSyncStatus } from '../wallet/WalletSyncStatus';
|
||||||
|
|
||||||
|
export interface BitcoinWalletStatus {
|
||||||
|
network: BitcoinNetwork;
|
||||||
|
rpcVersion: string;
|
||||||
|
blockHeight: number | null;
|
||||||
|
serverHeight: number | null;
|
||||||
|
syncStatus: WalletSyncStatus;
|
||||||
|
balanceBtc: string;
|
||||||
|
confirmedBalanceBtc: string;
|
||||||
|
}
|
||||||
@@ -2,6 +2,31 @@
|
|||||||
<div>
|
<div>
|
||||||
<h3 class="m-0 mb-16">Wallet</h3>
|
<h3 class="m-0 mb-16">Wallet</h3>
|
||||||
|
|
||||||
<monero-wallet />
|
<el-tabs :model-value="activeTab" class="mb-24" @tab-change="onTabChange">
|
||||||
|
<el-tab-pane label="Monero (XMR)" name="monero" />
|
||||||
|
<el-tab-pane label="Bitcoin (BTC)" name="bitcoin" />
|
||||||
|
</el-tabs>
|
||||||
|
|
||||||
|
<router-view />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ROUTE_NAMES } from '@/consts/routeNames';
|
||||||
|
import { computed } from 'vue';
|
||||||
|
import { useRoute, useRouter } from 'vue-router';
|
||||||
|
|
||||||
|
const route = useRoute();
|
||||||
|
const router = useRouter();
|
||||||
|
|
||||||
|
const activeTab = computed(() => (route.name === ROUTE_NAMES.BitcoinWallet ? 'bitcoin' : 'monero'));
|
||||||
|
|
||||||
|
const onTabChange = (tabName: string | number) => {
|
||||||
|
if (tabName === 'bitcoin') {
|
||||||
|
router.push({ name: ROUTE_NAMES.BitcoinWallet });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
router.push({ name: ROUTE_NAMES.MoneroWallet });
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|||||||
Reference in New Issue
Block a user