| 1 | import type { MobileTopBarProps } from '../types' |
| 2 | /** |
| 3 | * MobileTopBar - 移动端顶部栏 |
| 4 | * 左侧 Logo + 文字,右侧根据登录状态显示用户头像或菜单图标 |
| 5 | */ |
| 6 | import { Menu } from 'lucide-react' |
| 7 | import Image from 'next/image' |
| 8 | import Link from 'next/link' |
| 9 | import { useTransClient } from '@/app/i18n/client' |
| 10 | import logo from '@/assets/images/logo.png' |
| 11 | import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar' |
| 12 | import { useUserStore } from '@/store/user' |
| 13 | import { getOssUrl } from '@/utils/oss' |
| 14 | |
| 15 | export function MobileTopBar({ onOpen }: MobileTopBarProps) { |
| 16 | const { t } = useTransClient('common') |
| 17 | const token = useUserStore(state => state.token) |
| 18 | const userInfo = useUserStore(state => state.userInfo) |
| 19 | |
| 20 | const isLoggedIn = !!token && !!userInfo |
| 21 | |
| 22 | return ( |
| 23 | <div className="md:hidden fixed top-0 left-0 right-0 z-50 flex items-center justify-between h-14 px-4 bg-background border-b border-border" data-testid="mobile-topbar"> |
| 24 | <Link href="/" className="flex items-center gap-2" data-testid="mobile-topbar-logo"> |
| 25 | <Image src={logo} alt="Aitoearn" width={32} height={32} /> |
| 26 | <span className="text-base font-semibold text-foreground">Aitoearn</span> |
| 27 | </Link> |
| 28 | |
| 29 | <div className="flex items-center gap-2"> |
| 30 | {isLoggedIn ? ( |
| 31 | <button |
| 32 | onClick={onOpen} |
| 33 | data-testid="mobile-topbar-menu-btn" |
| 34 | className="flex items-center rounded-lg p-1.5 text-muted-foreground hover:bg-muted transition-colors cursor-pointer" |
| 35 | > |
| 36 | <Avatar className="h-7 w-7 shrink-0 border border-border"> |
| 37 | <AvatarImage src={getOssUrl(userInfo.avatar) || ''} alt={userInfo.name || t('unknownUser')} /> |
| 38 | <AvatarFallback className="bg-muted-foreground font-semibold text-background text-xs"> |
| 39 | {userInfo.name?.charAt(0)?.toUpperCase() || 'U'} |
| 40 | </AvatarFallback> |
| 41 | </Avatar> |
| 42 | </button> |
| 43 | ) : ( |
| 44 | <button |
| 45 | onClick={onOpen} |
| 46 | data-testid="mobile-topbar-menu-btn" |
| 47 | className="flex items-center justify-center w-10 h-10 rounded-lg text-muted-foreground hover:bg-muted transition-colors cursor-pointer" |
| 48 | > |
| 49 | <Menu size={24} /> |
| 50 | </button> |
| 51 | )} |
| 52 | </div> |
| 53 | </div> |
| 54 | ) |
| 55 | } |
| 56 |