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:
2026-06-17 14:13:42 +08:00
parent cda76a1651
commit 287affa34a
16 changed files with 53 additions and 47 deletions
+118
View File
@@ -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>
);
}