297 lines
7.2 KiB
TypeScript
297 lines
7.2 KiB
TypeScript
|
|
/**
|
|||
|
|
* 左侧菜单组件
|
|||
|
|
* 基于 react-native-paper Drawer 组件重建
|
|||
|
|
* 功能包括:
|
|||
|
|
* - 用户钱包信息
|
|||
|
|
* - 菜单项导航
|
|||
|
|
* - 利息宝显示
|
|||
|
|
* - 登录状态判断
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
import React, { useState, useCallback, useMemo } from 'react';
|
|||
|
|
import { View, Text, ScrollView, Modal, TouchableOpacity, Dimensions } from 'react-native';
|
|||
|
|
import { Drawer, Button, Divider } from 'react-native-paper';
|
|||
|
|
import { useColorScheme, useThemeColors } from '@/theme';
|
|||
|
|
import { createThemeStyles } from '@/theme';
|
|||
|
|
import { useIsLoggedIn, useUser } from '@/stores';
|
|||
|
|
import Ionicons from '@expo/vector-icons/Ionicons';
|
|||
|
|
import WalletAmount from '../WalletAmount';
|
|||
|
|
|
|||
|
|
const { width } = Dimensions.get('window');
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 创建主题样式
|
|||
|
|
*/
|
|||
|
|
const styles = createThemeStyles((colors) => ({
|
|||
|
|
overlay: {
|
|||
|
|
flex: 1,
|
|||
|
|
backgroundColor: 'rgba(0, 0, 0, 0.5)',
|
|||
|
|
},
|
|||
|
|
drawerContainer: {
|
|||
|
|
flex: 1,
|
|||
|
|
backgroundColor: colors.background,
|
|||
|
|
width: width * 0.65,
|
|||
|
|
position: 'absolute',
|
|||
|
|
top: 0,
|
|||
|
|
left: 0,
|
|||
|
|
right: 0,
|
|||
|
|
bottom: 0,
|
|||
|
|
},
|
|||
|
|
container: {
|
|||
|
|
flex: 1,
|
|||
|
|
backgroundColor: colors.background,
|
|||
|
|
},
|
|||
|
|
walletSection: {
|
|||
|
|
paddingHorizontal: 16,
|
|||
|
|
paddingVertical: 16,
|
|||
|
|
backgroundColor: colors.card,
|
|||
|
|
marginHorizontal: 12,
|
|||
|
|
marginVertical: 12,
|
|||
|
|
borderRadius: 12,
|
|||
|
|
},
|
|||
|
|
walletLabel: {
|
|||
|
|
fontSize: 12,
|
|||
|
|
color: colors.text + '80',
|
|||
|
|
marginBottom: 8,
|
|||
|
|
},
|
|||
|
|
walletButtons: {
|
|||
|
|
flexDirection: 'row',
|
|||
|
|
gap: 8,
|
|||
|
|
marginTop: 12,
|
|||
|
|
},
|
|||
|
|
buttonText: {
|
|||
|
|
fontSize: 12,
|
|||
|
|
fontWeight: '600',
|
|||
|
|
},
|
|||
|
|
lixibaoSection: {
|
|||
|
|
marginHorizontal: 12,
|
|||
|
|
marginVertical: 12,
|
|||
|
|
paddingHorizontal: 12,
|
|||
|
|
paddingVertical: 12,
|
|||
|
|
borderRadius: 12,
|
|||
|
|
borderWidth: 2,
|
|||
|
|
borderColor: colors.primary,
|
|||
|
|
backgroundColor: colors.card,
|
|||
|
|
flexDirection: 'row',
|
|||
|
|
alignItems: 'center',
|
|||
|
|
justifyContent: 'space-between',
|
|||
|
|
},
|
|||
|
|
lixibaoLeft: {
|
|||
|
|
flexDirection: 'row',
|
|||
|
|
alignItems: 'center',
|
|||
|
|
flex: 1,
|
|||
|
|
},
|
|||
|
|
lixibaoInfo: {
|
|||
|
|
flex: 1,
|
|||
|
|
},
|
|||
|
|
lixibaoLabel: {
|
|||
|
|
fontSize: 12,
|
|||
|
|
color: colors.text + '80',
|
|||
|
|
},
|
|||
|
|
lixibaoValue: {
|
|||
|
|
fontSize: 14,
|
|||
|
|
fontWeight: '700',
|
|||
|
|
color: colors.primary,
|
|||
|
|
marginTop: 4,
|
|||
|
|
},
|
|||
|
|
emptyText: {
|
|||
|
|
textAlign: 'center',
|
|||
|
|
fontSize: 14,
|
|||
|
|
color: colors.text + '80',
|
|||
|
|
paddingVertical: 40,
|
|||
|
|
},
|
|||
|
|
}));
|
|||
|
|
|
|||
|
|
interface LeftMenuProps {
|
|||
|
|
visible: boolean;
|
|||
|
|
onClose: () => void;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
interface MenuItem {
|
|||
|
|
id: string;
|
|||
|
|
title: string;
|
|||
|
|
icon: string;
|
|||
|
|
route?: string;
|
|||
|
|
requireLogin?: boolean;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 左侧菜单组件
|
|||
|
|
*/
|
|||
|
|
export default function LeftMenu({ visible, onClose }: LeftMenuProps) {
|
|||
|
|
const colorScheme = useColorScheme();
|
|||
|
|
const s = styles[colorScheme];
|
|||
|
|
const themeColors = useThemeColors();
|
|||
|
|
const isLoggedIn = useIsLoggedIn();
|
|||
|
|
const user = useUser();
|
|||
|
|
|
|||
|
|
const [walletBalance] = useState(0); // 从 store 获取
|
|||
|
|
const [interestBalance] = useState(0); // 从 store 获取
|
|||
|
|
|
|||
|
|
// 菜单项配置
|
|||
|
|
const menuItems: MenuItem[] = useMemo(
|
|||
|
|
() => [
|
|||
|
|
{ id: 'balance', title: '利息宝', icon: 'gift' },
|
|||
|
|
{
|
|||
|
|
id: 'services',
|
|||
|
|
title: '客服',
|
|||
|
|
icon: 'headset',
|
|||
|
|
route: '/services',
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
id: 'collect',
|
|||
|
|
title: '收藏',
|
|||
|
|
icon: 'star',
|
|||
|
|
route: '/collect',
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
id: 'recent',
|
|||
|
|
title: '最近',
|
|||
|
|
icon: 'time',
|
|||
|
|
route: '/recent',
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
id: 'betRecord',
|
|||
|
|
title: '投注记录',
|
|||
|
|
icon: 'document-text',
|
|||
|
|
route: '/betRecord',
|
|||
|
|
requireLogin: true,
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
id: 'activity',
|
|||
|
|
title: '任务中心',
|
|||
|
|
icon: 'checkmark-circle',
|
|||
|
|
route: '/activity',
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
id: 'bonus',
|
|||
|
|
title: '福利中心',
|
|||
|
|
icon: 'gift',
|
|||
|
|
route: '/bonus',
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
id: 'rebate',
|
|||
|
|
title: '自助返水',
|
|||
|
|
icon: 'cash',
|
|||
|
|
route: '/rebate',
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
id: 'findBalance',
|
|||
|
|
title: '找回余额',
|
|||
|
|
icon: 'search',
|
|||
|
|
route: '/findBalance',
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
id: 'message',
|
|||
|
|
title: '消息中心',
|
|||
|
|
icon: 'mail',
|
|||
|
|
route: '/message',
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
id: 'promotion',
|
|||
|
|
title: '推广赚钱',
|
|||
|
|
icon: 'share-social',
|
|||
|
|
route: '/promotion',
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
id: 'backup',
|
|||
|
|
title: '备用网站',
|
|||
|
|
icon: 'link',
|
|||
|
|
route: '/backup',
|
|||
|
|
},
|
|||
|
|
],
|
|||
|
|
[]
|
|||
|
|
);
|
|||
|
|
|
|||
|
|
const handleMenuItemPress = useCallback(
|
|||
|
|
(item: MenuItem) => {
|
|||
|
|
if (item.requireLogin && !isLoggedIn) {
|
|||
|
|
// 显示登录提示
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
// 导航到对应页面
|
|||
|
|
console.log('Navigate to:', item.route);
|
|||
|
|
onClose();
|
|||
|
|
},
|
|||
|
|
[isLoggedIn, onClose]
|
|||
|
|
);
|
|||
|
|
|
|||
|
|
const handleDeposit = useCallback(() => {
|
|||
|
|
console.log('Navigate to deposit');
|
|||
|
|
onClose();
|
|||
|
|
}, [onClose]);
|
|||
|
|
|
|||
|
|
const handleWithdraw = useCallback(() => {
|
|||
|
|
console.log('Navigate to withdraw');
|
|||
|
|
onClose();
|
|||
|
|
}, [onClose]);
|
|||
|
|
|
|||
|
|
return (
|
|||
|
|
<Modal visible={visible} transparent animationType="fade" onRequestClose={onClose}>
|
|||
|
|
<View style={s.overlay}>
|
|||
|
|
<TouchableOpacity style={{ flex: 1 }} activeOpacity={1} onPress={onClose} />
|
|||
|
|
<View style={s.drawerContainer}>
|
|||
|
|
<ScrollView showsVerticalScrollIndicator={false}>
|
|||
|
|
{/* 用户信息或登录提示 */}
|
|||
|
|
{isLoggedIn && user ? (
|
|||
|
|
<>
|
|||
|
|
{/* 钱包信息 */}
|
|||
|
|
<View style={s.walletSection}>
|
|||
|
|
<Text style={s.walletLabel}>钱包余额</Text>
|
|||
|
|
<WalletAmount balance={walletBalance} />
|
|||
|
|
<View style={s.walletButtons}>
|
|||
|
|
<Button
|
|||
|
|
mode="contained"
|
|||
|
|
onPress={handleDeposit}
|
|||
|
|
style={{ flex: 1 }}
|
|||
|
|
labelStyle={s.buttonText}
|
|||
|
|
>
|
|||
|
|
充值
|
|||
|
|
</Button>
|
|||
|
|
<Button
|
|||
|
|
mode="outlined"
|
|||
|
|
onPress={handleWithdraw}
|
|||
|
|
style={{ flex: 1 }}
|
|||
|
|
labelStyle={s.buttonText}
|
|||
|
|
>
|
|||
|
|
提现
|
|||
|
|
</Button>
|
|||
|
|
</View>
|
|||
|
|
</View>
|
|||
|
|
</>
|
|||
|
|
) : (
|
|||
|
|
<Text style={s.emptyText}>加入我们,开启畅赢人生!</Text>
|
|||
|
|
)}
|
|||
|
|
|
|||
|
|
<Divider style={{ marginVertical: 8 }} />
|
|||
|
|
|
|||
|
|
{/* 菜单项 */}
|
|||
|
|
<Drawer.Section title="">
|
|||
|
|
{menuItems.map((item) => (
|
|||
|
|
<Drawer.Item
|
|||
|
|
key={item.id}
|
|||
|
|
label={item.title}
|
|||
|
|
icon={({ color, size }) => (
|
|||
|
|
<Ionicons name={item.icon as any} size={size} color={color} />
|
|||
|
|
)}
|
|||
|
|
onPress={() => handleMenuItemPress(item)}
|
|||
|
|
active={false}
|
|||
|
|
right={() => (
|
|||
|
|
<Ionicons
|
|||
|
|
name="chevron-forward"
|
|||
|
|
size={20}
|
|||
|
|
color={themeColors.text + '60'}
|
|||
|
|
style={{ marginRight: -10 }}
|
|||
|
|
/>
|
|||
|
|
)}
|
|||
|
|
style={{ marginHorizontal: 0 }}
|
|||
|
|
/>
|
|||
|
|
))}
|
|||
|
|
</Drawer.Section>
|
|||
|
|
</ScrollView>
|
|||
|
|
</View>
|
|||
|
|
</View>
|
|||
|
|
</Modal>
|
|||
|
|
);
|
|||
|
|
}
|