mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-01-26 19:09:52 +00:00
[API Nodes] Add credit management panel UI (#3535)
Co-authored-by: github-actions <github-actions@github.com>
This commit is contained in:
@@ -4,7 +4,7 @@
|
||||
const { defineConfig } = require('@lobehub/i18n-cli');
|
||||
|
||||
module.exports = defineConfig({
|
||||
modelName: 'o4-mini',
|
||||
modelName: 'gpt-4.1',
|
||||
splitToken: 1024,
|
||||
entry: 'src/locales/en',
|
||||
entryLocale: 'en',
|
||||
|
||||
@@ -48,6 +48,7 @@
|
||||
</PanelTemplate>
|
||||
|
||||
<AboutPanel />
|
||||
<CreditsPanel />
|
||||
<Suspense>
|
||||
<KeybindingPanel />
|
||||
<template #fallback>
|
||||
@@ -90,6 +91,7 @@ import { flattenTree } from '@/utils/treeUtil'
|
||||
|
||||
import AboutPanel from './setting/AboutPanel.vue'
|
||||
import ColorPaletteMessage from './setting/ColorPaletteMessage.vue'
|
||||
import CreditsPanel from './setting/CreditsPanel.vue'
|
||||
import CurrentUserMessage from './setting/CurrentUserMessage.vue'
|
||||
import FirstTimeUIMessage from './setting/FirstTimeUIMessage.vue'
|
||||
import PanelTemplate from './setting/PanelTemplate.vue'
|
||||
|
||||
130
src/components/dialog/content/setting/CreditsPanel.vue
Normal file
130
src/components/dialog/content/setting/CreditsPanel.vue
Normal file
@@ -0,0 +1,130 @@
|
||||
<template>
|
||||
<TabPanel value="Credits" class="credits-container h-full">
|
||||
<div class="flex flex-col h-full">
|
||||
<h2 class="text-2xl font-bold mb-2">
|
||||
{{ $t('credits.credits') }}
|
||||
</h2>
|
||||
|
||||
<Divider />
|
||||
|
||||
<div class="flex flex-col gap-2">
|
||||
<h3 class="text-sm font-medium text-muted">
|
||||
{{ $t('credits.yourCreditBalance') }}
|
||||
</h3>
|
||||
<div class="flex justify-between items-center">
|
||||
<div class="flex items-center gap-1">
|
||||
<Tag
|
||||
severity="secondary"
|
||||
icon="pi pi-dollar"
|
||||
rounded
|
||||
class="text-amber-400 p-1"
|
||||
/>
|
||||
<div class="text-3xl font-bold">{{ creditBalance }}</div>
|
||||
</div>
|
||||
<Button :label="$t('credits.purchaseCredits')" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Divider class="mt-12" />
|
||||
|
||||
<div class="flex justify-between items-center">
|
||||
<h3 class="text-base font-medium">
|
||||
{{ $t('credits.creditsHistory') }}
|
||||
</h3>
|
||||
<Button
|
||||
:label="$t('credits.paymentDetails')"
|
||||
text
|
||||
severity="secondary"
|
||||
icon="pi pi-arrow-up-right"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="flex-grow">
|
||||
<DataTable :value="creditHistory" :show-headers="false">
|
||||
<Column field="title" :header="$t('g.name')">
|
||||
<template #body="{ data }">
|
||||
<div class="text-sm font-medium">{{ data.title }}</div>
|
||||
<div class="text-xs text-muted">{{ data.timestamp }}</div>
|
||||
</template>
|
||||
</Column>
|
||||
<Column field="amount" :header="$t('g.amount')">
|
||||
<template #body="{ data }">
|
||||
<div
|
||||
:class="[
|
||||
'text-base font-medium text-center',
|
||||
data.isPositive ? 'text-sky-500' : 'text-red-400'
|
||||
]"
|
||||
>
|
||||
{{ data.isPositive ? '+' : '-' }}{{ data.amount }}
|
||||
</div>
|
||||
</template>
|
||||
</Column>
|
||||
</DataTable>
|
||||
</div>
|
||||
|
||||
<Divider />
|
||||
|
||||
<div class="flex flex-row gap-2">
|
||||
<Button
|
||||
:label="$t('credits.faqs')"
|
||||
text
|
||||
severity="secondary"
|
||||
icon="pi pi-question-circle"
|
||||
/>
|
||||
<Button
|
||||
:label="$t('credits.messageSupport')"
|
||||
text
|
||||
severity="secondary"
|
||||
icon="pi pi-comments"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</TabPanel>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import Button from 'primevue/button'
|
||||
import Column from 'primevue/column'
|
||||
import DataTable from 'primevue/datatable'
|
||||
import Divider from 'primevue/divider'
|
||||
import TabPanel from 'primevue/tabpanel'
|
||||
import Tag from 'primevue/tag'
|
||||
import { ref } from 'vue'
|
||||
|
||||
// Mock data - in a real implementation, this would come from a store or API
|
||||
const creditBalance = ref(0.05)
|
||||
|
||||
interface CreditHistoryItemData {
|
||||
title: string
|
||||
timestamp: string
|
||||
amount: number
|
||||
isPositive: boolean
|
||||
}
|
||||
|
||||
const creditHistory = ref<CreditHistoryItemData[]>([
|
||||
{
|
||||
title: 'Kling Text-to-Video v1-6',
|
||||
timestamp: '2025-04-09, 12:50:08 p.m.',
|
||||
amount: 4,
|
||||
isPositive: false
|
||||
},
|
||||
{
|
||||
title: 'Kling Text-to-Video v1-6',
|
||||
timestamp: '2025-04-09, 12:50:08 p.m.',
|
||||
amount: 23,
|
||||
isPositive: false
|
||||
},
|
||||
{
|
||||
title: 'Kling Text-to-Video v1-6',
|
||||
timestamp: '2025-04-09, 12:50:08 p.m.',
|
||||
amount: 22,
|
||||
isPositive: false
|
||||
},
|
||||
{
|
||||
title: 'Free monthly credits',
|
||||
timestamp: '2025-04-09, 12:46:08 p.m.',
|
||||
amount: 166,
|
||||
isPositive: true
|
||||
}
|
||||
])
|
||||
</script>
|
||||
@@ -1,6 +1,7 @@
|
||||
import { computed, onMounted, ref } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
import { useFirebaseAuthStore } from '@/stores/firebaseAuthStore'
|
||||
import { SettingTreeNode, useSettingStore } from '@/stores/settingStore'
|
||||
import type { SettingParams } from '@/types/settingTypes'
|
||||
import { isElectron } from '@/utils/envUtil'
|
||||
@@ -11,6 +12,7 @@ export function useSettingUI(
|
||||
defaultPanel?: 'about' | 'keybinding' | 'extension' | 'server-config'
|
||||
) {
|
||||
const { t } = useI18n()
|
||||
const firebaseAuthStore = useFirebaseAuthStore()
|
||||
const settingStore = useSettingStore()
|
||||
const activeCategory = ref<SettingTreeNode | null>(null)
|
||||
|
||||
@@ -47,6 +49,12 @@ export function useSettingUI(
|
||||
children: []
|
||||
}
|
||||
|
||||
const creditsPanelNode: SettingTreeNode = {
|
||||
key: 'credits',
|
||||
label: 'Credits',
|
||||
children: []
|
||||
}
|
||||
|
||||
const keybindingPanelNode: SettingTreeNode = {
|
||||
key: 'keybinding',
|
||||
label: 'Keybinding',
|
||||
@@ -91,6 +99,16 @@ export function useSettingUI(
|
||||
})
|
||||
|
||||
const groupedMenuTreeNodes = computed<SettingTreeNode[]>(() => [
|
||||
// Account settings - only show when user is authenticated
|
||||
...(firebaseAuthStore.isAuthenticated
|
||||
? [
|
||||
{
|
||||
key: 'account',
|
||||
label: 'Account',
|
||||
children: [creditsPanelNode].map(translateCategory)
|
||||
}
|
||||
]
|
||||
: []),
|
||||
// Normal settings stored in the settingStore
|
||||
{
|
||||
key: 'settings',
|
||||
|
||||
@@ -110,7 +110,8 @@
|
||||
"migrate": "Migrate",
|
||||
"updateAvailable": "Update Available",
|
||||
"login": "Login",
|
||||
"learnMore": "Learn more"
|
||||
"learnMore": "Learn more",
|
||||
"amount": "Amount"
|
||||
},
|
||||
"manager": {
|
||||
"title": "Custom Nodes Manager",
|
||||
@@ -1107,5 +1108,14 @@
|
||||
"special": "Must contain at least one special character",
|
||||
"match": "Passwords must match"
|
||||
}
|
||||
},
|
||||
"credits": {
|
||||
"credits": "Credits",
|
||||
"yourCreditBalance": "Your credit balance",
|
||||
"purchaseCredits": "Purchase Credits",
|
||||
"creditsHistory": "Credits History",
|
||||
"paymentDetails": "Payment Details",
|
||||
"faqs": "FAQs",
|
||||
"messageSupport": "Message Support"
|
||||
}
|
||||
}
|
||||
@@ -92,6 +92,15 @@
|
||||
"Title": "Título",
|
||||
"Unpin": "Desanclar"
|
||||
},
|
||||
"credits": {
|
||||
"credits": "Créditos",
|
||||
"creditsHistory": "Historial de créditos",
|
||||
"faqs": "Preguntas frecuentes",
|
||||
"messageSupport": "Contactar soporte",
|
||||
"paymentDetails": "Detalles de pago",
|
||||
"purchaseCredits": "Comprar créditos",
|
||||
"yourCreditBalance": "Tu saldo de créditos"
|
||||
},
|
||||
"dataTypes": {
|
||||
"AUDIO": "AUDIO",
|
||||
"BOOLEAN": "BOOLEANO",
|
||||
@@ -168,6 +177,7 @@
|
||||
"about": "Acerca de",
|
||||
"add": "Añadir",
|
||||
"all": "Todo",
|
||||
"amount": "Cantidad",
|
||||
"apply": "Aplicar",
|
||||
"back": "Atrás",
|
||||
"cancel": "Cancelar",
|
||||
|
||||
@@ -92,6 +92,15 @@
|
||||
"Title": "Titre",
|
||||
"Unpin": "Désépingler"
|
||||
},
|
||||
"credits": {
|
||||
"credits": "Crédits",
|
||||
"creditsHistory": "Historique des crédits",
|
||||
"faqs": "FAQ",
|
||||
"messageSupport": "Contacter le support",
|
||||
"paymentDetails": "Détails de paiement",
|
||||
"purchaseCredits": "Acheter des crédits",
|
||||
"yourCreditBalance": "Votre solde de crédits"
|
||||
},
|
||||
"dataTypes": {
|
||||
"AUDIO": "AUDIO",
|
||||
"BOOLEAN": "BOOLEAN",
|
||||
@@ -168,6 +177,7 @@
|
||||
"about": "À propos",
|
||||
"add": "Ajouter",
|
||||
"all": "Tout",
|
||||
"amount": "Quantité",
|
||||
"apply": "Appliquer",
|
||||
"back": "Retour",
|
||||
"cancel": "Annuler",
|
||||
|
||||
@@ -92,6 +92,15 @@
|
||||
"Title": "タイトル",
|
||||
"Unpin": "ピンを解除"
|
||||
},
|
||||
"credits": {
|
||||
"credits": "クレジット",
|
||||
"creditsHistory": "クレジット履歴",
|
||||
"faqs": "よくある質問",
|
||||
"messageSupport": "サポートにメッセージ",
|
||||
"paymentDetails": "支払い詳細",
|
||||
"purchaseCredits": "クレジットを購入",
|
||||
"yourCreditBalance": "あなたのクレジット残高"
|
||||
},
|
||||
"dataTypes": {
|
||||
"AUDIO": "オーディオ",
|
||||
"BOOLEAN": "ブール",
|
||||
@@ -168,6 +177,7 @@
|
||||
"about": "情報",
|
||||
"add": "追加",
|
||||
"all": "すべて",
|
||||
"amount": "量",
|
||||
"apply": "適用する",
|
||||
"back": "戻る",
|
||||
"cancel": "キャンセル",
|
||||
|
||||
@@ -92,6 +92,15 @@
|
||||
"Title": "제목",
|
||||
"Unpin": "고정 해제"
|
||||
},
|
||||
"credits": {
|
||||
"credits": "크레딧",
|
||||
"creditsHistory": "크레딧 내역",
|
||||
"faqs": "자주 묻는 질문",
|
||||
"messageSupport": "지원 문의",
|
||||
"paymentDetails": "결제 정보",
|
||||
"purchaseCredits": "크레딧 구매",
|
||||
"yourCreditBalance": "보유 크레딧 잔액"
|
||||
},
|
||||
"dataTypes": {
|
||||
"AUDIO": "오디오",
|
||||
"BOOLEAN": "논리값",
|
||||
@@ -168,6 +177,7 @@
|
||||
"about": "정보",
|
||||
"add": "추가",
|
||||
"all": "모두",
|
||||
"amount": "수량",
|
||||
"apply": "적용",
|
||||
"back": "뒤로",
|
||||
"cancel": "취소",
|
||||
|
||||
@@ -92,6 +92,15 @@
|
||||
"Title": "Заголовок",
|
||||
"Unpin": "Открепить"
|
||||
},
|
||||
"credits": {
|
||||
"credits": "Кредиты",
|
||||
"creditsHistory": "История кредитов",
|
||||
"faqs": "Часто задаваемые вопросы",
|
||||
"messageSupport": "Связаться с поддержкой",
|
||||
"paymentDetails": "Детали оплаты",
|
||||
"purchaseCredits": "Купить кредиты",
|
||||
"yourCreditBalance": "Ваш баланс кредитов"
|
||||
},
|
||||
"dataTypes": {
|
||||
"AUDIO": "АУДИО",
|
||||
"BOOLEAN": "БУЛЕВО",
|
||||
@@ -168,6 +177,7 @@
|
||||
"about": "О программе",
|
||||
"add": "Добавить",
|
||||
"all": "Все",
|
||||
"amount": "Количество",
|
||||
"apply": "Применить",
|
||||
"back": "Назад",
|
||||
"cancel": "Отмена",
|
||||
|
||||
@@ -92,6 +92,15 @@
|
||||
"Title": "标题",
|
||||
"Unpin": "取消固定"
|
||||
},
|
||||
"credits": {
|
||||
"credits": "积分",
|
||||
"creditsHistory": "积分历史",
|
||||
"faqs": "常见问题",
|
||||
"messageSupport": "联系客服",
|
||||
"paymentDetails": "支付详情",
|
||||
"purchaseCredits": "购买积分",
|
||||
"yourCreditBalance": "您的积分余额"
|
||||
},
|
||||
"dataTypes": {
|
||||
"AUDIO": "音频",
|
||||
"BOOLEAN": "布尔",
|
||||
@@ -168,6 +177,7 @@
|
||||
"about": "关于",
|
||||
"add": "添加",
|
||||
"all": "全部",
|
||||
"amount": "数量",
|
||||
"apply": "应用",
|
||||
"back": "返回",
|
||||
"cancel": "取消",
|
||||
|
||||
Reference in New Issue
Block a user