144 lines
4.6 KiB
TypeScript
144 lines
4.6 KiB
TypeScript
import { Ionicons } from '@expo/vector-icons'
|
|
import { Block, ConfirmModal, Img, Text, Toast } from '@share/components'
|
|
import { router, Stack } from 'expo-router'
|
|
import { observer } from 'mobx-react-lite'
|
|
import React from 'react'
|
|
import { ScrollView } from 'react-native'
|
|
|
|
import { userStore } from '@/stores'
|
|
|
|
type MenuItem = {
|
|
id: string
|
|
label: string
|
|
icon: keyof typeof Ionicons.glyphMap
|
|
onPress: () => void
|
|
}
|
|
|
|
export default observer(function SettingsPage() {
|
|
const { user, isAuthenticated, signOut } = userStore
|
|
|
|
const handleLogout = () => {
|
|
Toast.showModal(
|
|
<ConfirmModal
|
|
title="退出登录"
|
|
content="确定要退出登录吗?"
|
|
onCancel={Toast.hideModal}
|
|
onConfirm={async () => {
|
|
await signOut()
|
|
Toast.show({ title: '已退出登录' })
|
|
router.replace('/(tabs)')
|
|
// 关闭modal
|
|
Toast.hideModal()
|
|
}}
|
|
/>,
|
|
)
|
|
}
|
|
|
|
const menuItems: MenuItem[] = [
|
|
{
|
|
id: 'service',
|
|
label: '服务条款',
|
|
icon: 'document-text-outline',
|
|
onPress: () => {
|
|
router.push({
|
|
pathname: '/service',
|
|
params: { type: 'terms', title: '服务条款' },
|
|
})
|
|
},
|
|
},
|
|
{
|
|
id: 'privacy',
|
|
label: '隐私协议',
|
|
icon: 'shield-outline',
|
|
onPress: () => {
|
|
router.push({
|
|
pathname: '/privacy',
|
|
params: { type: 'privacy', title: '隐私协议' },
|
|
})
|
|
},
|
|
},
|
|
// {
|
|
// id: 'about',
|
|
// label: '关于我们',
|
|
// icon: 'information-circle-outline',
|
|
// onPress: () => {
|
|
// // TODO: 替换为实际的关于我们URL或创建关于页面
|
|
// router.push({
|
|
// pathname: '/webview',
|
|
// params: { url: 'https://example.com/about', title: '关于我们' },
|
|
// })
|
|
// },
|
|
// },
|
|
]
|
|
|
|
const handleUserProfileClick = () => {
|
|
router.push('/profile')
|
|
}
|
|
|
|
const renderHeader = () => (
|
|
<Block className="flex-row items-center justify-between px-[16px] py-[10px]">
|
|
<Block className="ml-[-8px] size-[40px] items-center justify-center" opacity={0.7} onClick={() => router.back()}>
|
|
<Ionicons color="#323232" name="chevron-back" size={24} />
|
|
</Block>
|
|
<Text className="text-[16px] font-[700] text-[#323232]">设置</Text>
|
|
<Block className="w-[32px]" />
|
|
</Block>
|
|
)
|
|
|
|
const renderUserSection = () => (
|
|
<Block className="flex-row items-center gap-[12px] px-[16px] py-[10px]" onClick={handleUserProfileClick}>
|
|
<Block className="size-[68px] items-center justify-center overflow-hidden rounded-full bg-gray-200">
|
|
{user?.image ? (
|
|
<Img src={user.image} style={{ width: 68, height: 68, borderRadius: 30 }} width={68} />
|
|
) : (
|
|
<Ionicons color="#9CA3AF" name="person" size={32} />
|
|
)}
|
|
</Block>
|
|
<Block className="flex-1">
|
|
<Text className="text-[16px] font-[700] text-[#323232]">{user?.name || user?.phoneNumber || '未登录'}</Text>
|
|
{(user?.phoneNumber || (user?.email && user?.emailVerified)) && user?.name && (
|
|
<Text className="mt-[4px] text-[12px] text-[#9D9D9D]">{user.phoneNumber || user.email}</Text>
|
|
)}
|
|
</Block>
|
|
<Ionicons color="#323232" name="chevron-forward" size={20} />
|
|
</Block>
|
|
)
|
|
|
|
const renderMenuSection = () => (
|
|
<Block className="mt-[8px]">
|
|
<Text className="px-[20px] py-[8px] text-[12px] text-[#9D9D9D]">使用相关</Text>
|
|
<Block className="mx-[16px] rounded-xl bg-white">
|
|
{menuItems.map((item) => (
|
|
<Block key={item.id}>
|
|
<Block className="flex-row items-center gap-[12px] p-[16px]" onClick={item.onPress}>
|
|
<Ionicons color="#323232" name={item.icon} size={22} />
|
|
<Text className="flex-1 text-[14px] text-[#323232]">{item.label}</Text>
|
|
<Ionicons color="#9D9D9D" name="chevron-forward" size={20} />
|
|
</Block>
|
|
</Block>
|
|
))}
|
|
</Block>
|
|
</Block>
|
|
)
|
|
|
|
const renderLogoutButton = () => (
|
|
<Block className="mt-[40px] items-center px-[16px]">
|
|
<Block className="w-full items-center justify-center rounded-xl bg-white py-[14px]" onClick={handleLogout}>
|
|
<Text className="text-[14px] font-[600] text-[#323232]">退出登录</Text>
|
|
</Block>
|
|
</Block>
|
|
)
|
|
|
|
return (
|
|
<Block className="h-full flex-1 bg-[#fafafa]">
|
|
<Stack.Screen options={{ headerShown: false }} />
|
|
{renderHeader()}
|
|
<ScrollView contentContainerStyle={{ flexGrow: 1 }} showsVerticalScrollIndicator={false}>
|
|
{renderUserSection()}
|
|
{renderMenuSection()}
|
|
{renderLogoutButton()}
|
|
</ScrollView>
|
|
</Block>
|
|
)
|
|
})
|