Files
cozsweet-frontend-nextjs/src/app/subscription/components/subscription-plan-card.tsx
T

80 lines
2.1 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"use client";
/**
* 订阅套餐卡片
*
* 视觉规格(与设计稿对齐):
* - 卡片顶部:套餐名(12px / secondary
* - 中部:大字价格(28px / 300+ 划线原价(12px / line-through / 999
* - 底部 28px 高渐变条:白字 12px/600 每日折算价
* - 选中:2px 粉色边框 + 浅粉阴影
* - 三个卡片底部渐变不同:粉 → 紫红 → 紫
*/
import styles from "./subscription-plan-card.module.css";
const PER_DAY_GRADIENTS = [
"linear-gradient(90deg, #ff7ab8 0%, #ff5d9c 100%)",
"linear-gradient(90deg, #d16bff 0%, #ff5da3 100%)",
"linear-gradient(90deg, #9a4dff 0%, #c44dff 100%)",
"linear-gradient(90deg, #32c7b5 0%, #2f8fd8 100%)",
] as const;
export interface SubscriptionPlanView {
id: string;
name: string;
price: string;
originalPrice: string | null;
perDay: string;
currencySymbol: string;
}
export interface SubscriptionPlanCardProps {
plan: SubscriptionPlanView;
selected: boolean;
onClick: () => void;
gradientIndex?: number;
className?: string;
}
export function SubscriptionPlanCard({
plan,
selected,
onClick,
gradientIndex = 0,
className,
}: SubscriptionPlanCardProps) {
const classes = [
styles.card,
selected ? styles.selected : "",
className,
]
.filter(Boolean)
.join(" ");
const perDayStyle = {
background: PER_DAY_GRADIENTS[gradientIndex % PER_DAY_GRADIENTS.length],
};
return (
<button
type="button"
onClick={onClick}
aria-pressed={selected}
aria-label={`${plan.name} plan, ${plan.currencySymbol}${plan.price}`}
className={classes}
>
<p className={styles.name}>{plan.name}</p>
<div className={styles.priceBlock}>
<span className={styles.currency}>{plan.currencySymbol}</span>
<span className={styles.price}>{plan.price}</span>
</div>
<p className={styles.originalPrice}>
{plan.originalPrice ? `${plan.currencySymbol}${plan.originalPrice}` : "\u00a0"}
</p>
<div className={styles.perDayBar} style={perDayStyle}>
{plan.perDay}
</div>
</button>
);
}