返回 AiToEarn
MobileUserSection.tsx
根目录 / project / aitoearn-web / src / app / layout / MobileNav / components / MobileUserSection.tsx
1 import type { MobileUserSectionProps } from '../types'
2 /**
3 * MobileUserSection - 移动端用户头像/登录区域
4 */
5 import { useTransClient } from '@/app/i18n/client'
6 import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar'
7 import { Button } from '@/components/ui/button'
8 import { useUserStore } from '@/store/user'
9 import { navigateToLogin } from '@/utils/auth'
10 import { getOssUrl } from '@/utils/oss'
11
12 export function MobileUserSection({
13 onClose,
14 onOpenSettings,
15 }: MobileUserSectionProps) {
16 const { t } = useTransClient('common')
17 const token = useUserStore(state => state.token)
18 const userInfo = useUserStore(state => state.userInfo)
19
20 const handleLogin = () => {
21 onClose()
22 navigateToLogin()
23 }
24
25 if (token && userInfo) {
26 const handleClick = () => {
27 onClose()
28 onOpenSettings()
29 }
30
31 return (
32 <button
33 onClick={handleClick}
34 data-testid="mobile-user-btn"
35 className="flex w-full items-center gap-3 px-4 py-3 rounded-lg text-muted-foreground hover:bg-muted transition-colors cursor-pointer"
36 >
37 <Avatar className="h-8 w-8 shrink-0 border border-border">
38 <AvatarImage src={getOssUrl(userInfo.avatar) || ''} alt={userInfo.name || t('unknownUser')} />
39 <AvatarFallback className="bg-muted-foreground font-semibold text-background">
40 {userInfo.name?.charAt(0)?.toUpperCase() || 'U'}
41 </AvatarFallback>
42 </Avatar>
43
44 <div className="flex min-w-0 flex-1 flex-col items-start">
45 <span className="truncate text-sm font-medium text-foreground" data-testid="mobile-user-name">
46 {userInfo.name || t('unknownUser')}
47 </span>
48 </div>
49 </button>
50 )
51 }
52
53 return (
54 <Button onClick={handleLogin} className="w-full cursor-pointer" data-testid="mobile-login-btn">
55 {t('login')}
56 </Button>
57 )
58 }
59
59 lines Plain Text