feat(tip): improve gift layout and background

This commit is contained in:
2026-07-21 15:35:57 +08:00
parent 612c4139af
commit 0381090867
3 changed files with 165 additions and 112 deletions
+90 -84
View File
@@ -210,6 +210,8 @@ export function TipScreen({
}
>
<div className={styles.bgImage} aria-hidden="true" />
<div className={styles.bgGlowOne} aria-hidden="true" />
<div className={styles.bgGlowTwo} aria-hidden="true" />
<header className={styles.header}>
<BackButton
@@ -218,6 +220,9 @@ export function TipScreen({
ariaLabel="Back to character home"
analyticsKey="tip.back_to_splash"
/>
</header>
<div className={styles.contentFlow}>
<div className={styles.headerIdentity}>
<div className={styles.headerAvatar}>
<CharacterAvatar
@@ -232,97 +237,98 @@ export function TipScreen({
{character.copy.tipTitle}
</h1>
</div>
<span className={styles.headerBalance} aria-hidden="true" />
</header>
<p
className={`${styles.supportPrompt} ${
supportPrompt.isReady ? styles.supportPromptReady : ""
}`}
>
{supportPrompt.prompt}
</p>
<p
className={`${styles.supportPrompt} ${
supportPrompt.isReady ? styles.supportPromptReady : ""
}`}
>
{supportPrompt.prompt}
</p>
<div className={styles.purchaseFlow}>
{payment.isLoadingPlans ? (
<section
className={`${styles.productCard} ${styles.productSkeleton}`}
aria-label="Loading gifts"
aria-busy="true"
>
<div className={styles.skeletonImage} />
<div className={styles.skeletonList}>
<span />
<span />
<span />
</div>
</section>
) : selectedProduct ? (
<>
<div className={styles.purchaseFlow}>
{payment.isLoadingPlans ? (
<section
className={styles.productCard}
aria-label="Gift products"
className={`${styles.productCard} ${styles.productSkeleton}`}
aria-label="Loading gifts"
aria-busy="true"
>
<div className={styles.coffeeStage}>
<TipProductImage
key={selectedProduct.planId}
sources={getGiftImageSources(
selectedProduct,
selectedCategory,
)}
alt={selectedProduct.planName}
className={styles.coffeeImage}
priority
<div className={styles.skeletonImage} />
<div className={styles.skeletonList}>
<span />
<span />
<span />
</div>
</section>
) : selectedProduct ? (
<>
<section
className={styles.productCard}
aria-label="Gift products"
>
<div className={styles.coffeeStage}>
<TipProductImage
key={selectedProduct.planId}
sources={getGiftImageSources(
selectedProduct,
selectedCategory,
)}
alt={selectedProduct.planName}
className={styles.coffeeImage}
priority
/>
</div>
<TipGiftProductSelector
disabled={isSelectionDisabled}
products={visibleProducts}
onChange={handleProductChange}
selectedPlanId={payment.selectedPlanId}
/>
</section>
<PaymentMethodSelector
config={paymentMethodConfig}
value={payment.payChannel}
density="compact"
disabled={isPaymentBusy}
className={styles.paymentMethodSlot}
analyticsKey="tip.payment_method"
onChange={handlePaymentMethodChange}
/>
<div className={styles.checkoutSlot}>
<TipCheckoutButton
giftCategory={payment.selectedGiftCategory}
giftPlanId={payment.selectedPlanId || null}
disabled={!canCreateOrder}
onOrder={handleOrder}
returnPath={returnPath}
/>
</div>
<TipGiftProductSelector
disabled={isSelectionDisabled}
products={visibleProducts}
onChange={handleProductChange}
selectedPlanId={payment.selectedPlanId}
/>
</>
) : showCatalogError || showEmptyCatalog ? (
<section className={styles.catalogStatus} role="status">
<p>
{showCatalogError
? "We could not load gifts for this character."
: "This character does not have any gifts available yet."}
</p>
{showCatalogError ? (
<button
type="button"
onClick={() =>
paymentDispatch({
type: "PaymentCatalogRetryRequested",
})
}
>
Try again
</button>
) : null}
</section>
<PaymentMethodSelector
config={paymentMethodConfig}
value={payment.payChannel}
density="compact"
disabled={isPaymentBusy}
className={styles.paymentMethodSlot}
analyticsKey="tip.payment_method"
onChange={handlePaymentMethodChange}
/>
<div className={styles.checkoutSlot}>
<TipCheckoutButton
giftCategory={payment.selectedGiftCategory}
giftPlanId={payment.selectedPlanId || null}
disabled={!canCreateOrder}
onOrder={handleOrder}
returnPath={returnPath}
/>
</div>
</>
) : showCatalogError || showEmptyCatalog ? (
<section className={styles.catalogStatus} role="status">
<p>
{showCatalogError
? "We could not load gifts for this character."
: "This character does not have any gifts available yet."}
</p>
{showCatalogError ? (
<button
type="button"
onClick={() =>
paymentDispatch({ type: "PaymentCatalogRetryRequested" })
}
>
Try again
</button>
) : null}
</section>
) : null}
) : null}
</div>
</div>
</main>
</MobileShell>