import { Colors } from '@/constants/Colors'; import { useAuthGuard } from '@/hooks/useAuthGuard'; import { useColorScheme } from '@/hooks/useColorScheme'; import { BMI_CATEGORIES, canCalculateBMI, getBMIResult, type BMIResult } from '@/utils/bmi'; import { Ionicons } from '@expo/vector-icons'; import { LinearGradient } from 'expo-linear-gradient'; import React, { useState } from 'react'; import { Dimensions, Modal, ScrollView, StyleSheet, Text, TouchableOpacity, View } from 'react-native'; import Toast from 'react-native-toast-message'; const { width: screenWidth, height: screenHeight } = Dimensions.get('window'); interface BMICardProps { weight?: number; height?: number; style?: any; compact?: boolean; } export function BMICard({ weight, height, style, compact = false }: BMICardProps) { const { pushIfAuthedElseLogin } = useAuthGuard(); const [showInfoModal, setShowInfoModal] = useState(false); const canCalculate = canCalculateBMI(weight, height); let bmiResult: BMIResult | null = null; if (canCalculate && weight && height) { try { bmiResult = getBMIResult(weight, height); } catch (error) { console.warn('BMI 计算错误:', error); } } const handleGoToProfile = () => { Toast.show({ text1: '请先登录', type: 'info', }); pushIfAuthedElseLogin('/profile/edit'); }; const handleShowInfoModal = () => { setShowInfoModal(true); }; const handleHideInfoModal = () => { setShowInfoModal(false); }; const renderContent = () => { if (!canCalculate) { // 缺少数据的情况 return ( BMI {!compact && ( )} {compact ? ( {!weight && !height ? '完善身高体重' : !weight ? '完善体重' : '完善身高'} ) : ( <> {!weight && !height ? '请完善身高和体重信息' : !weight ? '请完善体重信息' : '请完善身高信息'} 前往完善 )} ); } // 有完整数据的情况 return ( BMI {!compact && ( )} {compact ? ( {bmiResult?.value} {bmiResult?.category.name} ) : ( <> {bmiResult?.value} {bmiResult?.category.name} {bmiResult?.description} {bmiResult?.category.encouragement} )} ); }; const colorScheme = useColorScheme(); const themeColors = Colors[colorScheme ?? 'light']; return ( <> {renderContent()} {/* BMI 信息弹窗 */} {/* 标题 */} BMI 指数说明 {/* 介绍部分 */} BMI(身体质量指数)是评估体重与身高关系的国际通用健康指标 计算公式:体重(kg) ÷ 身高²(m) {/* BMI 分类标准 */} BMI 分类标准 {BMI_CATEGORIES.map((category, index) => { const colors = [ { bg: '#FEF3C7', text: '#B45309', border: '#F59E0B' }, // 偏瘦 { bg: '#E8F5E8', text: Colors.light.accentGreenDark, border: Colors.light.accentGreen }, // 正常 { bg: '#FEF3C7', text: '#B45309', border: '#F59E0B' }, // 超重 { bg: '#FEE2E2', text: '#B91C1C', border: '#EF4444' } // 肥胖 ][index]; return ( {category.name} {category.range} {category.advice} ); })} {/* 健康建议 */} 健康建议 保持均衡饮食,控制热量摄入 每周至少150分钟中等强度运动 保证7-9小时充足睡眠 定期监测体重变化,及时调整 {/* 免责声明 */} BMI 仅供参考,不能反映肌肉量、骨密度等指标。如有健康疑问,请咨询专业医生。 {/* 底部继续按钮 */} 继续 ); } const styles = StyleSheet.create({ card: { borderRadius: 22, padding: 18, overflow: 'hidden', backgroundColor: '#FFFFFF', }, cardHeader: { flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between', marginBottom: 12, }, titleRow: { flexDirection: 'row', alignItems: 'center', }, iconSquare: { width: 30, height: 30, borderRadius: 8, backgroundColor: '#FFFFFF', alignItems: 'center', justifyContent: 'center', marginRight: 10, }, cardTitle: { fontSize: 14, fontWeight: '800', color: '#192126', }, infoButton: { padding: 4, }, // 缺少数据时的样式 incompleteContent: { minHeight: 80, backgroundColor: '#FFFFFF', borderRadius: 22, padding: 18, margin: -18, }, missingDataContainer: { flexDirection: 'row', alignItems: 'center', backgroundColor: '#FEF3C7', borderRadius: 12, padding: 12, marginBottom: 12, }, missingDataText: { fontSize: 14, color: '#B45309', fontWeight: '600', marginLeft: 8, flex: 1, }, completeButton: { flexDirection: 'row', alignItems: 'center', justifyContent: 'center', backgroundColor: '#ffffff', borderRadius: 12, paddingVertical: 12, paddingHorizontal: 16, }, completeButtonText: { fontSize: 16, fontWeight: '600', color: '#6B7280', marginRight: 4, }, // 有完整数据时的样式 completeContent: { minHeight: 80, borderRadius: 22, padding: 18, margin: -18, }, bmiValueContainer: { flexDirection: 'row', alignItems: 'center', marginBottom: 8, }, bmiValue: { fontSize: 20, fontWeight: '800', marginRight: 12, }, categoryBadge: { paddingHorizontal: 12, paddingVertical: 4, borderRadius: 12, }, categoryText: { fontSize: 12, fontWeight: '700', }, bmiDescription: { fontSize: 12, fontWeight: '600', marginBottom: 8, }, encouragementText: { fontSize: 10, color: '#6B7280', fontWeight: '500', lineHeight: 18, fontStyle: 'italic', }, // 紧凑模式样式 compactIncompleteContent: { minHeight: 80, padding: 14, margin: -14, }, compactCompleteContent: { minHeight: 80, padding: 14, margin: -14, }, compactTitle: { fontSize: 14, }, compactMissingData: { alignItems: 'center', justifyContent: 'center', flex: 1, }, compactMissingText: { fontSize: 12, color: '#9AA3AE', fontWeight: '500', textAlign: 'center', }, compactBMIContent: { alignItems: 'center', justifyContent: 'center', flex: 1, }, compactBMIValue: { fontSize: 24, fontWeight: '800', marginBottom: 4, }, compactBMICategory: { fontSize: 12, fontWeight: '700', }, // 弹窗样式 modalBackdrop: { flex: 1, backgroundColor: 'rgba(0,0,0,0.6)', justifyContent: 'center', alignItems: 'center', padding: 20, }, modalContainer: { width: screenWidth * 0.92, backgroundColor: '#FFFFFF', borderRadius: 24, overflow: 'hidden', elevation: 20, shadowColor: '#000', shadowOffset: { width: 0, height: 8 }, shadowOpacity: 0.3, shadowRadius: 20, }, modalHeader: { flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between', padding: 20, borderBottomWidth: 1, borderBottomColor: '#F3F4F6', backgroundColor: '#FAFAFA', }, modalTitleContainer: { flexDirection: 'row', alignItems: 'center', }, modalIconContainer: { width: 40, height: 40, borderRadius: 12, backgroundColor: '#EFF6FF', alignItems: 'center', justifyContent: 'center', marginRight: 12, }, modalTitle: { fontSize: 20, fontWeight: '800', color: '#111827', letterSpacing: -0.5, }, closeButton: { width: 36, height: 36, borderRadius: 18, backgroundColor: '#F3F4F6', alignItems: 'center', justifyContent: 'center', }, // 内容区域样式 modalContent: { paddingHorizontal: 20, paddingBottom: 24, }, // 介绍部分 introSection: { marginBottom: 20, }, modalDescription: { fontSize: 15, color: '#374151', lineHeight: 22, textAlign: 'center', marginBottom: 12, }, formulaContainer: { backgroundColor: '#F8FAFC', borderRadius: 12, padding: 16, borderLeftWidth: 4, borderLeftColor: '#3B82F6', }, formulaText: { fontSize: 15, color: '#1F2937', fontWeight: '600', textAlign: 'center', }, // 分类部分 categoriesSection: { marginBottom: 18, }, sectionTitle: { fontSize: 16, fontWeight: '800', color: '#111827', marginBottom: 12, textAlign: 'center', }, categoriesGrid: { flexDirection: 'row', flexWrap: 'wrap', gap: 8, }, categoryCompact: { flex: 1, minWidth: '48%', borderRadius: 12, padding: 12, marginBottom: 8, }, categoryCompactHeader: { flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', marginBottom: 6, }, categoryCompactName: { fontSize: 14, fontWeight: '700', }, categoryCompactRange: { fontSize: 12, fontWeight: '600', opacity: 0.8, }, categoryCompactAdvice: { fontSize: 11, lineHeight: 16, fontWeight: '500', opacity: 0.9, }, // 健康提示 healthTips: { backgroundColor: '#F9FAFB', borderRadius: 12, padding: 14, marginBottom: 16, borderLeftWidth: 3, borderLeftColor: '#EF4444', }, tipsHeader: { flexDirection: 'row', alignItems: 'center', marginBottom: 6, }, tipsTitle: { fontSize: 14, fontWeight: '700', color: '#111827', marginLeft: 6, }, tipsContent: { fontSize: 13, color: '#374151', lineHeight: 18, }, // 免责声明紧凑版 disclaimerCompact: { flexDirection: 'row', alignItems: 'center', backgroundColor: '#F9FAFB', borderRadius: 8, padding: 12, marginTop: 4, }, disclaimerCompactText: { fontSize: 12, color: '#6B7280', fontStyle: 'italic', lineHeight: 16, marginLeft: 6, flex: 1, }, // 新样式 - 与StressAnalysisModal保持一致 newModalContainer: { flex: 1, }, newContent: { flex: 1, paddingHorizontal: 20, }, newTitle: { fontSize: 24, fontWeight: '800', color: '#111827', textAlign: 'center', marginTop: 20, marginBottom: 32, }, newIntroSection: { marginBottom: 32, }, newDescription: { fontSize: 16, color: '#374151', lineHeight: 24, textAlign: 'center', marginBottom: 16, }, newFormulaContainer: { backgroundColor: '#F8FAFC', borderRadius: 12, padding: 16, borderLeftWidth: 4, borderLeftColor: '#3B82F6', }, newFormulaText: { fontSize: 15, color: '#1F2937', fontWeight: '600', textAlign: 'center', }, newSectionTitle: { fontSize: 22, fontWeight: '800', color: '#111827', marginBottom: 20, }, newStatsCard: { backgroundColor: '#FFFFFF', borderRadius: 16, padding: 20, marginBottom: 32, shadowColor: '#000', shadowOffset: { width: 0, height: 2, }, shadowOpacity: 0.05, shadowRadius: 8, elevation: 2, }, newStatItem: { backgroundColor: '#FFFFFF', borderRadius: 12, padding: 16, marginBottom: 12, borderLeftWidth: 4, }, newStatHeader: { flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', marginBottom: 8, }, newStatTitle: { fontSize: 16, fontWeight: '700', }, newStatRange: { fontSize: 14, fontWeight: '600', opacity: 0.8, }, newStatAdvice: { fontSize: 14, lineHeight: 20, fontWeight: '500', opacity: 0.9, }, newHealthTips: { backgroundColor: '#FFFFFF', borderRadius: 16, padding: 20, marginBottom: 32, shadowColor: '#000', shadowOffset: { width: 0, height: 2, }, shadowOpacity: 0.05, shadowRadius: 8, elevation: 2, }, newTipsItem: { flexDirection: 'row', alignItems: 'center', marginBottom: 12, }, newTipsText: { fontSize: 15, color: '#374151', marginLeft: 12, flex: 1, }, newDisclaimer: { flexDirection: 'row', alignItems: 'flex-start', backgroundColor: '#F9FAFB', borderRadius: 12, padding: 16, marginBottom: 32, }, newDisclaimerText: { fontSize: 13, color: '#6B7280', lineHeight: 18, marginLeft: 8, flex: 1, }, newBottomContainer: { paddingHorizontal: 20, paddingBottom: 34, }, newContinueButton: { borderRadius: 25, overflow: 'hidden', marginBottom: 8, }, newButtonBackground: { backgroundColor: Colors.light.accentGreen, paddingVertical: 18, alignItems: 'center', justifyContent: 'center', }, newButtonText: { fontSize: 18, fontWeight: '700', color: '#192126', }, newHomeIndicator: { width: 134, height: 5, backgroundColor: '#000', borderRadius: 3, alignSelf: 'center', }, });