mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-04-20 06:20:11 +00:00
## Summary Implements billing infrastructure for team workspaces, separate from legacy personal billing. ## Changes - **Billing abstraction**: New `useBillingContext` composable that switches between legacy (personal) and workspace billing based on context - **Workspace subscription flows**: Pricing tables, plan transitions, cancellation dialogs, and payment preview components for workspace billing - **Top-up credits**: Workspace-specific top-up dialog with polling for payment confirmation - **Workspace API**: Extended with billing endpoints (subscriptions, invoices, payment methods, credits top-up) - **Workspace switcher**: Now displays tier badges for each workspace - **Subscribe polling**: Added polling mechanisms (`useSubscribePolling`, `useTopupPolling`) for async payment flows ## Review Focus - Billing flow correctness for workspace vs legacy contexts - Polling timeout and error handling in payment flows ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-8508-Feat-workspaces-6-billing-2f96d73d365081f69f65c1ddf369010d) by [Unito](https://www.unito.io) --------- Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
73 lines
1.7 KiB
Vue
73 lines
1.7 KiB
Vue
<template>
|
|
<Button
|
|
:size
|
|
:disabled="disabled"
|
|
variant="primary"
|
|
:style="
|
|
variant === 'gradient'
|
|
? {
|
|
background: 'var(--color-subscription-button-gradient)',
|
|
color: 'var(--color-white)'
|
|
}
|
|
: undefined
|
|
"
|
|
:class="cn('font-bold', fluid && 'w-full')"
|
|
@click="handleSubscribe"
|
|
>
|
|
{{ label || $t('subscription.required.subscribe') }}
|
|
</Button>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { onBeforeUnmount, ref, watch } from 'vue'
|
|
|
|
import Button from '@/components/ui/button/Button.vue'
|
|
import { useBillingContext } from '@/composables/billing/useBillingContext'
|
|
import { isCloud } from '@/platform/distribution/types'
|
|
import { useTelemetry } from '@/platform/telemetry'
|
|
import { cn } from '@/utils/tailwindUtil'
|
|
|
|
const {
|
|
size = 'lg',
|
|
fluid = true,
|
|
variant = 'default',
|
|
label,
|
|
disabled = false
|
|
} = defineProps<{
|
|
label?: string
|
|
size?: 'sm' | 'lg'
|
|
variant?: 'default' | 'gradient'
|
|
fluid?: boolean
|
|
disabled?: boolean
|
|
}>()
|
|
|
|
const emit = defineEmits<{
|
|
subscribed: []
|
|
}>()
|
|
|
|
const { isActiveSubscription, showSubscriptionDialog } = useBillingContext()
|
|
const isAwaitingStripeSubscription = ref(false)
|
|
|
|
watch(
|
|
[isAwaitingStripeSubscription, isActiveSubscription],
|
|
([awaiting, isActive]) => {
|
|
if (isCloud && awaiting && isActive) {
|
|
emit('subscribed')
|
|
isAwaitingStripeSubscription.value = false
|
|
}
|
|
}
|
|
)
|
|
|
|
const handleSubscribe = () => {
|
|
if (isCloud) {
|
|
useTelemetry()?.trackSubscription('subscribe_clicked')
|
|
}
|
|
isAwaitingStripeSubscription.value = true
|
|
showSubscriptionDialog()
|
|
}
|
|
|
|
onBeforeUnmount(() => {
|
|
isAwaitingStripeSubscription.value = false
|
|
})
|
|
</script>
|