mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-04-28 02:02:08 +00:00
[API Node] Fix credits fetch condition (#3575)
This commit is contained in:
@@ -86,6 +86,7 @@ import { computed, defineAsyncComponent, watch } from 'vue'
|
|||||||
import SearchBox from '@/components/common/SearchBox.vue'
|
import SearchBox from '@/components/common/SearchBox.vue'
|
||||||
import { useSettingSearch } from '@/composables/setting/useSettingSearch'
|
import { useSettingSearch } from '@/composables/setting/useSettingSearch'
|
||||||
import { useSettingUI } from '@/composables/setting/useSettingUI'
|
import { useSettingUI } from '@/composables/setting/useSettingUI'
|
||||||
|
import { useFirebaseAuthStore } from '@/stores/firebaseAuthStore'
|
||||||
import { SettingTreeNode } from '@/stores/settingStore'
|
import { SettingTreeNode } from '@/stores/settingStore'
|
||||||
import { ISettingGroup, SettingParams } from '@/types/settingTypes'
|
import { ISettingGroup, SettingParams } from '@/types/settingTypes'
|
||||||
import { flattenTree } from '@/utils/treeUtil'
|
import { flattenTree } from '@/utils/treeUtil'
|
||||||
@@ -135,6 +136,8 @@ const {
|
|||||||
getSearchResults
|
getSearchResults
|
||||||
} = useSettingSearch()
|
} = useSettingSearch()
|
||||||
|
|
||||||
|
const authStore = useFirebaseAuthStore()
|
||||||
|
|
||||||
// Sort groups for a category
|
// Sort groups for a category
|
||||||
const sortedGroups = (category: SettingTreeNode): ISettingGroup[] => {
|
const sortedGroups = (category: SettingTreeNode): ISettingGroup[] => {
|
||||||
return [...(category.children ?? [])]
|
return [...(category.children ?? [])]
|
||||||
@@ -165,6 +168,9 @@ watch(activeCategory, (_, oldValue) => {
|
|||||||
if (!tabValue.value) {
|
if (!tabValue.value) {
|
||||||
activeCategory.value = oldValue
|
activeCategory.value = oldValue
|
||||||
}
|
}
|
||||||
|
if (activeCategory.value?.key === 'credits') {
|
||||||
|
void authStore.fetchBalance()
|
||||||
|
}
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,14 @@
|
|||||||
{{ $t('credits.yourCreditBalance') }}
|
{{ $t('credits.yourCreditBalance') }}
|
||||||
</h3>
|
</h3>
|
||||||
<div class="flex justify-between items-center">
|
<div class="flex justify-between items-center">
|
||||||
<div class="flex items-center gap-1">
|
<div v-if="balanceLoading" class="flex items-center gap-1">
|
||||||
|
<div class="flex items-center gap-2">
|
||||||
|
<Skeleton shape="circle" width="1.5rem" height="1.5rem" />
|
||||||
|
</div>
|
||||||
|
<div class="flex-1"></div>
|
||||||
|
<Skeleton width="8rem" height="2rem" />
|
||||||
|
</div>
|
||||||
|
<div v-else class="flex items-center gap-1">
|
||||||
<Tag
|
<Tag
|
||||||
severity="secondary"
|
severity="secondary"
|
||||||
icon="pi pi-dollar"
|
icon="pi pi-dollar"
|
||||||
@@ -21,11 +28,7 @@
|
|||||||
/>
|
/>
|
||||||
<div class="text-3xl font-bold">{{ formattedBalance }}</div>
|
<div class="text-3xl font-bold">{{ formattedBalance }}</div>
|
||||||
</div>
|
</div>
|
||||||
<ProgressSpinner
|
<Skeleton v-if="loading" width="2rem" height="2rem" />
|
||||||
v-if="loading"
|
|
||||||
class="w-12 h-12"
|
|
||||||
style="--pc-spinner-color: #000"
|
|
||||||
/>
|
|
||||||
<Button
|
<Button
|
||||||
v-else
|
v-else
|
||||||
:label="$t('credits.purchaseCredits')"
|
:label="$t('credits.purchaseCredits')"
|
||||||
@@ -34,7 +37,13 @@
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex flex-row items-center">
|
<div class="flex flex-row items-center">
|
||||||
<div v-if="formattedLastUpdateTime" class="text-xs text-muted">
|
<Skeleton
|
||||||
|
v-if="balanceLoading"
|
||||||
|
width="12rem"
|
||||||
|
height="1rem"
|
||||||
|
class="text-xs"
|
||||||
|
/>
|
||||||
|
<div v-else-if="formattedLastUpdateTime" class="text-xs text-muted">
|
||||||
{{ $t('credits.lastUpdated') }}: {{ formattedLastUpdateTime }}
|
{{ $t('credits.lastUpdated') }}: {{ formattedLastUpdateTime }}
|
||||||
</div>
|
</div>
|
||||||
<Button
|
<Button
|
||||||
@@ -112,10 +121,10 @@ import Button from 'primevue/button'
|
|||||||
import Column from 'primevue/column'
|
import Column from 'primevue/column'
|
||||||
import DataTable from 'primevue/datatable'
|
import DataTable from 'primevue/datatable'
|
||||||
import Divider from 'primevue/divider'
|
import Divider from 'primevue/divider'
|
||||||
import ProgressSpinner from 'primevue/progressspinner'
|
import Skeleton from 'primevue/skeleton'
|
||||||
import TabPanel from 'primevue/tabpanel'
|
import TabPanel from 'primevue/tabpanel'
|
||||||
import Tag from 'primevue/tag'
|
import Tag from 'primevue/tag'
|
||||||
import { computed, onMounted, ref } from 'vue'
|
import { computed, ref } from 'vue'
|
||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
|
|
||||||
import { useDialogService } from '@/services/dialogService'
|
import { useDialogService } from '@/services/dialogService'
|
||||||
@@ -133,7 +142,7 @@ const { t } = useI18n()
|
|||||||
const dialogService = useDialogService()
|
const dialogService = useDialogService()
|
||||||
const authStore = useFirebaseAuthStore()
|
const authStore = useFirebaseAuthStore()
|
||||||
const loading = computed(() => authStore.loading)
|
const loading = computed(() => authStore.loading)
|
||||||
|
const balanceLoading = computed(() => authStore.isFetchingBalance)
|
||||||
const formattedBalance = computed(() => {
|
const formattedBalance = computed(() => {
|
||||||
if (!authStore.balance) return '0.00'
|
if (!authStore.balance) return '0.00'
|
||||||
return formatMetronomeCurrency(authStore.balance.amount_micros, 'usd')
|
return formatMetronomeCurrency(authStore.balance.amount_micros, 'usd')
|
||||||
@@ -174,10 +183,5 @@ const handleFaqClick = () => {
|
|||||||
window.open('https://drip-art.notion.site/api-nodes-faqs', '_blank')
|
window.open('https://drip-art.notion.site/api-nodes-faqs', '_blank')
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fetch initial balance when panel is mounted
|
|
||||||
onMounted(() => {
|
|
||||||
void authStore.fetchBalance()
|
|
||||||
})
|
|
||||||
|
|
||||||
const creditHistory = ref<CreditHistoryItemData[]>([])
|
const creditHistory = ref<CreditHistoryItemData[]>([])
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ export const useFirebaseAuthStore = defineStore('firebaseAuth', () => {
|
|||||||
const currentUser = ref<User | null>(null)
|
const currentUser = ref<User | null>(null)
|
||||||
const isInitialized = ref(false)
|
const isInitialized = ref(false)
|
||||||
const customerCreated = ref(false)
|
const customerCreated = ref(false)
|
||||||
|
const isFetchingBalance = ref(false)
|
||||||
|
|
||||||
// Balance state
|
// Balance state
|
||||||
const balance = ref<GetCustomerBalanceResponse | null>(null)
|
const balance = ref<GetCustomerBalanceResponse | null>(null)
|
||||||
@@ -95,33 +96,42 @@ export const useFirebaseAuthStore = defineStore('firebaseAuth', () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const fetchBalance = async (): Promise<GetCustomerBalanceResponse | null> => {
|
const fetchBalance = async (): Promise<GetCustomerBalanceResponse | null> => {
|
||||||
const token = await getIdToken()
|
isFetchingBalance.value = true
|
||||||
if (!token) {
|
try {
|
||||||
error.value = 'Cannot fetch balance: User not authenticated'
|
const token = await getIdToken()
|
||||||
return null
|
if (!token) {
|
||||||
}
|
error.value = 'Cannot fetch balance: User not authenticated'
|
||||||
|
isFetchingBalance.value = false
|
||||||
const response = await fetch(`${API_BASE_URL}/customers/balance`, {
|
|
||||||
headers: {
|
|
||||||
Authorization: `Bearer ${token}`
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
if (!response.ok) {
|
|
||||||
if (response.status === 404) {
|
|
||||||
// Customer not found is expected for new users
|
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
const errorData = await response.json()
|
|
||||||
error.value = `Failed to fetch balance: ${errorData.message}`
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
const balanceData = await response.json()
|
const response = await fetch(`${API_BASE_URL}/customers/balance`, {
|
||||||
// Update the last balance update time
|
headers: {
|
||||||
lastBalanceUpdateTime.value = new Date()
|
Authorization: `Bearer ${token}`
|
||||||
balance.value = balanceData
|
}
|
||||||
return balanceData
|
})
|
||||||
|
|
||||||
|
if (!response.ok) {
|
||||||
|
if (response.status === 404) {
|
||||||
|
// Customer not found is expected for new users
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
const errorData = await response.json()
|
||||||
|
error.value = `Failed to fetch balance: ${errorData.message}`
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
const balanceData = await response.json()
|
||||||
|
// Update the last balance update time
|
||||||
|
lastBalanceUpdateTime.value = new Date()
|
||||||
|
balance.value = balanceData
|
||||||
|
return balanceData
|
||||||
|
} catch (e) {
|
||||||
|
error.value = `Failed to fetch balance: ${e}`
|
||||||
|
return null
|
||||||
|
} finally {
|
||||||
|
isFetchingBalance.value = false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const createCustomer = async (
|
const createCustomer = async (
|
||||||
@@ -303,6 +313,7 @@ export const useFirebaseAuthStore = defineStore('firebaseAuth', () => {
|
|||||||
isInitialized,
|
isInitialized,
|
||||||
balance,
|
balance,
|
||||||
lastBalanceUpdateTime,
|
lastBalanceUpdateTime,
|
||||||
|
isFetchingBalance,
|
||||||
|
|
||||||
// Getters
|
// Getters
|
||||||
isAuthenticated,
|
isAuthenticated,
|
||||||
|
|||||||
Reference in New Issue
Block a user