feat(payment): sync plans and add coins rules

This commit is contained in:
2026-06-29 14:11:50 +08:00
parent 274fe87ced
commit e372d58b4c
24 changed files with 1099 additions and 224 deletions
+41 -18
View File
@@ -1,9 +1,10 @@
"use client";
import { LogOut } from "lucide-react";
import { signOut } from "next-auth/react";
import { useRouter } from "next/navigation";
import { MobileShell, SettingsSection } from "@/app/_components/core";
import { MobileShell } from "@/app/_components/core";
import { ROUTES } from "@/router/routes";
import { useAuthDispatch, useAuthState } from "@/stores/auth/auth-context";
import { useUserDispatch, useUserState } from "@/stores/user/user-context";
@@ -20,6 +21,12 @@ import styles from "./components/sidebar-screen.module.css";
const FALLBACK_USERNAME = "User name";
const VIP_SUBSCRIPTION_URL = `${ROUTES.subscription}?type=vip`;
const STATUS_LABELS: Record<SidebarUserState, string> = {
guest: "Sign in to keep your coins and unlock more features.",
member: "Manage your wallet, subscription and account settings.",
vip: "Your VIP benefits are active. Enjoy the full experience.",
};
/**
* 侧边栏主屏幕
*
@@ -58,12 +65,22 @@ export function SidebarScreen() {
const avatarUrl = user.avatarUrl ?? user.currentUser?.avatarUrl ?? null;
return (
<MobileShell>
<MobileShell background="#fcf3f4">
<div className={styles.shell}>
<BackBar />
<div className={styles.bgOrbOne} aria-hidden="true" />
<div className={styles.bgOrbTwo} aria-hidden="true" />
{/* 用户信息区:三种状态 */}
<section className={styles.userSlot}>
<div className={styles.topBar}>
<BackBar />
</div>
<section className={styles.hero}>
<p className={styles.kicker}>Cozsweet</p>
<h1 className={styles.title}>Account</h1>
<p className={styles.subtitle}>{STATUS_LABELS[sidebarState]}</p>
</section>
<section className={`${styles.userSlot} ${styles.revealOne}`}>
<UserHeader
state={sidebarState}
name={name}
@@ -73,10 +90,11 @@ export function SidebarScreen() {
/>
</section>
<section className={styles.cardSlot}>
<section className={`${styles.cardSlot} ${styles.revealTwo}`}>
<SidebarWalletCard
creditBalance={user.creditBalance}
onTopUp={() => router.push(VIP_SUBSCRIPTION_URL)}
onRulesClick={() => router.push(ROUTES.coinsRules)}
/>
</section>
@@ -91,18 +109,23 @@ export function SidebarScreen() {
*/}
{sidebarState !== "guest" ? (
<section className={styles.settingsSlot}>
<SettingsSection
title="Other"
items={[
{
id: "logout",
title: "Log out",
destructive: true,
onClick: handleLogoutClick,
},
]}
/>
<section className={`${styles.settingsSlot} ${styles.revealThree}`}>
<p className={styles.settingsLabel}>Other</p>
<button
type="button"
className={styles.logoutCard}
onClick={handleLogoutClick}
>
<span className={styles.logoutIcon} aria-hidden="true">
<LogOut size={19} strokeWidth={2.2} />
</span>
<span className={styles.logoutText}>
<span className={styles.logoutTitle}>Log out</span>
<span className={styles.logoutSubtitle}>
End the current session safely
</span>
</span>
</button>
</section>
) : null}
</div>