- 为所有健康数据卡片添加对应功能图标,提升视觉一致性 - 将“小鱼干”文案统一为“能量值”,并更新获取说明 - 语音录音页面增加组件卸载保护、错误提示与资源清理逻辑 - 个人页支持毛玻璃按钮样式,默认用户名置空 - 新增血氧、饮食、心情、压力、睡眠、步数、体重等图标资源 - 升级 react-native-purchases 至 9.4.3 - 移除 useAuthGuard 调试日志
158 lines
3.6 KiB
TypeScript
158 lines
3.6 KiB
TypeScript
import { AnimatedNumber } from '@/components/AnimatedNumber';
|
|
import { Image } from 'expo-image';
|
|
import React from 'react';
|
|
import { StyleSheet, Text, View } from 'react-native';
|
|
|
|
interface BasalMetabolismCardProps {
|
|
value: number | null;
|
|
resetToken?: number;
|
|
style?: any;
|
|
}
|
|
|
|
export function BasalMetabolismCard({ value, resetToken, style }: BasalMetabolismCardProps) {
|
|
// 获取基础代谢状态描述
|
|
const getMetabolismStatus = () => {
|
|
if (value === null || value === 0) {
|
|
return { text: '未知', color: '#9AA3AE' };
|
|
}
|
|
|
|
// 基于常见的基础代谢范围来判断状态
|
|
if (value >= 1800) {
|
|
return { text: '高代谢', color: '#10B981' };
|
|
} else if (value >= 1400) {
|
|
return { text: '正常', color: '#3B82F6' };
|
|
} else if (value >= 1000) {
|
|
return { text: '偏低', color: '#F59E0B' };
|
|
} else {
|
|
return { text: '较低', color: '#EF4444' };
|
|
}
|
|
};
|
|
|
|
const status = getMetabolismStatus();
|
|
|
|
return (
|
|
<View style={[styles.container, style]}>
|
|
|
|
{/* 头部区域 */}
|
|
<View style={styles.header}>
|
|
<View style={styles.leftSection}>
|
|
<Image
|
|
source={require('@/assets/images/icons/icon-fire.png')}
|
|
style={styles.titleIcon}
|
|
/>
|
|
<Text style={styles.title}>基础代谢</Text>
|
|
</View>
|
|
<View style={[styles.statusBadge, { backgroundColor: status.color + '20' }]}>
|
|
<Text style={[styles.statusText, { color: status.color }]}>{status.text}</Text>
|
|
</View>
|
|
</View>
|
|
|
|
{/* 数值显示区域 */}
|
|
<View style={styles.valueSection}>
|
|
{value != null && value > 0 ? (
|
|
<AnimatedNumber
|
|
value={value}
|
|
resetToken={resetToken}
|
|
style={styles.value}
|
|
format={(v) => Math.round(v).toString()}
|
|
/>
|
|
) : (
|
|
<Text style={styles.value}>--</Text>
|
|
)}
|
|
<Text style={styles.unit}>千卡/日</Text>
|
|
</View>
|
|
</View>
|
|
);
|
|
}
|
|
|
|
const styles = StyleSheet.create({
|
|
container: {
|
|
backgroundColor: '#FFFFFF',
|
|
borderRadius: 20,
|
|
padding: 16,
|
|
shadowColor: '#000',
|
|
shadowOffset: {
|
|
width: 0,
|
|
height: 4,
|
|
},
|
|
shadowOpacity: 0.08,
|
|
shadowRadius: 12,
|
|
elevation: 4,
|
|
position: 'relative',
|
|
overflow: 'hidden',
|
|
},
|
|
|
|
header: {
|
|
flexDirection: 'row',
|
|
alignItems: 'center',
|
|
justifyContent: 'space-between',
|
|
marginBottom: 16,
|
|
zIndex: 1,
|
|
},
|
|
leftSection: {
|
|
flexDirection: 'row',
|
|
alignItems: 'center',
|
|
},
|
|
iconContainer: {
|
|
width: 32,
|
|
height: 32,
|
|
borderRadius: 10,
|
|
backgroundColor: '#FFFFFF',
|
|
alignItems: 'center',
|
|
justifyContent: 'center',
|
|
marginRight: 8,
|
|
shadowColor: '#000',
|
|
shadowOffset: {
|
|
width: 0,
|
|
height: 1,
|
|
},
|
|
shadowOpacity: 0.1,
|
|
shadowRadius: 2,
|
|
elevation: 1,
|
|
},
|
|
fireIcon: {
|
|
width: 14,
|
|
height: 18,
|
|
backgroundColor: '#EF4444',
|
|
borderTopLeftRadius: 7,
|
|
borderTopRightRadius: 7,
|
|
borderBottomLeftRadius: 2,
|
|
borderBottomRightRadius: 2,
|
|
},
|
|
title: {
|
|
fontSize: 14,
|
|
color: '#0F172A',
|
|
fontWeight: '600',
|
|
},
|
|
titleIcon: {
|
|
width: 16,
|
|
height: 16,
|
|
marginRight: 4,
|
|
},
|
|
statusBadge: {
|
|
paddingHorizontal: 8,
|
|
paddingVertical: 4,
|
|
borderRadius: 12,
|
|
},
|
|
statusText: {
|
|
fontSize: 11,
|
|
fontWeight: '600',
|
|
},
|
|
valueSection: {
|
|
flexDirection: 'row',
|
|
alignItems: 'center',
|
|
zIndex: 1,
|
|
},
|
|
value: {
|
|
fontSize: 16,
|
|
fontWeight: '600',
|
|
color: '#0F172A',
|
|
lineHeight: 28,
|
|
},
|
|
unit: {
|
|
fontSize: 12,
|
|
color: '#64748B',
|
|
marginLeft: 6,
|
|
},
|
|
});
|