Files
d8d-admin-mobile-starter-pu…/client/mobile/pages_profile.tsx

148 lines
4.4 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import React from 'react'
import { useNavigate } from 'react-router'
import { useForm } from 'react-hook-form'
import { useQuery, useMutation } from '@tanstack/react-query'
import { UserAPI } from './api.ts'
import type { User } from '../share/types.ts'
import { useAuth } from './hooks.tsx'
export default function ProfilePage() {
const navigate = useNavigate()
const { register, handleSubmit, formState: { errors }, setValue } = useForm<{
username: string
nickname: string
email: string
phone?: string
password?: string
}>()
// 获取当前用户信息
const { data: user } = useQuery({
queryKey: ['currentUser'],
queryFn: async () => {
const res = await UserAPI.getUsers({ limit: 1 })
if (res.data?.length > 0) {
const userData = res.data[0]
setValue('username', userData.username)
setValue('nickname', userData.nickname || '')
setValue('email', userData.email || '')
setValue('phone', userData.phone || '')
return userData
}
return null
}
})
// 更新用户信息
const { mutate: updateUser, isPending } = useMutation({
mutationFn: async (data: {
nickname: string
email: string
phone?: string
password?: string
}) => {
if (!user?.id) throw new Error('用户ID不存在')
return UserAPI.updateUser(user.id, {
nickname: data.nickname,
email: data.email,
phone: data.phone,
...(data.password ? { password: data.password } : {})
})
},
onSuccess: (updatedUser) => {
alert('更新成功')
},
onError: (error) => {
console.error('更新失败:', error)
alert('更新失败')
}
})
const onSubmit = (data: {
username: string
nickname: string
email: string
phone?: string
password?: string
}) => {
updateUser({
nickname: data.nickname,
email: data.email,
phone: data.phone,
password: data.password
})
}
const { logout } = useAuth()
const handleLogout = async () => {
if (confirm('确定要退出登录吗?')) {
await logout()
navigate('/mobile/login')
}
}
return (
<div className="p-4">
<h1 className="text-2xl font-bold mb-4"></h1>
<div className="bg-white rounded-lg shadow p-4 mb-4">
<div className="flex items-center mb-4">
<div className="w-16 h-16 bg-blue-100 rounded-full flex items-center justify-center mr-4">
{user?.avatar ? (
<img
src={user.avatar}
alt={user?.nickname || user?.username || '用户'}
className="w-16 h-16 rounded-full object-cover"
/>
) : (
<span className="text-2xl text-blue-600"></span>
)}
</div>
<div>
<h2 className="text-xl font-semibold">{user?.nickname || user?.username || '未登录用户'}</h2>
<p className="text-gray-500"></p>
</div>
</div>
<button
onClick={() => navigate('/mobile/settings')}
className="w-full mt-4 py-2 bg-blue-100 text-blue-600 rounded-md hover:bg-blue-200 transition-colors"
>
</button>
</div>
<div className="bg-white rounded-lg shadow mb-4">
<div className="p-4 border-b">
<span className="font-medium"></span>
</div>
<div className="divide-y">
<div className="p-4 flex justify-between items-center">
<span></span>
<span className="text-gray-400"></span>
</div>
<div className="p-4 flex justify-between items-center">
<span></span>
<span className="text-gray-400"></span>
</div>
<div className="p-4 flex justify-between items-center">
<span></span>
<span className="text-gray-400"></span>
</div>
<div className="p-4 flex justify-between items-center">
<span></span>
<span className="text-gray-400"></span>
</div>
</div>
</div>
<button
onClick={handleLogout}
className="w-full py-3 bg-red-600 text-white rounded-lg hover:bg-red-700 transition-colors"
>
退
</button>
</div>
)
}