Files
wechat_wc/src/pages/settings/index.tsx
T

178 lines
6.9 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 { View, Text, Image, Input, Button } from '@tarojs/components'
import Taro from '@tarojs/taro'
import { useState, useEffect, useCallback } from 'react'
import './index.scss'
import { useThemeContext } from '../../context/ThemeContext'
import { useSafeArea } from '../../hooks/useSafeArea'
import { useStatusBar } from '../../hooks/useStatusBar'
import ThemedPageMeta from '../../components/ThemedPageMeta'
import { getUserInfo, setUserInfo, clearUserInfo, getAddressList, getDefaultAddress, type AddressItem } from '../../utils/store'
const THEME_OPTIONS: { label: string; value: 'light' | 'dark' | 'auto' }[] = [
{ label: '浅色模式', value: 'light' },
{ label: '深色模式', value: 'dark' },
{ label: '跟随系统', value: 'auto' }
]
const MENU = [
{ label: '个人信息', icon: '/icon/个人.png', action: (s: any) => s.setShowEdit(true) },
{ label: '账号管理', icon: '/icon/账号管理.png', action: () => Taro.navigateTo({ url: '/pages/userDatabase/index' }) },
{ label: '定制协议', icon: '/icon/定制协议.png', action: () => Taro.navigateTo({ url: '/pages/agreement/index' }) },
{ label: '关于我们', icon: '/icon/关于我们.png', action: () => Taro.showToast({ title: '智绘微刻 v1.0', icon: 'none' }) }
]
export default function SettingsPage() {
const { theme, setTheme, resolvedTheme } = useThemeContext()
const safe = useSafeArea()
useStatusBar(resolvedTheme)
const [user, setUser] = useState<any>({})
const [editName, setEditName] = useState('')
const [editAvatar, setEditAvatar] = useState('')
const [showEdit, setShowEdit] = useState(false)
const loadUser = () => {
const u = getUserInfo() || {}
setUser(u)
setEditName(u.nickName || '')
setEditAvatar(u.avatarUrl || '')
}
useEffect(() => {
loadUser()
}, [])
const handleSaveInfo = () => {
setUserInfo({ ...user, nickName: editName, avatarUrl: editAvatar })
Taro.showToast({ title: '修改成功', icon: 'success' })
setShowEdit(false)
loadUser()
}
const handleLogout = () => {
Taro.showModal({
title: '确认退出',
content: '退出后将清空当前登录状态,确定吗?',
success: (res) => {
if (res.confirm) {
clearUserInfo()
Taro.switchTab({ url: '/pages/index/index' })
}
}
})
}
const onChooseAvatar = (e: any) => {
setEditAvatar(e.detail.avatarUrl || '')
}
return (
<View className={`theme-${resolvedTheme}`} style={{ minHeight: '100vh' }}>
<ThemedPageMeta />
<View className='settings-page'>
<View className='settings-area'>
<View className='page-header dashed-card mt-20' style={{ marginTop: `${safe.headerPaddingTop}px` }}>
<View className='flex-between' style={{ width: '100%' }}>
<Text className='back-btn' onTap={() => Taro.navigateBack()}></Text>
<Text className='page-title'>设置</Text>
<View style={{ width: '60px' }} />
</View>
</View>
{/* 用户卡片 */}
<View className='settings-user dashed-card mt-20'>
<View className='flex-between' onTap={() => setShowEdit(true)}>
<View className='flex-center'>
{user.avatarUrl ? (
<Image className='settings-avatar' src={user.avatarUrl} mode='aspectFill' />
) : (
<View className='settings-avatar-placeholder'>
<Image className='settings-avatar-icon' src='/icon/个人.png' mode='aspectFit' />
</View>
)}
<View style={{ marginLeft: '20px' }}>
<Text className='settings-name'>{user.nickName || '未登录'}</Text>
<Text className='settings-id'>ID: {user.openid ? user.openid.slice(-8) : '---'}</Text>
</View>
</View>
<Text className='arrow'></Text>
</View>
</View>
{/* 主题设置 */}
<View className='settings-section dashed-card mt-20'>
<Text className='section-label'>外观</Text>
<View className='theme-options'>
{THEME_OPTIONS.map(opt => (
<View
key={opt.value}
className={`theme-option ${theme === opt.value ? 'active' : ''}`}
onTap={() => setTheme(opt.value)}
>
<Text className='theme-option-text'>{opt.label}</Text>
{theme === opt.value && <View className='theme-check' />}
</View>
))}
</View>
{theme === 'auto' && (
<Text className='theme-hint'>当前跟随系统:{resolvedTheme === 'dark' ? '深色模式' : '浅色模式'}</Text>
)}
</View>
{/* 菜单列表 */}
<View className='settings-list dashed-card mt-20'>
{MENU.map((item, idx) => (
<View key={idx} className={`settings-item ${idx < MENU.length - 1 ? 'bordered' : ''}`} onTap={() => item.action({ setShowEdit })}>
<Image className='settings-item-icon-img' src={item.icon} mode='aspectFit' />
<Text className='settings-item-label'>{item.label}</Text>
<Text className='arrow'></Text>
</View>
))}
</View>
{/* 退出登录 */}
{user?.openid && (
<View className='mt-20'>
<View className='btn-outline logout-btn' onTap={handleLogout}>
<Text>退出登录</Text>
</View>
</View>
)}
<View style={{ height: '40px' }} />
{/* 编辑弹窗 */}
{showEdit && (
<View className='modal-overlay'>
<View className='modal-card dashed-card'>
<Text className='modal-title'>修改信息</Text>
<Button className='avatar-btn' openType='chooseAvatar' onChooseAvatar={onChooseAvatar}>
{editAvatar ? (
<Image className='avatar-img' src={editAvatar} mode='aspectFill' />
) : (
<Image className='avatar-placeholder-img' src='/icon/个人.png' mode='aspectFit' />
)}
</Button>
<Input
className='nickname-input'
placeholder='请输入昵称'
value={editName}
onInput={(e: any) => setEditName(e.detail.value)}
/>
<View className='form-actions'>
<View className='btn-outline' onTap={() => setShowEdit(false)}>
<Text>取消</Text>
</View>
<View className='btn-gradient' onTap={handleSaveInfo}>
<Text>保存</Text>
</View>
</View>
</View>
</View>
)}
</View>
</View>
</View>
)
}