import { ThemedText } from '@/components/ThemedText'; import { ThemedView } from '@/components/ThemedView'; import { useColorScheme } from '@/hooks/useColorScheme'; import { useThemeColor } from '@/hooks/useThemeColor'; import AsyncStorage from '@react-native-async-storage/async-storage'; import { router } from 'expo-router'; import React, { useState } from 'react'; import { Alert, Dimensions, ScrollView, StatusBar, StyleSheet, Text, TextInput, TouchableOpacity, View, } from 'react-native'; const { width } = Dimensions.get('window'); interface PersonalInfo { gender: 'male' | 'female' | ''; age: string; height: string; weight: string; } export default function PersonalInfoScreen() { const colorScheme = useColorScheme(); const backgroundColor = useThemeColor({}, 'background'); const primaryColor = useThemeColor({}, 'primary'); const textColor = useThemeColor({}, 'text'); const iconColor = useThemeColor({}, 'icon'); const [personalInfo, setPersonalInfo] = useState({ gender: '', age: '', height: '', weight: '', }); const [currentStep, setCurrentStep] = useState(0); const steps = [ { title: '请选择您的性别', subtitle: '这将帮助我们为您制定更合适的训练计划', type: 'gender' as const, }, { title: '请输入您的年龄', subtitle: '年龄信息有助于调整训练强度', type: 'age' as const, }, { title: '请输入您的身高', subtitle: '身高信息用于计算身体比例', type: 'height' as const, }, { title: '请输入您的体重', subtitle: '体重信息用于个性化训练方案', type: 'weight' as const, }, ]; const handleGenderSelect = (gender: 'male' | 'female') => { setPersonalInfo(prev => ({ ...prev, gender })); }; const handleInputChange = (field: keyof PersonalInfo, value: string) => { setPersonalInfo(prev => ({ ...prev, [field]: value })); }; const handleNext = () => { const currentStepType = steps[currentStep].type; // 验证当前步骤是否已填写 if (currentStepType === 'gender' && !personalInfo.gender) { Alert.alert('提示', '请选择您的性别'); return; } if (currentStepType === 'age' && !personalInfo.age) { Alert.alert('提示', '请输入您的年龄'); return; } if (currentStepType === 'height' && !personalInfo.height) { Alert.alert('提示', '请输入您的身高'); return; } if (currentStepType === 'weight' && !personalInfo.weight) { Alert.alert('提示', '请输入您的体重'); return; } if (currentStep < steps.length - 1) { setCurrentStep(currentStep + 1); } else { handleComplete(); } }; const handlePrevious = () => { if (currentStep > 0) { setCurrentStep(currentStep - 1); } }; const handleSkip = async () => { try { await AsyncStorage.setItem('@onboarding_completed', 'true'); router.replace('/(tabs)'); } catch (error) { console.error('保存引导状态失败:', error); router.replace('/(tabs)'); } }; const handleComplete = async () => { try { // 保存用户信息和引导完成状态 await AsyncStorage.multiSet([ ['@onboarding_completed', 'true'], ['@user_personal_info', JSON.stringify(personalInfo)], ]); console.log('用户信息:', personalInfo); router.replace('/(tabs)'); } catch (error) { console.error('保存用户信息失败:', error); router.replace('/(tabs)'); } }; const renderGenderSelection = () => ( handleGenderSelect('female')} > 👩 女性 handleGenderSelect('male')} > 👨 男性 ); const renderNumberInput = ( field: 'age' | 'height' | 'weight', placeholder: string, unit: string ) => ( handleInputChange(field, value)} placeholder={placeholder} placeholderTextColor={iconColor} keyboardType="numeric" maxLength={field === 'age' ? 3 : 4} /> {unit} ); const renderStepContent = () => { const step = steps[currentStep]; switch (step.type) { case 'gender': return renderGenderSelection(); case 'age': return renderNumberInput('age', '请输入年龄', '岁'); case 'height': return renderNumberInput('height', '请输入身高', 'cm'); case 'weight': return renderNumberInput('weight', '请输入体重', 'kg'); default: return null; } }; const isStepCompleted = () => { const currentStepType = steps[currentStep].type; switch (currentStepType) { case 'gender': return !!personalInfo.gender; case 'age': return !!personalInfo.age; case 'height': return !!personalInfo.height; case 'weight': return !!personalInfo.weight; default: return false; } }; return ( {/* 顶部导航 */} {currentStep > 0 && ( ‹ 返回 )} 跳过 {/* 进度条 */} {currentStep + 1} / {steps.length} {/* 标题区域 */} {steps[currentStep].title} {steps[currentStep].subtitle} {/* 内容区域 */} {renderStepContent()} {/* 底部按钮 */} {currentStep === steps.length - 1 ? '完成' : '下一步'} ); } const styles = StyleSheet.create({ container: { flex: 1, paddingTop: StatusBar.currentHeight || 44, }, header: { flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', paddingHorizontal: 20, paddingVertical: 16, }, backButton: { padding: 8, }, backText: { fontSize: 16, fontWeight: '500', }, skipButton: { padding: 8, }, skipText: { fontSize: 16, fontWeight: '500', }, progressContainer: { paddingHorizontal: 20, marginBottom: 32, }, progressBackground: { height: 4, borderRadius: 2, marginBottom: 8, }, progressBar: { height: '100%', borderRadius: 2, }, progressText: { fontSize: 12, textAlign: 'right', }, content: { flex: 1, }, contentContainer: { paddingHorizontal: 24, paddingBottom: 24, }, titleContainer: { marginBottom: 48, }, title: { textAlign: 'center', marginBottom: 16, fontWeight: '700', }, subtitle: { fontSize: 16, textAlign: 'center', lineHeight: 24, }, optionsContainer: { flexDirection: 'row', justifyContent: 'space-around', paddingHorizontal: 20, }, genderOption: { width: width * 0.35, height: 120, borderRadius: 16, borderWidth: 1, justifyContent: 'center', alignItems: 'center', padding: 16, }, genderIcon: { fontSize: 48, marginBottom: 8, }, genderText: { fontSize: 16, fontWeight: '600', }, inputContainer: { alignItems: 'center', }, inputWrapper: { flexDirection: 'row', alignItems: 'center', borderWidth: 1, borderRadius: 12, paddingHorizontal: 16, width: width * 0.6, height: 56, }, numberInput: { flex: 1, fontSize: 18, fontWeight: '600', textAlign: 'center', }, unitText: { fontSize: 16, fontWeight: '500', marginLeft: 8, }, buttonContainer: { paddingHorizontal: 24, paddingBottom: 48, }, nextButton: { height: 56, borderRadius: 16, justifyContent: 'center', alignItems: 'center', shadowColor: '#000', shadowOffset: { width: 0, height: 2, }, shadowOpacity: 0.1, shadowRadius: 4, elevation: 4, }, nextButtonText: { fontSize: 18, fontWeight: '600', }, });