dashboard: in-context upgrade prompts replacing generic CTAs (U2)#39
Merged
Conversation
Every generic "Upgrade to Pro" CTA now renders a feature-specific UpgradePromptCard. Copy lives in src/components/upgradeCopy.ts as a record map keyed by UpgradeFeature, so each call site stays at one prop (<UpgradePromptCard feature="vault_prod" />) and the framing varies by surface. The CARD copy varies by surface; the BUTTON inside it composes with P1's A/B variant on /auth/me.experiments.upgrade_cta. When no variant is in flight we fall back to DEFAULT_UPGRADE_CTA so the UI degrades cleanly. Refactored surfaces (verified by grep audit): - DeployDetailPage.PromoteUpsell -> feature="family_bindings" - DeployDetailPage.CustomDomainUpsell -> feature="custom_domain" - CustomDomainPanel 402 banner -> feature="custom_domain" (dense) - ResourcesPage quota wall -> feature="quota_wall" (>=80% on hobby) - VaultPage non-prod env on hobby -> feature="vault_prod" - BillingPage main CTA stays generic, gains "what <next> unlocks" bullet list above the button (per brief). 23 new tests across UpgradePromptCard.test.tsx + UpgradePromptSurfaces.test.tsx + BillingPage.test.tsx. 234 pass / 3 skip. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ompts-fresh # Conflicts: # src/pages/BillingPage.tsx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
UpgradePromptCardso the framing converts to the surface the user is on (vault prod isolation, family bindings, quota wall, custom domain, provision-twin).src/components/upgradeCopy.ts) keyed byUpgradeFeature. Each call site stays at one prop./auth/me.experiments.upgrade_ctavariant. Falls back cleanly toDEFAULT_UPGRADE_CTA = "Upgrade to Pro →"when no variant is in flight.Surfaces refactored (verified via grep audit)
DeployDetailPage.PromoteUpsell->feature="family_bindings"DeployDetailPage.CustomDomainUpsell->feature="custom_domain"CustomDomainPanel402 banner ->feature="custom_domain"(dense)ResourcesPagequota wall ->feature="quota_wall"(only fires for anonymous/free/hobby when any resource is at ≥ 80% storage)VaultPage->feature="vault_prod"(only fires when a single-env tier navigates to a non-prod env tab)BillingPage-> keeps its generic primary CTA per brief; gains thedata-testid="next-tier-unlocks"bullet list above the button so the user sees what their click pays for.P1 coordination
P1's variant contract isn't published yet. Assumption (documented in
upgradeCopy.tsand surfaced on the newAuthMeResponse.experimentsfield): the variant payload looks like{ variant?: string; label?: string }and the UI only consumeslabel. If P1 ships a different shape we adapt the reader inUpgradePromptCard— call sites don't change.Test plan
npm test: 234 pass, 3 skipped (was 209 / 3) —vitestnpx tsc --noEmit: cleanOut of scope
🤖 Generated with Claude Code