This commit is contained in:
imeepos 2025-11-12 16:50:51 +08:00
parent daf9cca667
commit 12a1df8481
2 changed files with 15 additions and 56 deletions

View File

@ -1,3 +1,5 @@
import { useBalance } from '@/hooks/use-balance';
import { usePricing } from '@/hooks/use-pricing';
import Ionicons from '@expo/vector-icons/Ionicons'; import Ionicons from '@expo/vector-icons/Ionicons';
import { useRouter } from 'expo-router'; import { useRouter } from 'expo-router';
import React, { useCallback, useMemo, useState } from 'react'; import React, { useCallback, useMemo, useState } from 'react';
@ -12,8 +14,6 @@ import {
View View
} from 'react-native'; } from 'react-native';
import { useSafeAreaInsets } from 'react-native-safe-area-context'; import { useSafeAreaInsets } from 'react-native-safe-area-context';
import { useBalance } from '@/hooks/use-balance';
import { usePricing } from '@/hooks/use-pricing';
type PurchaseTab = 'subscription' | 'pack'; type PurchaseTab = 'subscription' | 'pack';
@ -44,19 +44,14 @@ const TABS: { key: PurchaseTab; label: string }[] = [
{ key: 'pack', label: 'points pack' }, { key: 'pack', label: 'points pack' },
]; ];
const POINT_BUNDLES: PointsBundle[] = [ const POINT_BUNDLES: PointsBundle[] = [];
{ id: 'bundle-500', points: 500, price: 35 },
{ id: 'bundle-2000', points: 2000, price: 140 },
{ id: 'bundle-5000', points: 5000, price: 350 },
{ id: 'bundle-10000', points: 10000, price: 700 },
];
export default function PointsExchangeScreen() { export default function PointsExchangeScreen() {
const router = useRouter(); const router = useRouter();
const insets = useSafeAreaInsets(); const insets = useSafeAreaInsets();
const [activeTab, setActiveTab] = useState<PurchaseTab>('subscription'); const [activeTab, setActiveTab] = useState<PurchaseTab>('subscription');
const [selectedBundleId, setSelectedBundleId] = useState<string | null>(null); const [selectedBundleId, setSelectedBundleId] = useState<string | null>(null);
const [selectedSubscriptionIndex, setSelectedSubscriptionIndex] = useState<number | null>(null); const [selectedSubscriptionIndex, setSelectedSubscriptionIndex] = useState<number | null>(0);
const [customAmount, setCustomAmount] = useState<string>('500'); const [customAmount, setCustomAmount] = useState<string>('500');
const { balance, isLoading: isBalanceLoading, refresh } = useBalance(); const { balance, isLoading: isBalanceLoading, refresh } = useBalance();
@ -139,26 +134,14 @@ export default function PointsExchangeScreen() {
] ]
); );
} else { } else {
console.log(`自定义数量`, customAmount)
// 自定义数量 // 自定义数量
const amount = parseInt(customAmount, 10); const amount = parseInt(customAmount, 10);
if (isNaN(amount) || amount < 500) { if (isNaN(amount) || amount < 0) {
Alert.alert('Invalid Amount', 'Please enter a valid amount (minimum 500 points).'); Alert.alert('Invalid Amount', 'Please enter a valid amount (minimum 500 points).');
return; return;
} }
rechargeToken(amount);
Alert.alert(
'Confirm purchase',
`You are purchasing ${amount} points.`,
[
{ text: 'Cancel', style: 'cancel' },
{
text: 'Confirm',
onPress: () => {
rechargeToken(amount);
},
},
]
);
} }
} }
}, [ }, [
@ -369,7 +352,6 @@ export default function PointsExchangeScreen() {
{/* 自定义金额输入 */} {/* 自定义金额输入 */}
<View style={styles.customAmountContainer}> <View style={styles.customAmountContainer}>
<Text style={styles.customAmountLabel}>Or enter custom amount:</Text>
<TextInput <TextInput
style={styles.customAmountInput} style={styles.customAmountInput}
value={customAmount} value={customAmount}
@ -658,36 +640,6 @@ const styles = StyleSheet.create({
color: screenPalette.secondaryText, color: screenPalette.secondaryText,
fontWeight: '500', fontWeight: '500',
}, },
subscriptionCreditsContainer: {
flexDirection: 'row',
alignItems: 'center',
gap: 6,
marginBottom: 16,
},
subscriptionCredits: {
fontSize: 14,
fontWeight: '600',
color: screenPalette.primaryText,
},
subscriptionFeatures: {
gap: 8,
},
featureItem: {
flexDirection: 'row',
alignItems: 'flex-start',
gap: 8,
},
featureBullet: {
fontSize: 16,
color: screenPalette.accent,
lineHeight: 20,
},
featureText: {
flex: 1,
fontSize: 13,
color: screenPalette.secondaryText,
lineHeight: 20,
},
popularBadge: { popularBadge: {
backgroundColor: screenPalette.button, backgroundColor: screenPalette.button,
paddingHorizontal: 12, paddingHorizontal: 12,

View File

@ -261,8 +261,15 @@ export function usePricing() {
return null; return null;
} }
// 检查 pricing data 是否加载完成
if (!stripePricingData?.pricing_table_items?.[0]?.metered_price_id) { if (!stripePricingData?.pricing_table_items?.[0]?.metered_price_id) {
Alert.alert('Error', 'Pricing data not available'); Alert.alert('Error', 'Pricing data not available. Please try again later.');
return null;
}
// 检查用户是否有 metered subscription
if (!meteredSubscriptions || meteredSubscriptions.length === 0 || !meteredSubscriptions[0]?.priceId) {
Alert.alert('Error', 'No active metered subscription found. Please contact support.');
return null; return null;
} }