From 22bf26b7ff4383df22601724ab8ad04ae8ba802e Mon Sep 17 00:00:00 2001 From: Sodbileg Gansukh Date: Thu, 7 May 2026 19:26:26 +0800 Subject: [PATCH 01/10] Simplified Portal gift selection UI when only one paid tier is available --- apps/portal/src/components/pages/gift-page.js | 27 ++++++++++++++----- 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/apps/portal/src/components/pages/gift-page.js b/apps/portal/src/components/pages/gift-page.js index ff4c1642882..bfe74637af6 100644 --- a/apps/portal/src/components/pages/gift-page.js +++ b/apps/portal/src/components/pages/gift-page.js @@ -137,6 +137,10 @@ export const GiftPageStyles = ` border-color: var(--grey9); } +.gh-portal-gift-checkout-tiers.single .gh-portal-gift-checkout-tier-item:hover { + border-color: var(--grey11); +} + .gh-portal-gift-checkout-tier-item.selected { border-color: var(--brandcolor); background: color-mix(in srgb, var(--brandcolor) 6%, var(--white)); @@ -157,6 +161,10 @@ export const GiftPageStyles = ` color: inherit; } +.gh-portal-gift-checkout-tiers.single .gh-portal-gift-checkout-tier { + cursor: default; +} + .gh-portal-gift-checkout-tier-radio { flex-shrink: 0; width: 18px; @@ -646,6 +654,7 @@ const GiftPage = () => { } const activeProduct = products.find(p => p.id === selectedProductId) || products[0]; + const isSingleTier = products.length === 1; const isPurchasing = action === 'checkoutGift:running'; const isDisabled = isCookiesDisabled() || isPurchasing; @@ -681,25 +690,31 @@ const GiftPage = () => {
-
Tier
-
+
{isSingleTier ? 'Membership details' : 'Tier'}
+
{products.map((product) => { const isSelected = product.id === activeProduct.id; const benefits = product.benefits || []; return (
From 6da97ab1d550914c6e8e51f2a4744685e4df2d16 Mon Sep 17 00:00:00 2001 From: Sodbileg Gansukh Date: Thu, 7 May 2026 19:59:02 +0800 Subject: [PATCH 02/10] Surfaced tier description in Portal gift selection and details --- apps/portal/src/components/pages/gift-page.js | 49 +++++++++++++++++-- .../components/pages/gift-redemption-page.js | 42 +++++++++------- .../src/components/pages/gift-success-page.js | 29 ++++++----- .../src/components/pages/magic-link-page.js | 42 +++++++++------- 4 files changed, 110 insertions(+), 52 deletions(-) diff --git a/apps/portal/src/components/pages/gift-page.js b/apps/portal/src/components/pages/gift-page.js index bfe74637af6..f28c1b982cf 100644 --- a/apps/portal/src/components/pages/gift-page.js +++ b/apps/portal/src/components/pages/gift-page.js @@ -149,7 +149,7 @@ export const GiftPageStyles = ` .gh-portal-gift-checkout-tier { display: flex; - align-items: center; + align-items: flex-start; gap: 10px; width: 100%; background: transparent; @@ -169,6 +169,7 @@ export const GiftPageStyles = ` flex-shrink: 0; width: 18px; height: 18px; + margin-top: 3px; border-radius: 50%; border: 1.5px solid var(--grey9); background: var(--white); @@ -192,6 +193,20 @@ export const GiftPageStyles = ` transform: translate(-50%, -50%); } +.gh-portal-gift-checkout-tier-content { + flex: 1; + min-width: 0; + display: flex; + flex-direction: column; + gap: 4px; +} + +.gh-portal-gift-checkout-tier-heading { + display: flex; + align-items: baseline; + gap: 10px; +} + .gh-portal-gift-checkout-tier-name { flex: 1; font-size: 1.5rem; @@ -205,6 +220,14 @@ export const GiftPageStyles = ` color: var(--grey0); } +.gh-portal-gift-checkout-tier-description { + margin: 0; + margin-top: -2px; + font-size: 1.4rem; + line-height: 1.4; + color: var(--grey4); +} + .gh-portal-gift-checkout-tier-benefits { display: grid; grid-template-rows: 0fr; @@ -245,7 +268,7 @@ export const GiftPageStyles = ` .gh-portal-gift-checkout-benefit svg { width: 14px; height: 14px; - margin-top: 4px; + margin-top: 3px; color: var(--grey1); flex-shrink: 0; } @@ -367,6 +390,17 @@ export const GiftPageStyles = ` overflow: hidden; } +.gh-portal-gift-checkout-details-description { + margin: 0 0 12px; + font-size: 1.45rem; + line-height: 1.4; + color: rgba(255, 255, 255, 0.85); +} + +.gh-portal-gift-checkout-details-description:last-child { + margin-bottom: 0; +} + .gh-portal-gift-checkout-card { position: relative; width: 100%; @@ -715,8 +749,15 @@ const GiftPage = () => { {!isSingleTier && (
- {benefits.length > 0 && ( + {(tierDescription || benefits.length > 0) && ( <>
{ aria-hidden={!showDetails} >
-
- {benefits.map((benefit, index) => { - const benefitName = typeof benefit === 'string' ? benefit : benefit?.name; - const benefitKey = typeof benefit === 'string' ? benefit : benefit?.id || `gift-benefit-${index}`; - - if (!benefitName) { - return null; - } - - return ( -
- - {benefitName} -
- ); - })} -
+ {tierDescription && ( +

{tierDescription}

+ )} + {benefits.length > 0 && ( +
+ {benefits.map((benefit, index) => { + const benefitName = typeof benefit === 'string' ? benefit : benefit?.name; + const benefitKey = typeof benefit === 'string' ? benefit : benefit?.id || `gift-benefit-${index}`; + + if (!benefitName) { + return null; + } + + return ( +
+ + {benefitName} +
+ ); + })} +
+ )}
- {tier && tier.benefits && tier.benefits.length > 0 && ( + {tier && (tier.description || (tier.benefits && tier.benefits.length > 0)) && ( <>
{ aria-hidden={!showDetails} >
-
- {tier.benefits.map((benefit, idx) => { - const key = benefit?.id || `benefit-${idx}`; - return ( -
- - {benefit.name} -
- ); - })} -
+ {tier.description && ( +

{tier.description}

+ )} + {tier.benefits && tier.benefits.length > 0 && ( +
+ {tier.benefits.map((benefit, idx) => { + const key = benefit?.id || `benefit-${idx}`; + return ( +
+ + {benefit.name} +
+ ); + })} +
+ )}
- {benefits.length > 0 && ( + {(tierDescription || benefits.length > 0) && ( <>
-
- {benefits.map((benefit, index) => { - const benefitName = typeof benefit === 'string' ? benefit : benefit?.name; - const benefitKey = typeof benefit === 'string' ? benefit : benefit?.id || `gift-benefit-${index}`; - - if (!benefitName) { - return null; - } - - return ( -
- - {benefitName} -
- ); - })} -
+ {tierDescription && ( +

{tierDescription}

+ )} + {benefits.length > 0 && ( +
+ {benefits.map((benefit, index) => { + const benefitName = typeof benefit === 'string' ? benefit : benefit?.name; + const benefitKey = typeof benefit === 'string' ? benefit : benefit?.id || `gift-benefit-${index}`; + + if (!benefitName) { + return null; + } + + return ( +
+ + {benefitName} +
+ ); + })} +
+ )}