返回 AiToEarn
index.tsx
1 /**
2 * ChannelManager - 频道管理弹窗组件
3 *
4 * 功能描述:
5 * - 三页面视图:主页、连接频道列表、授权loading页
6 * - 左侧频道类型侧边栏 + 右侧空间和账号管理
7 * - 支持外部调用 openModal、openAndAuth 等方法
8 * - 全局单例,挂载在根布局
9 */
10
11 'use client'
12
13 import { VisuallyHidden } from '@radix-ui/react-visually-hidden'
14 import { useShallow } from 'zustand/react/shallow'
15 import { useTransClient } from '@/app/i18n/client'
16 import { Dialog, DialogContent, DialogHeader, DialogTitle } from '@/components/ui/dialog'
17 import { useChannelManagerStore } from './channelManagerStore'
18 import { AuthLoadingPage } from './components/AuthLoadingPage'
19 import { ConnectChannelList } from './components/ConnectChannelList'
20 import { MainPage } from './components/MainPage'
21
22 export function ChannelManager() {
23 const { t } = useTransClient('account')
24
25 const { open, currentView, closeModal } = useChannelManagerStore(
26 useShallow(state => ({
27 open: state.open,
28 currentView: state.currentView,
29 closeModal: state.closeModal,
30 })),
31 )
32
33 // 根据当前视图获取标题
34 const getTitle = () => {
35 switch (currentView) {
36 case 'connect-list':
37 return t('channelManager.connectNewChannel')
38 case 'auth-loading':
39 return t('channelManager.authInProgress')
40 default:
41 return t('channelManager.title')
42 }
43 }
44
45 // 渲染当前视图
46 const renderView = () => {
47 switch (currentView) {
48 case 'connect-list':
49 return <ConnectChannelList />
50 case 'auth-loading':
51 return <AuthLoadingPage />
52 default:
53 return <MainPage />
54 }
55 }
56
57 return (
58 <Dialog open={open} onOpenChange={closeModal}>
59 <DialogContent data-testid="channel-manager-dialog" className="flex h-[100dvh] max-h-[100dvh] w-full max-w-full flex-col overflow-hidden border-border/70 bg-background p-0 shadow-2xl md:h-[744px] md:max-h-[calc(100dvh-32px)] md:max-w-[1160px] md:rounded-xl">
60 {/* Header - 只在主页和连接列表页显示,auth-loading 时用 VisuallyHidden 保留无障碍标题 */}
61 {currentView !== 'auth-loading' ? (
62 <DialogHeader className="justify-center space-y-0 border-b border-border/70 bg-background px-6 py-4 md:min-h-[68px] md:px-7">
63 <DialogTitle className="text-xl font-semibold tracking-tight text-foreground">{getTitle()}</DialogTitle>
64 </DialogHeader>
65 ) : (
66 <VisuallyHidden>
67 <DialogTitle>{getTitle()}</DialogTitle>
68 </VisuallyHidden>
69 )}
70
71 {/* 内容区域 */}
72 <div className="min-h-0 flex-1">{renderView()}</div>
73 </DialogContent>
74 </Dialog>
75 )
76 }
77
78 // 导出store hook
79 export { useChannelManagerStore } from './channelManagerStore'
80
81 // 导出类型
82 export * from './types'
83
84 // 默认导出
85 export default ChannelManager
86
86 lines Plain Text