import { useAuthGuard } from '@/hooks/useAuthGuard';
import {
BMI_CATEGORIES,
canCalculateBMI,
getBMIResult,
type BMIResult
} from '@/utils/bmi';
import { Ionicons } from '@expo/vector-icons';
import React, { useState } from 'react';
import {
Dimensions,
Modal,
Pressable,
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;
}
export function BMICard({ weight, height, style }: 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 指数
{!weight && !height ? '请完善身高和体重信息' :
!weight ? '请完善体重信息' : '请完善身高信息'}
前往完善
);
}
// 有完整数据的情况
return (
BMI 指数
{bmiResult?.value}
{bmiResult?.category.name}
{bmiResult?.description}
{bmiResult?.category.encouragement}
);
};
return (
<>
{renderContent()}
{/* BMI 信息弹窗 */}
e.stopPropagation()}
>
{/* 弹窗头部 */}
BMI 指数说明
{/* 内容区域 - 去除滚动,精简设计 */}
{/* 介绍部分 */}
BMI 是评估体重与身高关系的健康指标
计算公式:体重(kg) ÷ 身高²(m)
{/* BMI 分类标准 - 紧凑设计 */}
分类标准
{BMI_CATEGORIES.map((category, index) => {
const colors = index === 0 ? { bg: '#FEF3C7', text: '#B45309' } :
index === 1 ? { bg: '#E8F5E8', text: '#2D5016' } :
index === 2 ? { bg: '#FEF3C7', text: '#B45309' } :
{ bg: '#FEE2E2', text: '#B91C1C' };
return (
{category.name}
{category.range}
{category.advice}
);
})}
{/* 健康提示 - 简化版 */}
健康建议
保持均衡饮食、规律运动、充足睡眠,定期监测体重变化
{/* 免责声明 - 精简版 */}
BMI 仅供参考,如有疑问请咨询专业医生
>
);
}
const styles = StyleSheet.create({
card: {
borderRadius: 22,
padding: 18,
marginBottom: 16,
overflow: 'hidden',
},
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: 18,
fontWeight: '800',
color: '#192126',
},
infoButton: {
padding: 4,
},
// 缺少数据时的样式
incompleteContent: {
minHeight: 120,
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: '#F3F4F6',
borderRadius: 12,
paddingVertical: 12,
paddingHorizontal: 16,
},
completeButtonText: {
fontSize: 16,
fontWeight: '600',
color: '#6B7280',
marginRight: 4,
},
// 有完整数据时的样式
completeContent: {
minHeight: 120,
borderRadius: 22,
padding: 18,
margin: -18,
},
bmiValueContainer: {
flexDirection: 'row',
alignItems: 'center',
marginBottom: 8,
},
bmiValue: {
fontSize: 32,
fontWeight: '800',
marginRight: 12,
},
categoryBadge: {
paddingHorizontal: 12,
paddingVertical: 4,
borderRadius: 12,
},
categoryText: {
fontSize: 14,
fontWeight: '700',
},
bmiDescription: {
fontSize: 14,
fontWeight: '600',
marginBottom: 8,
},
encouragementText: {
fontSize: 13,
color: '#6B7280',
fontWeight: '500',
lineHeight: 18,
fontStyle: 'italic',
},
// 弹窗样式
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,
},
});