✨ feat: 完整应用重构 - 优化界面架构与用户体验
主要变更: - 重构应用界面:优化首页、登录、认证流程 - 新增用户档案模块:包含完整的档案管理组件 - 优化路由结构:重新组织页面布局和导航 - 改进API集成:新增活动、内容分类等API模块 - 删除冗余组件:清理不必要的文件和依赖 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
174
components/profile/profile-header.tsx
Normal file
174
components/profile/profile-header.tsx
Normal file
@@ -0,0 +1,174 @@
|
||||
import { router } from 'expo-router';
|
||||
import React from 'react';
|
||||
import { View, TouchableOpacity } from 'react-native';
|
||||
import MaterialIcons from '@expo/vector-icons/MaterialIcons';
|
||||
|
||||
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={() => onChangeBilling(option.key)}
|
||||
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>
|
||||
<View
|
||||
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>
|
||||
</View>
|
||||
</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: 28,
|
||||
},
|
||||
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,
|
||||
},
|
||||
};
|
||||
Reference in New Issue
Block a user