mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-03-12 00:20:15 +00:00
feat: add Free subscription tier support (#8864)
## Summary Add frontend support for a Free subscription tier — login/signup page restructuring, telemetry instrumentation, and tier-aware billing gating. ## Changes - **What**: - Restructure login/signup pages: OAuth buttons promoted as primary sign-in method, email login available via progressive disclosure - Add Free tier badge on Google sign-up button with dynamic credit count from remote config - Add `FREE` subscription tier to type system (tier pricing, tier rank, registry types) - Add `isFreeTier` computed to `useSubscription()` - Disable credit top-up for Free tier users (dialogService, purchaseCredits, popover CTA) - Show subscription/upgrade dialog instead of top-up dialog when Free tier user hits out-of-credits - Add funnel telemetry: `trackLoginOpened`, enrich `trackSignupOpened` with `free_tier_badge_shown`, track email toggle clicks ## Review Focus - Tier gating logic: Free tier users should see "Upgrade" instead of "Add Credits" and never reach the top-up flow - Telemetry event design for Mixpanel funnel analysis - Progressive disclosure UX on login/signup pages ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-8864-feat-add-Free-subscription-tier-support-3076d73d36508133b84ec5f0a67ccb03) by [Unito](https://www.unito.io)
This commit is contained in:
@@ -17,6 +17,7 @@ import type {
|
||||
} from '@/stores/dialogStore'
|
||||
|
||||
import type { ComponentAttrs } from 'vue-component-type-helpers'
|
||||
import type { SubscriptionDialogReason } from '@/platform/cloud/subscription/composables/useSubscriptionDialog'
|
||||
|
||||
// Lazy loaders for dialogs - components are loaded on first use
|
||||
const lazyApiNodesSignInContent = () =>
|
||||
@@ -274,8 +275,15 @@ export const useDialogService = () => {
|
||||
async function showTopUpCreditsDialog(options?: {
|
||||
isInsufficientCredits?: boolean
|
||||
}) {
|
||||
const { isActiveSubscription, type } = useBillingContext()
|
||||
if (!isActiveSubscription.value) return
|
||||
const { isActiveSubscription, isFreeTier, type } = useBillingContext()
|
||||
if (!isActiveSubscription.value || isFreeTier.value) {
|
||||
await showSubscriptionRequiredDialog({
|
||||
reason: options?.isInsufficientCredits
|
||||
? 'out_of_credits'
|
||||
: 'top_up_blocked'
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
const component =
|
||||
type.value === 'workspace'
|
||||
@@ -392,7 +400,9 @@ export const useDialogService = () => {
|
||||
})
|
||||
}
|
||||
|
||||
async function showSubscriptionRequiredDialog() {
|
||||
async function showSubscriptionRequiredDialog(options?: {
|
||||
reason?: SubscriptionDialogReason
|
||||
}) {
|
||||
if (!isCloud || !window.__CONFIG__?.subscription_required) {
|
||||
return
|
||||
}
|
||||
@@ -400,7 +410,7 @@ export const useDialogService = () => {
|
||||
const { useSubscriptionDialog } =
|
||||
await import('@/platform/cloud/subscription/composables/useSubscriptionDialog')
|
||||
const { show } = useSubscriptionDialog()
|
||||
show()
|
||||
show(options)
|
||||
}
|
||||
|
||||
// Workspace dialogs - dynamically imported to avoid bundling when feature flag is off
|
||||
|
||||
Reference in New Issue
Block a user