refactor(app): move route screens out of components
Exclude test and spec files from generated barrels so page imports do not load test modules at runtime.
This commit is contained in:
@@ -0,0 +1,118 @@
|
||||
"use client";
|
||||
|
||||
import { useEffect } from "react";
|
||||
import { useRouter } from "next/navigation";
|
||||
|
||||
import { MobileShell, SettingsSection } 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";
|
||||
|
||||
import {
|
||||
BackBar,
|
||||
UserHeader,
|
||||
type SidebarUserState,
|
||||
VipBenefitsCard,
|
||||
VoicePackageCard,
|
||||
} from "./components";
|
||||
|
||||
import styles from "./components/sidebar-screen.module.css";
|
||||
|
||||
const FALLBACK_USERNAME = "User name";
|
||||
|
||||
/**
|
||||
* 侧边栏主屏幕
|
||||
*
|
||||
* 根据 `loginStatus + currentUser.isVip` 派生三种状态:
|
||||
* - guest:未登录
|
||||
* - member:已登录未购买 VIP
|
||||
* - vip:已登录且购买 VIP
|
||||
*
|
||||
* 原始 Dart: lib/ui/sidebar/sidebar_screen.dart + profile_view.dart
|
||||
*/
|
||||
export function SidebarScreen() {
|
||||
const user = useUserState();
|
||||
const userDispatch = useUserDispatch();
|
||||
const auth = useAuthState();
|
||||
const authDispatch = useAuthDispatch();
|
||||
const router = useRouter();
|
||||
|
||||
useEffect(() => {
|
||||
userDispatch({ type: "UserInit" });
|
||||
}, [userDispatch]);
|
||||
|
||||
const handleLogoutClick = () => {
|
||||
authDispatch({ type: "AuthReset" });
|
||||
userDispatch({ type: "UserLogout" });
|
||||
router.replace(ROUTES.chat);
|
||||
};
|
||||
|
||||
// 状态派生:未登录 / 已登录未 VIP / 已登录 VIP
|
||||
const sidebarState: SidebarUserState =
|
||||
auth.loginStatus === "notLoggedIn"
|
||||
? "guest"
|
||||
: user.currentUser?.isVip === true
|
||||
? "vip"
|
||||
: "member";
|
||||
|
||||
const isInitializingUser =
|
||||
sidebarState !== "guest" && user.currentUser == null;
|
||||
|
||||
const name = user.currentUser?.username ?? FALLBACK_USERNAME;
|
||||
const avatarUrl = user.currentUser?.avatarUrl ?? null;
|
||||
|
||||
return (
|
||||
<MobileShell>
|
||||
<div className={styles.shell}>
|
||||
<BackBar />
|
||||
|
||||
{/* 用户信息区:三种状态 */}
|
||||
<section className={styles.userSlot}>
|
||||
<UserHeader
|
||||
state={sidebarState}
|
||||
name={name}
|
||||
avatarUrl={avatarUrl}
|
||||
isLoading={isInitializingUser}
|
||||
onLoginClick={() => router.push(ROUTES.auth)}
|
||||
/>
|
||||
</section>
|
||||
|
||||
<section className={styles.cardSlot}>
|
||||
<VipBenefitsCard
|
||||
state={sidebarState}
|
||||
onActivate={() => router.push(ROUTES.subscription)}
|
||||
/>
|
||||
</section>
|
||||
|
||||
<section className={styles.cardSlot}>
|
||||
<VoicePackageCard
|
||||
usedMinutes={0}
|
||||
totalMinutes={0}
|
||||
onBuyPackage={() => router.push(ROUTES.subscription)}
|
||||
/>
|
||||
</section>
|
||||
|
||||
{sidebarState !== "guest" ? (
|
||||
<section className={styles.settingsSlot}>
|
||||
<SettingsSection
|
||||
title="Other"
|
||||
items={[
|
||||
{
|
||||
id: "membership",
|
||||
title: "Membership",
|
||||
onClick: () => router.push(ROUTES.subscription),
|
||||
},
|
||||
{
|
||||
id: "logout",
|
||||
title: "Log out",
|
||||
destructive: true,
|
||||
onClick: handleLogoutClick,
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</section>
|
||||
) : null}
|
||||
</div>
|
||||
</MobileShell>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user