Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 63 additions & 16 deletions src/components/dialog/content/TopUpCreditsDialogContent.vue
Original file line number Diff line number Diff line change
Expand Up @@ -49,25 +49,66 @@
@select="selectedCredits = option.credits"
/>
</div>
<div class="text-xs text-muted-foreground w-96">
{{ $t('credits.topUp.templateNote') }}
<div class="flex flex-row items-center gap-2 group pt-2">
<i
class="pi pi-question-circle text-xs text-muted-foreground group-hover:text-base-foreground"
/>
<span
class="text-sm font-normal text-muted-foreground cursor-pointer group-hover:text-base-foreground"
@click="togglePopover"
>
{{ t('subscription.videoTemplateBasedCredits') }}
</span>
</div>
</div>

<!-- Buy Button -->
<Button
:disabled="!selectedCredits || loading"
:loading="loading"
variant="primary"
:class="cn('w-full', (!selectedCredits || loading) && 'opacity-30')"
@click="handleBuy"
<!-- Buy Button -->
<Button
:disabled="!selectedCredits || loading"
:loading="loading"
variant="primary"
:class="cn('w-full', (!selectedCredits || loading) && 'opacity-30')"
@click="handleBuy"
>
{{ $t('credits.topUp.buy') }}
</Button>
</div>
<Popover
ref="popover"
append-to="body"
:auto-z-index="true"
:base-z-index="1000"
:dismissable="true"
:close-on-escape="true"
unstyled
:pt="{
root: {
class:
'rounded-lg border border-interface-stroke bg-interface-panel-surface shadow-lg p-4 max-w-xs'
}
}"
>
{{ $t('credits.topUp.buy') }}
</Button>
<div class="flex flex-col gap-2">
<p class="text-sm text-base-foreground leading-normal">
{{ t('subscription.videoEstimateExplanation') }}
</p>
<a
href="https://cloud.comfy.org/?template=video_wan2_2_14B_fun_camera"
target="_blank"
rel="noopener noreferrer"
class="text-sm text-azure-600 hover:text-azure-400 no-underline flex gap-1"
>
<span class="underline">
{{ t('subscription.videoEstimateTryTemplate') }}
</span>
<span class="no-underline" v-html="'&rarr;'"></span>
</a>
</div>
</Popover>
</div>
</template>

<script setup lang="ts">
import { Popover } from 'primevue'
import { useToast } from 'primevue/usetoast'
import { ref } from 'vue'
import { useI18n } from 'vue-i18n'
Expand Down Expand Up @@ -101,22 +142,28 @@ const toast = useToast()
const selectedCredits = ref<number | null>(null)
const loading = ref(false)

const popover = ref()

const togglePopover = (event: Event) => {
popover.value.toggle(event)
}

const creditOptions: CreditOption[] = [
{
credits: 1055, // $5.00
description: t('credits.topUp.videosEstimate', { count: 41 })
description: t('credits.topUp.videosEstimate', { count: 30 })
},
{
credits: 2110, // $10.00
description: t('credits.topUp.videosEstimate', { count: 82 })
description: t('credits.topUp.videosEstimate', { count: 60 })
},
{
credits: 4220, // $20.00
description: t('credits.topUp.videosEstimate', { count: 184 })
description: t('credits.topUp.videosEstimate', { count: 120 })
},
{
credits: 10550, // $50.00
description: t('credits.topUp.videosEstimate', { count: 412 })
description: t('credits.topUp.videosEstimate', { count: 301 })
}
]

