178 lines
4.4 KiB
TypeScript
178 lines
4.4 KiB
TypeScript
import MaterialIcons from '@expo/vector-icons/MaterialIcons';
|
|
import { router } from 'expo-router';
|
|
import React from 'react';
|
|
import { TouchableOpacity, View } from 'react-native';
|
|
|
|
import { ThemedText } from '@/components/themed-text';
|
|
import { useColorScheme } from '@/hooks/use-color-scheme';
|
|
|
|
type BillingMode = 'monthly' | 'lifetime';
|
|
|
|
const BILLING_OPTIONS: { key: BillingMode; label: string }[] = [
|
|
{ key: 'monthly', label: '月付' },
|
|
];
|
|
|
|
export function ProfileHeader({
|
|
billingMode,
|
|
onChangeBilling,
|
|
credits,
|
|
}: {
|
|
billingMode: BillingMode;
|
|
onChangeBilling: (mode: BillingMode) => void;
|
|
credits: number;
|
|
}) {
|
|
const colorScheme = useColorScheme();
|
|
const palette = colorScheme === 'dark' ? darkPalette : lightPalette;
|
|
|
|
return (
|
|
<View style={styles.headerRow}>
|
|
<TouchableOpacity
|
|
onPress={() => router.push('/settings/account')}
|
|
style={[styles.settingsButton, { backgroundColor: palette.pill }]}
|
|
activeOpacity={0.85}
|
|
>
|
|
<MaterialIcons name="settings" size={24} color={palette.textPrimary} />
|
|
</TouchableOpacity>
|
|
<BillingBadge
|
|
palette={palette}
|
|
billingMode={billingMode}
|
|
onChangeBilling={onChangeBilling}
|
|
credits={credits}
|
|
/>
|
|
</View>
|
|
);
|
|
}
|
|
|
|
function BillingBadge({
|
|
palette,
|
|
billingMode,
|
|
onChangeBilling,
|
|
credits,
|
|
}: {
|
|
palette: any;
|
|
billingMode: BillingMode;
|
|
onChangeBilling: (mode: BillingMode) => void;
|
|
credits: number;
|
|
}) {
|
|
return (
|
|
<View style={[styles.billingShell, { backgroundColor: palette.pill, borderColor: palette.border }]}>
|
|
<View style={styles.billingOptions}>
|
|
{BILLING_OPTIONS.map(option => {
|
|
const isActive = option.key === billingMode;
|
|
return (
|
|
<TouchableOpacity
|
|
key={option.key}
|
|
onPress={() => router.push('/exchange')}
|
|
activeOpacity={0.85}
|
|
style={[
|
|
styles.billingOption,
|
|
{
|
|
backgroundColor: isActive ? palette.tabActive : 'transparent',
|
|
},
|
|
]}
|
|
>
|
|
<ThemedText
|
|
style={[
|
|
styles.billingLabel,
|
|
{
|
|
color: isActive ? palette.onAccent : palette.textSecondary,
|
|
},
|
|
]}
|
|
>
|
|
{option.label}
|
|
</ThemedText>
|
|
</TouchableOpacity>
|
|
);
|
|
})}
|
|
</View>
|
|
<TouchableOpacity
|
|
onPress={() => router.push('/exchange')}
|
|
activeOpacity={0.85}
|
|
style={[
|
|
styles.lightningShell,
|
|
{
|
|
backgroundColor: palette.elevated,
|
|
borderColor: palette.border,
|
|
},
|
|
]}
|
|
>
|
|
<MaterialIcons name="flash-on" size={16} color={palette.accent} />
|
|
<ThemedText style={[styles.lightningValue, { color: palette.textPrimary }]}>{credits}</ThemedText>
|
|
</TouchableOpacity>
|
|
</View>
|
|
);
|
|
}
|
|
|
|
const darkPalette = {
|
|
pill: '#16171C',
|
|
border: '#1D1E24',
|
|
tabActive: '#FFFFFF',
|
|
onAccent: '#050505',
|
|
textSecondary: '#8E9098',
|
|
textPrimary: '#F6F7FA',
|
|
accent: '#B7FF2F',
|
|
elevated: '#101014',
|
|
};
|
|
|
|
const lightPalette = {
|
|
pill: '#E8EBF4',
|
|
border: '#E2E5ED',
|
|
tabActive: '#FFFFFF',
|
|
onAccent: '#FFFFFF',
|
|
textSecondary: '#5E6474',
|
|
textPrimary: '#0F1320',
|
|
accent: '#405CFF',
|
|
elevated: '#F0F2F8',
|
|
};
|
|
|
|
const styles = {
|
|
headerRow: {
|
|
flexDirection: 'row' as const,
|
|
alignItems: 'center' as const,
|
|
justifyContent: 'space-between' as const,
|
|
marginBottom: 14,
|
|
marginTop: 14
|
|
},
|
|
settingsButton: {
|
|
width: 44,
|
|
height: 44,
|
|
borderRadius: 22,
|
|
alignItems: 'center' as const,
|
|
justifyContent: 'center' as const,
|
|
},
|
|
billingShell: {
|
|
flexDirection: 'row' as const,
|
|
alignItems: 'center' as const,
|
|
padding: 4,
|
|
borderWidth: 1,
|
|
borderRadius: 999,
|
|
},
|
|
billingOptions: {
|
|
flexDirection: 'row' as const,
|
|
alignItems: 'center' as const,
|
|
},
|
|
billingOption: {
|
|
paddingHorizontal: 16,
|
|
paddingVertical: 6,
|
|
borderRadius: 999,
|
|
},
|
|
billingLabel: {
|
|
fontSize: 13,
|
|
fontWeight: '600' as const,
|
|
},
|
|
lightningShell: {
|
|
flexDirection: 'row' as const,
|
|
alignItems: 'center' as const,
|
|
borderWidth: 1,
|
|
borderRadius: 999,
|
|
paddingHorizontal: 12,
|
|
paddingVertical: 6,
|
|
marginLeft: 8,
|
|
},
|
|
lightningValue: {
|
|
fontSize: 13,
|
|
fontWeight: '600' as const,
|
|
marginLeft: 6,
|
|
},
|
|
};
|