feat(chat): port chat widget components from Dart to React

This commit is contained in:
2026-06-09 20:19:52 +08:00
parent 199a14650e
commit 109a3e3855
48 changed files with 2463 additions and 382 deletions
+71
View File
@@ -0,0 +1,71 @@
"use client";
/**
* ChatHeader 顶部栏
*
* 原始 Dart: lib/ui/chat/widgets/chat_header.dart112 行)
*
* 两种模式:
* - 游客模式(isGuest=true):渲染 `GuestBanner` 提示注册(点击 → /auth
* - 登录模式(isGuest=false):渲染 `MenuButton`(点击 → 打开 ChatMenuBar
*/
import { useRouter } from "next/navigation";
import { useState } from "react";
import { ROUTES } from "@/lib/routes";
import { ChatMenuBar } from "./chat-menu-bar";
import styles from "./chat-header.module.css";
export interface ChatHeaderProps {
isGuest: boolean;
}
export function ChatHeader({ isGuest }: ChatHeaderProps) {
const router = useRouter();
const [menuOpen, setMenuOpen] = useState(false);
if (isGuest) {
return (
<header className={styles.header}>
<button
type="button"
className={styles.guestBanner}
onClick={() => router.push(ROUTES.auth)}
aria-label="Sign up to unlock more features"
>
<span className={styles.guestBannerIcon} aria-hidden="true">
🔒
</span>
<span>Sign up to unlock more features</span>
</button>
</header>
);
}
return (
<>
<header className={styles.header}>
<div className={styles.headerRow}>
{/* 菜单按钮(点击 → 打开 ChatMenuBar 浮层) */}
<button
type="button"
className={styles.menuButton}
onClick={() => setMenuOpen(true)}
aria-label="Menu"
aria-expanded={menuOpen}
>
<span className={styles.menuIcon} aria-hidden="true">
</span>
</button>
</div>
</header>
<ChatMenuBar
open={menuOpen}
onClose={() => setMenuOpen(false)}
environmentName="dev"
/>
</>
);
}