import { useState, useRef, useMemo, useCallback, useEffect } from 'react' import { View, Text, StyleSheet, ScrollView, Pressable, useWindowDimensions, } from 'react-native' import { LinearGradient } from 'expo-linear-gradient' import { useSafeAreaInsets } from 'react-native-safe-area-context' import { useTranslation } from 'react-i18next' import BottomSheet, { BottomSheetView, BottomSheetBackdrop, BottomSheetScrollView } from '@gorhom/bottom-sheet' import { CloseIcon } from '@/components/icon' import TopUpDrawer, { TopUpOption } from '@/components/drawer/TopUpDrawer' export type PointsTabType = 'all' | 'consume' | 'obtain' export interface PointsTransaction { id: string title: string date: string points: number // 正数表示获得,负数表示消耗 } export interface PointsDrawerProps { /** * 是否显示抽屉 */ visible: boolean /** * 关闭回调 */ onClose: () => void /** * 当前积分总额 */ totalPoints?: number /** * 订阅积分 */ subscriptionPoints?: number /** * 额外充值积分 */ topUpPoints?: number /** * 交易记录列表 */ transactions?: PointsTransaction[] } export default function PointsDrawer({ visible, onClose, totalPoints = 60, subscriptionPoints = 0, topUpPoints = 0, transactions = [], }: PointsDrawerProps) { const { t } = useTranslation() const { height: screenHeight } = useWindowDimensions() const insets = useSafeAreaInsets() const bottomSheetRef = useRef(null) const [pointsTab, setPointsTab] = useState('all') const [topUpDrawerVisible, setTopUpDrawerVisible] = useState(false) const snapPoints = useMemo(() => [screenHeight * 0.85], [screenHeight]) useEffect(() => { if (visible) { bottomSheetRef.current?.expand() } else { bottomSheetRef.current?.close() } }, [visible]) const handleSheetChanges = useCallback((index: number) => { if (index === -1) { onClose() } }, [onClose]) const renderBackdrop = useCallback( (props: any) => ( ), [] ) // 标签页配置 const tabOptions: Array<{ value: PointsTabType; label: string }> = [ { value: 'all', label: t('pointsDrawer.all') }, { value: 'consume', label: t('pointsDrawer.consume') }, { value: 'obtain', label: t('pointsDrawer.obtain') }, ] // 根据标签页过滤交易记录 const filteredTransactions = transactions.filter((transaction) => { if (pointsTab === 'all') return true if (pointsTab === 'consume') return transaction.points < 0 if (pointsTab === 'obtain') return transaction.points > 0 return true }) // 如果没有提供交易记录,使用示例数据 const displayTransactions = filteredTransactions.length > 0 ? filteredTransactions : [ { id: '1', title: t('pointsDrawer.dailyFreePoints'), date: '2025年11月28日 10:33', points: 60, }, ...Array.from({ length: 60 }, (_, i) => ({ id: `example-${i + 2}`, title: t('pointsDrawer.dailyFreePoints'), date: '2025年11月28日 10:33', points: -60, })), ] return ( {/* 顶部标题栏 */} {t('pointsDrawer.title')} {/* 积分总额 */} {totalPoints} {/* 积分类型细分 */} {t('pointsDrawer.subscriptionPoints')} {subscriptionPoints} {t('pointsDrawer.topUpPoints')} {topUpPoints} {/* 标签页 */} {tabOptions.map((tab) => { const isActive = pointsTab === tab.value return ( setPointsTab(tab.value)} > {isActive && ( )} {tab.label} ) })} {/* 交易历史列表 */} {displayTransactions.map((transaction) => ( {transaction.title} {transaction.date} {transaction.points > 0 ? '+' : ''} {transaction.points} ))} {/* 底部按钮 */} { onClose() }} > {t('pointsDrawer.subscribeForPoints')} { setTopUpDrawerVisible(true) }} > {t('pointsDrawer.topUpPointsButton')} {/* 充值抽屉 */} setTopUpDrawerVisible(false)} onNavigate={() => { setTopUpDrawerVisible(false) onClose() }} requiredPoints={100} remainingPoints={totalPoints} topUpTitle={t('topUp.title')} onConfirm={(option: TopUpOption) => { // 处理充值确认逻辑 console.log('确认充值:', option) setTopUpDrawerVisible(false) }} /> ) } const styles = StyleSheet.create({ bottomSheetBackground: { backgroundColor: '#090A0B', borderTopLeftRadius: 24, borderTopRightRadius: 24, }, handleIndicator: { backgroundColor: '#666666', }, container: { flex: 1, backgroundColor: '#090A0B', borderTopLeftRadius: 20, borderTopRightRadius: 20, overflow: 'hidden', }, header: { flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between', paddingTop: 12, marginRight: 12, }, titleContainer: { paddingLeft: 20, marginTop: -4, borderBottomWidth: 1, borderBottomColor: '#3A3A3A', }, title: { color: '#F5F5F5', fontSize: 12, fontWeight: '500', }, closeButton: { width: 24, height: 24, alignItems: 'center', justifyContent: 'center', }, balance: { marginBottom: 13, }, balanceValue: { color: '#F5F5F5', fontSize: 40, fontWeight: '500', }, breakdown: { flexDirection: 'row', gap: 16, marginBottom: 24, }, breakdownText: { color: '#ABABAB', fontSize: 12, fontWeight: '400', }, breakdownTextValue: { color: '#F5F5F5', fontSize: 12, fontWeight: '500', marginLeft: 6, }, breakdownTextSeparator: { width: 1, height: 14, backgroundColor: '#3A3A3A', marginTop: 2, }, tabs: { flexDirection: 'row', alignItems: 'center', paddingHorizontal: 16, marginTop:20, marginBottom:24, }, tab: { flex: 1, alignItems: 'center', justifyContent: 'center', }, tabContent: { position: 'relative', alignSelf: 'center', }, tabGradient: { position: 'absolute', left: 0, right: 0, bottom: 0, height: 10, backgroundColor: '#FF9966', }, tabText: { color: '#ABABAB', fontSize: 14, textAlign: 'center', }, tabTextActive: { color: '#F5F5F5', fontSize: 14, textAlign: 'center', }, list: { height: 400, }, listContent: { paddingBottom: 16, paddingHorizontal: 16, }, item: { flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', paddingVertical: 16, borderBottomWidth: 1, borderBottomColor: '#1C1E20', }, itemLeft: { flex: 1, }, itemTitle: { color: '#F5F5F5', fontSize: 14, fontWeight: '500', marginBottom: 4, }, itemDate: { color: '#ABABAB', fontSize: 12, fontWeight: '400', }, itemPoints: { color: '#4CAF50', fontSize: 16, fontWeight: '600', }, itemPointsNegative: { color: '#F5F5F5', }, footer: { paddingTop: 20, paddingHorizontal: 16, gap: 4, }, subscribeButton: { width: '100%', height: 48, borderRadius: 12, overflow: 'hidden', }, subscribeButtonGradient: { width: '100%', height: 48, alignItems: 'center', justifyContent: 'center', borderRadius: 12, }, subscribeButtonText: { color: '#F5F5F5', fontSize: 16, fontWeight: '500', }, topUpButton: { alignItems: 'center', justifyContent: 'center', paddingVertical: 12, }, topUpButtonText: { color: '#F5F5F5', fontSize: 12, fontWeight: '400', }, })