feat: enhance billing components with top-up functionality and payment history table

This commit is contained in:
2026-03-24 21:54:54 +07:00
parent 5350f421f9
commit 1f8fdad2da
3 changed files with 175 additions and 140 deletions

View File

@@ -1,31 +1,23 @@
<script setup lang="ts">
import { client as rpcClient } from '@/api/rpcclient';
import AppButton from '@/components/ui/AppButton.vue';
import { useAppToast } from '@/composables/useAppToast';
import { useUsageQuery } from '@/composables/useUsageQuery';
import { getApiErrorMessage } from '@/lib/utils';
import BillingTopupDialog from '@/routes/settings/Billing/components/BillingTopupDialog.vue';
import BillingUsageSection from '@/routes/settings/Billing/components/BillingUsageSection.vue';
import SettingsSectionCard from '@/routes/settings/components/SettingsSectionCard.vue';
import type { Plan as ModelPlan } from '@/server/gen/proto/app/v1/common';
import { useAuthStore } from '@/stores/auth';
import { useTranslation } from 'i18next-vue';
import { computed, ref } from 'vue';
import SettingsRow from '../components/SettingsRow.vue';
import PaymentHistory from './components/PaymentHistory';
import PlanSelection from './components/PlanSelection';
import UpgradePlan from './components/UpgradePlan';
const toast = useAppToast();
const auth = useAuthStore();
const { t } = useTranslation();
const { refetch: refetchUsage } = useUsageQuery();
const topupDialogVisible = ref(false);
const topupAmount = ref<number | null>(null);
const topupLoading = ref(false);
const topupPresets = [10, 20, 50, 100];
const upgradeDialogVisible = ref(false);
const selectedPlan = ref<ModelPlan | null>(null);
@@ -63,41 +55,11 @@ const handleUpgradeSuccess = async () => {
await refreshBillingState();
};
const handleTopup = async (amount: number) => {
topupLoading.value = true;
try {
await rpcClient.topupWallet({ amount });
await refreshBillingState();
toast.add({
severity: 'success',
summary: t('settings.billing.toast.topupSuccessSummary'),
detail: t('settings.billing.toast.topupSuccessDetail', { amount: auth.formatMoney(amount) }),
life: 3000,
});
topupDialogVisible.value = false;
topupAmount.value = null;
} catch (error) {
console.error(error);
toast.add({
severity: 'error',
summary: t('settings.billing.toast.topupFailedSummary'),
detail: getApiErrorMessage(error, t('settings.billing.toast.topupFailedDetail')),
life: 5000,
});
} finally {
topupLoading.value = false;
}
};
const openTopupDialog = () => {
topupAmount.value = null;
topupDialogVisible.value = true;
};
const selectPreset = (amount: number) => {
topupAmount.value = amount;
};
</script>
<template>
@@ -131,16 +93,7 @@ const selectPreset = (amount: number) => {
<PaymentHistory />
</SettingsSectionCard>
<BillingTopupDialog
:visible="topupDialogVisible"
:presets="topupPresets"
:amount="topupAmount"
:loading="topupLoading"
@update:visible="topupDialogVisible = $event"
@update:amount="topupAmount = $event"
@selectPreset="selectPreset"
@submit="handleTopup(topupAmount || 0)"
/>
<BillingTopupDialog v-model="topupDialogVisible" />
<UpgradePlan
:visible="upgradeDialogVisible"