Expand Down
11 changes: 6 additions & 5 deletions src/locales/en/main.json
Original file line number Diff line number Diff line change
Expand Up @@ -1912,7 +1912,7 @@
"insufficientWorkflowMessage": "You don't have enough credits to run this workflow.",
"creditsDescription": "Credits are used to run workflows or partner nodes.",
"howManyCredits": "How many credits would you like to add?",
"videosEstimate": "~{count} videos*",
"videosEstimate": "~{count} videos",
"templateNote": "*Generated with Wan Fun Control template",
"buy": "Buy",
"purchaseError": "Purchase Failed",
Expand Down Expand Up @@ -2015,10 +2015,11 @@
"gpuLabel": "RTX 6000 Pro (96GB VRAM)",
"addCreditsLabel": "Add more credits whenever",
"customLoRAsLabel": "Import your own LoRAs",
"videoEstimateLabel": "Number of 5s videos generated with Wan Fun Control template",
"videoEstimateHelp": "What is this?",
"videoEstimateExplanation": "These estimates are based on the Wan Fun Control template for 5-second videos.",
"videoEstimateTryTemplate": "Try the Wan Fun Control template →",
"videoEstimateLabel": "Approx. amount of 5s videos generated with Wan 2.2 Image-to-Video template",
"videoEstimateHelp": "More details on this template",
"videoEstimateExplanation": "These estimates are based on the Wan 2.2 Image-to-Video template using default settings (5 seconds, 640x640, 16fps, 4-step sampling).",
"videoEstimateTryTemplate": "Try this template",
"videoTemplateBasedCredits": "Videos generated with Wan 2.2 Image to Video",
"upgradePlan": "Upgrade Plan",
"upgradeTo": "Upgrade to {plan}",
"changeTo": "Change to {plan}",
Expand Down
13 changes: 9 additions & 4 deletions src/platform/cloud/subscription/components/PricingTable.vue
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,9 @@
<div class="flex flex-col gap-2">
<div class="flex flex-row items-start justify-between">
<div class="flex flex-col gap-2">
<span class="text-sm font-normal text-foreground">
<span
class="text-sm font-normal text-foreground leading-relaxed"
>
{{ t('subscription.videoEstimateLabel') }}
</span>
<div class="flex flex-row items-center gap-2 group pt-2">
Expand Down Expand Up @@ -220,16 +222,19 @@
}"
>
<div class="flex flex-col gap-2">
<p class="text-sm text-base-foreground">
<p class="text-sm text-base-foreground leading-normal">
{{ t('subscription.videoEstimateExplanation') }}
</p>
<a
href="https://cloud.comfy.org/?template=video_wan2_2_14B_fun_camera"
target="_blank"
rel="noopener noreferrer"
class="text-sm text-azure-600 hover:text-azure-400 underline"
class="text-sm text-azure-600 hover:text-azure-400 no-underline flex gap-1"
>
{{ t('subscription.videoEstimateTryTemplate') }}
<span class="underline">
{{ t('subscription.videoEstimateTryTemplate') }}
</span>
<span class="no-underline" v-html="'&rarr;'"></span>
</a>
Comment on lines 228 to 238
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Replace v-html with direct character or entity.

Using v-html for a simple arrow character is unnecessary and less efficient. The template also duplicates similar structure from TopUpCreditsDialogContent.vue.

🔎 Proposed refactor
-          <span class="underline">
-            {{ t('subscription.videoEstimateTryTemplate') }}
-          </span>
-          <span class="no-underline" v-html="'&rarr;'"></span>
+          <span class="underline">
+            {{ t('subscription.videoEstimateTryTemplate') }}
+          </span>
+          <span class="no-underline">→</span>
🤖 Prompt for AI Agents
In @src/platform/cloud/subscription/components/PricingTable.vue around lines 228
- 238, The anchor in PricingTable.vue is using v-html to render a simple arrow;
replace the v-html="'&rarr;'" on the span with a direct character or entity
(e.g., put → or &rarr; as plain text inside the span) and remove the v-html
binding to avoid unnecessary HTML injection; mirror the same simpler approach
used in TopUpCreditsDialogContent.vue so the markup is consistent with the
existing component.

</div>
</Popover>
Expand Down
6 changes: 3 additions & 3 deletions src/platform/cloud/subscription/constants/tierPricing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ export interface TierPricing {
}

export const TIER_PRICING: Record<Exclude<TierKey, 'founder'>, TierPricing> = {
standard: { monthly: 20, yearly: 16, credits: 4200, videoEstimate: 164 },
creator: { monthly: 35, yearly: 28, credits: 7400, videoEstimate: 288 },
pro: { monthly: 100, yearly: 80, credits: 21100, videoEstimate: 821 }
standard: { monthly: 20, yearly: 16, credits: 4200, videoEstimate: 120 },
creator: { monthly: 35, yearly: 28, credits: 7400, videoEstimate: 211 },
pro: { monthly: 100, yearly: 80, credits: 21100, videoEstimate: 600 }
}

interface TierFeatures {
Expand Down