| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245 |
- import { useState, useEffect } from 'react'
- import { View, Text, Image, Button, ScrollView } from '@tarojs/components'
- import Taro from '@tarojs/taro'
- import { TabBarLayout } from '@/layouts/tab-bar-layout'
- import { useAuth } from '@/utils/auth'
- import { cn } from '@/utils/cn'
- interface UserProfile {
- id: number
- username: string
- email?: string
- avatar?: string
- createdAt: string
- lastLoginAt?: string
- }
- const ProfilePage: React.FC = () => {
- const [userProfile, setUserProfile] = useState<UserProfile | null>(null)
- const [loading, setLoading] = useState(true)
- const { user, logout } = useAuth()
- useEffect(() => {
- if (user) {
- setUserProfile({
- id: user.id,
- username: user.username,
- email: user.email,
- avatar: user.avatar || 'https://source.unsplash.com/200x200/?avatar,face',
- createdAt: new Date().toISOString(),
- lastLoginAt: new Date().toISOString()
- })
- }
- setLoading(false)
- }, [user])
- const handleLogout = async () => {
- try {
- Taro.showModal({
- title: '退出登录',
- content: '确定要退出登录吗?',
- success: async (res) => {
- if (res.confirm) {
- Taro.showLoading({ title: '退出中...' })
- await logout()
- Taro.hideLoading()
- Taro.showToast({
- title: '已退出登录',
- icon: 'success',
- duration: 1500
- })
- setTimeout(() => {
- Taro.reLaunch({ url: '/pages/index/index' })
- }, 1500)
- }
- }
- })
- } catch (error) {
- Taro.hideLoading()
- Taro.showToast({
- title: '退出失败,请重试',
- icon: 'none'
- })
- }
- }
- const handleEditProfile = () => {
- Taro.showToast({
- title: '功能开发中...',
- icon: 'none'
- })
- }
- const handleSettings = () => {
- Taro.showToast({
- title: '功能开发中...',
- icon: 'none'
- })
- }
- const menuItems = [
- {
- icon: 'i-heroicons-user-circle-20-solid',
- title: '编辑资料',
- onClick: handleEditProfile,
- color: 'text-blue-500'
- },
- {
- icon: 'i-heroicons-cog-6-tooth-20-solid',
- title: '设置',
- onClick: handleSettings,
- color: 'text-gray-500'
- },
- {
- icon: 'i-heroicons-shield-check-20-solid',
- title: '隐私政策',
- onClick: () => Taro.showToast({ title: '功能开发中...', icon: 'none' }),
- color: 'text-green-500'
- },
- {
- icon: 'i-heroicons-question-mark-circle-20-solid',
- title: '帮助与反馈',
- onClick: () => Taro.showToast({ title: '功能开发中...', icon: 'none' }),
- color: 'text-purple-500'
- }
- ]
- if (loading) {
- return (
- <TabBarLayout activeKey="profile">
- <View className="flex-1 flex items-center justify-center">
- <View className="i-heroicons-arrow-path-20-solid animate-spin w-8 h-8 text-blue-500" />
- </View>
- </TabBarLayout>
- )
- }
- if (!userProfile) {
- return (
- <TabBarLayout activeKey="profile">
- <View className="flex-1 flex items-center justify-center">
- <View className="text-center">
- <View className="i-heroicons-exclamation-circle-20-solid w-12 h-12 text-gray-400 mx-auto mb-4" />
- <Text className="text-gray-600 mb-4">请先登录</Text>
- <Button
- className="bg-blue-500 text-white px-6 py-2 rounded-lg"
- onClick={() => Taro.navigateTo({ url: '/pages/login/index' })}
- >
- 去登录
- </Button>
- </View>
- </View>
- </TabBarLayout>
- )
- }
- return (
- <TabBarLayout activeKey="profile">
- <ScrollView className="flex-1 bg-gray-50">
- {/* 用户信息卡片 */}
- <View className="bg-white rounded-b-3xl shadow-sm pb-8">
- <View className="flex flex-col items-center pt-8 pb-6">
- <View className="relative">
- <Image
- className="w-24 h-24 rounded-full border-4 border-white shadow-lg"
- src={userProfile.avatar || 'https://source.unsplash.com/200x200/?avatar'}
- mode="aspectFill"
- />
- <View className="absolute -bottom-2 -right-2 w-8 h-8 bg-blue-500 rounded-full flex items-center justify-center shadow-md">
- <View className="i-heroicons-camera-20-solid w-4 h-4 text-white" />
- </View>
- </View>
- <Text className="text-xl font-bold text-gray-900 mt-4">{userProfile.username}</Text>
- {userProfile.email && (
- <Text className="text-sm text-gray-600 mt-1">{userProfile.email}</Text>
- )}
- <View className="flex items-center mt-2">
- <View className="i-heroicons-calendar-20-solid w-4 h-4 text-gray-400 mr-1" />
- <Text className="text-xs text-gray-500">
- 注册于 {new Date(userProfile.createdAt).toLocaleDateString('zh-CN')}
- </Text>
- </View>
- </View>
- {/* 统计信息 */}
- <View className="px-6">
- <View className="grid grid-cols-3 gap-4 text-center">
- <View className="bg-gray-50 rounded-xl p-4">
- <Text className="text-2xl font-bold text-blue-500">0</Text>
- <Text className="text-xs text-gray-600 mt-1">收藏</Text>
- </View>
- <View className="bg-gray-50 rounded-xl p-4">
- <Text className="text-2xl font-bold text-green-500">0</Text>
- <Text className="text-xs text-gray-600 mt-1">点赞</Text>
- </View>
- <View className="bg-gray-50 rounded-xl p-4">
- <Text className="text-2xl font-bold text-purple-500">0</Text>
- <Text className="text-xs text-gray-600 mt-1">关注</Text>
- </View>
- </View>
- </View>
- </View>
- {/* 功能菜单 */}
- <View className="px-4 pt-6">
- <View className="bg-white rounded-2xl shadow-sm overflow-hidden">
- {menuItems.map((item, index) => (
- <View
- key={index}
- className="flex items-center px-4 py-4 active:bg-gray-50 transition-colors duration-150"
- onClick={item.onClick}
- >
- <View className={cn("w-6 h-6 mr-3", item.color, item.icon)} />
- <Text className="flex-1 text-gray-800">{item.title}</Text>
- <View className="i-heroicons-chevron-right-20-solid w-5 h-5 text-gray-400" />
- </View>
- ))}
- </View>
- </View>
- {/* 账号信息 */}
- <View className="px-4 pt-6">
- <View className="bg-white rounded-2xl shadow-sm p-4">
- <Text className="text-sm font-medium text-gray-700 mb-3">账号信息</Text>
- <View className="space-y-3">
- <View className="flex justify-between items-center">
- <Text className="text-sm text-gray-600">用户ID</Text>
- <Text className="text-sm text-gray-900 font-mono">{userProfile.id}</Text>
- </View>
- {userProfile.lastLoginAt && (
- <View className="flex justify-between items-center">
- <Text className="text-sm text-gray-600">最近登录</Text>
- <Text className="text-sm text-gray-900">
- {new Date(userProfile.lastLoginAt).toLocaleString('zh-CN')}
- </Text>
- </View>
- )}
- </View>
- </View>
- </View>
- {/* 退出登录按钮 */}
- <View className="px-4 pt-6 pb-8">
- <Button
- className="w-full h-12 bg-red-500 text-white rounded-xl font-medium hover:bg-red-600 active:bg-red-700 transition-colors duration-200"
- onClick={handleLogout}
- >
- <View className="flex items-center justify-center">
- <View className="i-heroicons-arrow-left-on-rectangle-20-solid w-5 h-5 mr-2" />
- 退出登录
- </View>
- </Button>
- </View>
- {/* 版本信息 */}
- <View className="pb-8">
- <Text className="text-center text-xs text-gray-400">
- v1.0.0 - 小程序版
- </Text>
- </View>
- </ScrollView>
- </TabBarLayout>
- )
- }
- export default ProfilePage
|