| 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 |