feat(sidebar): redesign sidebar UI with three user states (light theme)

Replace the dark sidebar theme with a light-themed three-state UI
matching the design references:

- guest  : pink "login" pill in user row, no status pill on VIP card,
           "Activate VIP Membership" button shown
- member : "VIP membership not activated" subtitle, no status pill,
           "Activate VIP Membership" button shown
- vip    : pink "VIP Member" pill with diamond icon, "Activated" pill
           in VIP card header, no Activate button

Decompose into BackBar, UserHeader, VipBenefitsCard, and VoicePackageCard
under src/app/sidebar/components/. Delete obsolete GuestPanel,
UserInfoCard, and VipCta.

Lift VIP_BENEFITS to a shared src/data/constants/vip-benefits.ts so the
sidebar and subscription page render identical benefit copy.

Add five sidebar tokens (--color-card-surface, --color-voice-gradient-*
--border-card, --shadow-card, --color-pill-bg) to src/tokens/colors.css.

Includes barrelsby regeneration for src/app/sidebar/components and
side-effect barrel updates under src/stores/{auth,chat,sidebar,user},
plus package-lock.json from npm install (required for lint/typecheck).

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2026-06-16 10:25:04 +08:00
parent 0548a08cbb
commit e44cc7e2f3
22 changed files with 10240 additions and 559 deletions
@@ -0,0 +1,72 @@
"use client";
import styles from "./voice-package-card.module.css";
export interface VoicePackageCardProps {
/** 已使用分钟数 */
usedMinutes: number;
/** 总分钟数 */
totalMinutes: number;
/** "Buy Package" 按钮点击 */
onBuyPackage: () => void;
}
/**
* Voice Message Package 卡片
*
* 视觉规格(与设计稿对齐):
* - 白色卡片 + 粉色→橙色渐变描边
* - 标题 "Voice Message Package"(粉色加粗)
* - 右上角大圆形渐变麦克风图标
* - "0min/0min used/remaining" 文案(前缀粉色加粗)
* - 底部 "Buy Package" 粉色胶囊按钮
*/
export function VoicePackageCard({
usedMinutes,
totalMinutes,
onBuyPackage,
}: VoicePackageCardProps) {
return (
<section className={styles.card}>
<header className={styles.header}>
<h2 className={styles.title}>Voice Message Package</h2>
<div className={styles.micIcon} aria-hidden="true">
<svg
width="28"
height="28"
viewBox="0 0 24 24"
fill="none"
className={styles.micGlyph}
>
<path
d="M12 14a3 3 0 0 0 3-3V6a3 3 0 0 0-6 0v5a3 3 0 0 0 3 3Z"
fill="currentColor"
/>
<path
d="M19 11a1 1 0 1 0-2 0 5 5 0 0 1-10 0 1 1 0 1 0-2 0 7 7 0 0 0 6 6.92V21a1 1 0 1 0 2 0v-3.08A7 7 0 0 0 19 11Z"
fill="currentColor"
/>
</svg>
</div>
</header>
<p className={styles.usage}>
<span className={styles.usageNumber}>
{usedMinutes}min/{totalMinutes}min
</span>
<span className={styles.usageText}> used/remaining</span>
</p>
<div className={styles.footer}>
<button
type="button"
className={styles.buyBtn}
onClick={onBuyPackage}
aria-label="Buy Package"
>
Buy Package
</button>
</div>
</section>
);
}