diff --git a/projects/packages/podcast/changelog/fix-pods-189-podcast-welcome-entitled b/projects/packages/podcast/changelog/fix-pods-189-podcast-welcome-entitled new file mode 100644 index 00000000000..d9b9b71c778 --- /dev/null +++ b/projects/packages/podcast/changelog/fix-pods-189-podcast-welcome-entitled @@ -0,0 +1,4 @@ +Significance: patch +Type: fixed + +Welcome screen: Confirm podcasting is included instead of showing an upgrade prompt when the site's plan already covers it. diff --git a/projects/packages/podcast/src/dashboard/index.tsx b/projects/packages/podcast/src/dashboard/index.tsx index c37dac98553..2bd691ffc73 100644 --- a/projects/packages/podcast/src/dashboard/index.tsx +++ b/projects/packages/podcast/src/dashboard/index.tsx @@ -27,6 +27,13 @@ const ConnectPrompt = lazy( () => import( './connect-prompt' ) ); // grandfathered users out of the Episodes tab. const hasProductAccess = (): boolean => getScriptData()?.podcast?.has_product_access !== false; +// Fail-closed counterpart for entitlement *claims* (the welcome screen's +// "included with your plan" copy): only treat the site as entitled when the +// flag is explicitly true, so a missing flag never asserts entitlement we +// haven't confirmed or hides the upgrade path from a non-entitled user. +const hasConfirmedProductAccess = (): boolean => + getScriptData()?.podcast?.has_product_access === true; + const TabFallback = () => (
@@ -70,6 +77,9 @@ const App = () => { const { data: settings, isLoading } = usePodcastSettings(); const isSetUp = !! settings && settings.podcasting_category_id > 0; const hasAccess = hasProductAccess(); + // Confirmed entitlement gates the welcome "included" claim; the fail-open + // `hasAccess` keeps gating the tabs so a missing flag never locks anyone out. + const hasConfirmedAccess = hasConfirmedProductAccess(); const connected = isSiteConnected(); // `?tab=` owns the active tab; absent `?tab=` falls back to `defaultTab`. @@ -179,7 +189,7 @@ const App = () => {
}> - +
diff --git a/projects/packages/podcast/src/dashboard/welcome/index.tsx b/projects/packages/podcast/src/dashboard/welcome/index.tsx index 8f59e586f3b..02f28d88863 100644 --- a/projects/packages/podcast/src/dashboard/welcome/index.tsx +++ b/projects/packages/podcast/src/dashboard/welcome/index.tsx @@ -24,6 +24,8 @@ import './style.scss'; interface WelcomeProps { onEnable: () => void; + /** Whether the site already includes the paid podcast surfaces. */ + hasAccess: boolean; } const CHECKOUT_SOURCE = 'jetpack-podcast-welcome'; @@ -142,9 +144,9 @@ const STEPS: ReadonlyArray< { number: string; title: string; body: string } > = }, ]; -const Welcome = ( { onEnable }: WelcomeProps ) => { - const upgradeCheckoutUrl = getUpgradeCheckoutUrl(); - const planName = getUpgradePlanName(); +const Welcome = ( { onEnable, hasAccess }: WelcomeProps ) => { + const upgradeCheckoutUrl = ! hasAccess ? getUpgradeCheckoutUrl() : ''; + const planName = ! hasAccess ? getUpgradePlanName() : ''; const isWpcom = isWpcomPlatformSite(); const freeFeatures = isWpcom ? FREE_FEATURES_WPCOM : FREE_FEATURES_SELF_HOSTED; @@ -158,6 +160,17 @@ const Welcome = ( { onEnable }: WelcomeProps ) => { 'Unlock podcast stats, the episode dashboard, and the episode block.', 'jetpack-podcast' ); + // Shown when the site already owns the paid surfaces, so the plan comparison + // is replaced by confirmation copy instead of a checkout CTA. + const includedDescription = isWpcom + ? __( + 'Audio hosting, stats, the episode dashboard, and the episode block are all unlocked.', + 'jetpack-podcast' + ) + : __( + 'Podcast stats, the episode dashboard, and the episode block are all unlocked.', + 'jetpack-podcast' + ); // Fire-and-forget Tracks; the anchor handles navigation so middle/cmd-click // still opens checkout in a new tab and "copy link address" shows the URL. @@ -172,15 +185,31 @@ const Welcome = ( { onEnable }: WelcomeProps ) => {
-

- { __( 'Your podcast belongs with your blog', 'jetpack-podcast' ) } -

- - { __( - 'Publish your show on the same site as your blog and newsletter. Reach fans on Apple, Spotify, Pocket Casts, and every major podcast app.', - 'jetpack-podcast' - ) } - + { hasAccess ? ( + + + + + { __( 'Podcast is included with your plan', 'jetpack-podcast' ) } + + + { includedDescription } + + ) : ( + <> +

+ { __( 'Your podcast belongs with your blog', 'jetpack-podcast' ) } +

+ + { __( + 'Publish your show on the same site as your blog and newsletter. Reach fans on Apple, Spotify, Pocket Casts, and every major podcast app.', + 'jetpack-podcast' + ) } + + + ) }
-
- - - - - - - { __( 'Free', 'jetpack-podcast' ) } - - - { __( - 'Publish your podcast alongside your blog and newsletter.', - 'jetpack-podcast' - ) } - - - + { ! hasAccess && ( +
+ + + + + + + { __( 'Free', 'jetpack-podcast' ) } + + + { __( + 'Publish your podcast alongside your blog and newsletter.', + 'jetpack-podcast' + ) } + + - -
    - { freeFeatures.map( feature => ( -
  • - - { feature } -
  • - ) ) } -
- - - - - - - - - - - { planName } - - - { __( 'Popular', 'jetpack-podcast' ) } - - - { paidDescription } +
    + { freeFeatures.map( feature => ( +
  • + + { feature } +
  • + ) ) } +
- +
+
+ + + + + + + + { planName } + + + { __( 'Popular', 'jetpack-podcast' ) } + + + { paidDescription } + - -
    - { paidFeatures.map( feature => ( -
  • - - { feature } -
  • - ) ) } -
-
-
-
- -
+
    + { paidFeatures.map( feature => ( +
  • + + { feature } +
  • + ) ) } +
+
+
+
+
+
+ ) } { BENEFITS.map( b => ( diff --git a/projects/packages/podcast/src/dashboard/welcome/style.scss b/projects/packages/podcast/src/dashboard/welcome/style.scss index 9ec859f3720..2231bd92f7b 100644 --- a/projects/packages/podcast/src/dashboard/welcome/style.scss +++ b/projects/packages/podcast/src/dashboard/welcome/style.scss @@ -66,6 +66,16 @@ outline-offset: -2px; } +.podcast__welcome-plan-check { + display: inline-flex; + align-items: center; + color: #008a20; + + svg { + fill: currentColor; + } +} + .podcast__welcome-plan-badge { display: inline-block; padding: 2px 10px;