fix(tip): refine gift presentation

This commit is contained in:
2026-07-21 14:24:26 +08:00
parent 37ff69020b
commit a990f5082b
6 changed files with 45 additions and 31 deletions
@@ -57,4 +57,36 @@ describe("tip screen helpers", () => {
),
).toEqual([TIP_GIFT_PLACEHOLDER_IMAGE]);
});
it.each([
["coffee_small", "/images/tip/small.jpg"],
["coffee_medium", "/images/tip/medium.png"],
["coffee_large", "/images/tip/large.png"],
])("uses the %s tier image as its local fallback", (tipType, expected) => {
const tierProduct = GiftProductSchema.parse({
...product,
tipType,
imageUrl: null,
});
const categoryWithoutImage = GiftCategorySchema.parse({
...category,
imageUrl: null,
});
expect(getGiftImageSources(tierProduct, categoryWithoutImage)).toEqual([
expected,
]);
});
it("uses the generic placeholder for unknown gift types", () => {
const unknownProduct = GiftProductSchema.parse({
...product,
tipType: "flowers",
imageUrl: null,
});
expect(getGiftImageSources(unknownProduct, null)).toEqual([
TIP_GIFT_PLACEHOLDER_IMAGE,
]);
});
});
@@ -43,11 +43,6 @@ export function TipGiftProductSelector({
/>
<span className={styles.tierDetails}>
<span className={styles.tierName}>{product.planName}</span>
{product.description ? (
<span className={styles.tierDescription}>
{product.description}
</span>
) : null}
</span>
<span className={styles.tierPriceBlock}>
<span className={styles.tierPrice}>
+12 -1
View File
@@ -5,6 +5,12 @@ import type {
export const TIP_GIFT_PLACEHOLDER_IMAGE = "/images/tip/medium.png";
const TIP_GIFT_PLACEHOLDER_BY_TIP_TYPE: Readonly<Record<string, string>> = {
coffee_small: "/images/tip/small.jpg",
coffee_medium: "/images/tip/medium.png",
coffee_large: "/images/tip/large.png",
};
export function formatGiftPrice(
amountCents: number,
currency: string,
@@ -25,10 +31,15 @@ export function getGiftImageSources(
product: GiftProduct | null,
category: GiftCategory | null,
): readonly string[] {
const placeholderImage = product
? (TIP_GIFT_PLACEHOLDER_BY_TIP_TYPE[product.tipType] ??
TIP_GIFT_PLACEHOLDER_IMAGE)
: TIP_GIFT_PLACEHOLDER_IMAGE;
return [
product?.imageUrl,
category?.imageUrl,
TIP_GIFT_PLACEHOLDER_IMAGE,
placeholderImage,
].filter(
(source, index, sources): source is string =>
Boolean(source) && sources.indexOf(source) === index,
-19
View File
@@ -226,14 +226,6 @@
letter-spacing: -0.04em;
}
.productDescription {
margin: 10px 0 0;
color: #7d6264;
font-size: clamp(12px, 3.148vw, 15px);
font-weight: 620;
line-height: 1.45;
}
.visuallyHidden {
position: absolute;
width: 1px;
@@ -352,17 +344,6 @@
white-space: nowrap;
}
.tierDescription {
display: -webkit-box;
overflow: hidden;
color: #80676a;
font-size: 11px;
font-weight: 620;
line-height: 1.35;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
}
.tierPriceBlock {
align-items: flex-end;
gap: 3px;
-5
View File
@@ -286,11 +286,6 @@ export function TipScreen({
selectedProduct.currency,
)}
</p>
{selectedProduct.description ? (
<p className={styles.productDescription}>
{selectedProduct.description}
</p>
) : null}
</div>
<TipGiftProductSelector
+1 -1
View File
@@ -102,7 +102,7 @@ export function TipSuccessView({
className={styles.title}
tabIndex={-1}
>
You made {characterName} smile.
Thank you. Your gift made me smile.
</h1>
<div className={styles.copy}>
<p>