diff --git a/projects/packages/podcast/changelog/fix-create-ai-podcast-free-credit-reset-copy b/projects/packages/podcast/changelog/fix-create-ai-podcast-free-credit-reset-copy new file mode 100644 index 000000000000..8b7046991d9a --- /dev/null +++ b/projects/packages/podcast/changelog/fix-create-ai-podcast-free-credit-reset-copy @@ -0,0 +1,4 @@ +Significance: patch +Type: fixed + +Create AI Podcast: Clarify that free trial credits do not reset. diff --git a/projects/packages/podcast/src/admin-pages/create-ai-podcast/index.js b/projects/packages/podcast/src/admin-pages/create-ai-podcast/index.js index 61455e027ee9..2dd614cac9c0 100644 --- a/projects/packages/podcast/src/admin-pages/create-ai-podcast/index.js +++ b/projects/packages/podcast/src/admin-pages/create-ai-podcast/index.js @@ -311,7 +311,8 @@ bar.appendChild( fill ); creditsEl.appendChild( bar ); - const reset = formatResetPhrase( quota?.resetsAt ); + const resetsNever = quota?.resetsAt === 'never'; + const reset = resetsNever ? null : formatResetPhrase( quota?.resetsAt ); const meta = document.createElement( 'div' ); meta.className = 'jetpack-create-ai-podcast__credits-meta'; @@ -324,14 +325,20 @@ sep.className = 'jetpack-create-ai-podcast__credits-meta-sep'; sep.setAttribute( 'aria-hidden', 'true' ); sep.textContent = '·'; - meta.appendChild( sep ); const resetEl = document.createElement( 'span' ); resetEl.className = 'jetpack-create-ai-podcast__credits-meta-reset'; - resetEl.textContent = reset - ? sprintf( data.i18n.creditsResetSummary, reset.inline ) - : data.i18n.creditsResetMonthly; - meta.appendChild( resetEl ); + let resetText = ''; + if ( reset ) { + resetText = sprintf( data.i18n.creditsResetSummary, reset.inline ); + } else if ( ! resetsNever ) { + resetText = data.i18n.creditsResetMonthly; + } + if ( resetText ) { + meta.appendChild( sep ); + resetEl.textContent = resetText; + meta.appendChild( resetEl ); + } creditsEl.appendChild( meta ); @@ -345,6 +352,8 @@ outMessage = upgradeUrl ? sprintf( data.i18n.outOfCreditsUpgrade, reset.inline ) : sprintf( data.i18n.outOfCreditsWait, reset.inline ); + } else if ( resetsNever ) { + outMessage = data.i18n.outOfTrialCredits; } creditsEl.appendChild( buildBanner( { @@ -356,6 +365,17 @@ reset, } ) ); + } else if ( resetsNever ) { + creditsEl.appendChild( + buildBanner( { + state: 'low', + title: data.i18n.trialBannerTitle, + message: data.i18n.trialBannerMessage, + upgradeUrl, + quota: quotaSummary, + reset, + } ) + ); } else if ( isLow && upgradeUrl ) { creditsEl.appendChild( buildBanner( { @@ -374,8 +394,7 @@ * Translate quota.resetsAt into a relative phrase that works both inside * a sentence (e.g. "your credits refresh {inline}") and as a stand-alone * summary line (e.g. "Resets {inline}"). Returns null when the timestamp - * is missing or malformed so callers fall back to a generic "monthly" - * blurb. + * is missing or malformed so callers can use generic monthly copy. * * @param resetsAt - ISO-8601 reset timestamp. * @return {{ inline: string, days: number, date: Date } | null} Phrase, days until reset, and parsed Date — or null when input is missing. diff --git a/projects/packages/podcast/src/class-create-ai-podcast-page.php b/projects/packages/podcast/src/class-create-ai-podcast-page.php index 3d2e4eb9c220..dbaf778772ab 100644 --- a/projects/packages/podcast/src/class-create-ai-podcast-page.php +++ b/projects/packages/podcast/src/class-create-ai-podcast-page.php @@ -390,6 +390,8 @@ private static function build_localized_data(): array { 'relativeDays' => __( 'in %d days', 'jetpack-podcast' ), // translators: %s: formatted date, e.g. "May 20, 2026". 'relativeOn' => __( 'on %s', 'jetpack-podcast' ), + 'trialBannerTitle' => __( 'Try before you buy', 'jetpack-podcast' ), + 'trialBannerMessage' => __( 'Generate a podcast from your posts and see how it sounds on your site. Free trial is limited to one podcast episode.', 'jetpack-podcast' ), 'runningLowTitle' => __( 'Running low', 'jetpack-podcast' ), 'runningLowMessage' => __( 'Upgrade your plan to keep generating without waiting for the monthly refresh.', 'jetpack-podcast' ), 'outOfCreditsTitle' => __( 'Out of credits', 'jetpack-podcast' ), @@ -397,6 +399,7 @@ private static function build_localized_data(): array { 'outOfCreditsWait' => __( 'Your credits will refresh %s.', 'jetpack-podcast' ), // translators: %s: relative time, e.g. "in 12 days" or "tomorrow". 'outOfCreditsUpgrade' => __( 'Upgrade your plan for more credits, or wait until they refresh %s.', 'jetpack-podcast' ), + 'outOfTrialCredits' => __( 'You have used your one-time trial credit. Upgrade your plan for more credits.', 'jetpack-podcast' ), 'noPostsFound' => __( 'No posts match.', 'jetpack-podcast' ), 'loadingPosts' => __( 'Loading posts…', 'jetpack-podcast' ), 'pickPosts' => __( 'Select at least one post to continue.', 'jetpack-podcast' ),