Files
digital-pilates/components/BasalMetabolismCard.tsx
richarjiang 63ed820e93 feat(ui): 统一健康卡片标题图标并优化语音录音稳定性
- 为所有健康数据卡片添加对应功能图标,提升视觉一致性
- 将“小鱼干”文案统一为“能量值”,并更新获取说明
- 语音录音页面增加组件卸载保护、错误提示与资源清理逻辑
- 个人页支持毛玻璃按钮样式,默认用户名置空
- 新增血氧、饮食、心情、压力、睡眠、步数、体重等图标资源
- 升级 react-native-purchases 至 9.4.3
- 移除 useAuthGuard 调试日志
2025-09-16 09:35:50 +08:00

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,
},
});