新增手腕温度健康数据追踪,支持Apple Watch睡眠手腕温度数据展示和30天历史趋势分析 实现经期数据与HealthKit的完整双向同步,支持读取、写入和删除经期记录 优化经期预测算法,基于历史数据计算更准确的周期和排卵日预测 重构经期UI组件为模块化结构,提升代码可维护性 添加完整的中英文国际化支持,覆盖所有新增功能界面
112 lines
3.0 KiB
TypeScript
112 lines
3.0 KiB
TypeScript
import { Colors } from '@/constants/Colors';
|
|
import { Ionicons } from '@expo/vector-icons';
|
|
import dayjs from 'dayjs';
|
|
import React from 'react';
|
|
import { DimensionValue, StyleSheet, Text, TouchableOpacity, View } from 'react-native';
|
|
import { InlineTipProps } from './types';
|
|
|
|
export const InlineTip: React.FC<InlineTipProps> = ({
|
|
selectedDate,
|
|
selectedInfo,
|
|
columnIndex,
|
|
onMarkStart,
|
|
onCancelMark,
|
|
}) => {
|
|
// 14.28% per cell. Center is 7.14%.
|
|
const pointerLeft = `${columnIndex * 14.2857 + 7.1428}%` as DimensionValue;
|
|
const isFuture = selectedDate.isAfter(dayjs(), 'day');
|
|
|
|
return (
|
|
<View style={styles.inlineTipCard}>
|
|
<View style={[styles.inlineTipPointer, { left: pointerLeft }]} />
|
|
<View style={styles.inlineTipRow}>
|
|
<View style={styles.inlineTipDate}>
|
|
<Ionicons name="calendar-outline" size={16} color="#111827" />
|
|
<Text style={styles.inlineTipDateText}>{selectedDate.format('M月D日')}</Text>
|
|
</View>
|
|
{!isFuture && (!selectedInfo || !selectedInfo.confirmed) && (
|
|
<TouchableOpacity style={styles.inlinePrimaryBtn} onPress={onMarkStart}>
|
|
<Ionicons name="add" size={14} color="#fff" />
|
|
<Text style={styles.inlinePrimaryText}>标记经期</Text>
|
|
</TouchableOpacity>
|
|
)}
|
|
{!isFuture && selectedInfo?.confirmed && selectedInfo.status === 'period' && (
|
|
<TouchableOpacity style={styles.inlineSecondaryBtn} onPress={onCancelMark}>
|
|
<Text style={styles.inlineSecondaryText}>取消标记</Text>
|
|
</TouchableOpacity>
|
|
)}
|
|
</View>
|
|
</View>
|
|
);
|
|
};
|
|
|
|
const styles = StyleSheet.create({
|
|
inlineTipCard: {
|
|
backgroundColor: '#e8e7ff',
|
|
borderRadius: 18,
|
|
paddingVertical: 10,
|
|
paddingHorizontal: 12,
|
|
shadowColor: '#000',
|
|
shadowOpacity: 0.04,
|
|
shadowRadius: 6,
|
|
shadowOffset: { width: 0, height: 2 },
|
|
elevation: 1,
|
|
},
|
|
inlineTipPointer: {
|
|
position: 'absolute',
|
|
top: -6,
|
|
width: 12,
|
|
height: 12,
|
|
marginLeft: -6,
|
|
backgroundColor: '#e8e7ff',
|
|
transform: [{ rotate: '45deg' }],
|
|
borderRadius: 3,
|
|
},
|
|
inlineTipRow: {
|
|
flexDirection: 'row',
|
|
alignItems: 'center',
|
|
justifyContent: 'space-between',
|
|
gap: 8,
|
|
},
|
|
inlineTipDate: {
|
|
flexDirection: 'row',
|
|
alignItems: 'center',
|
|
gap: 6,
|
|
},
|
|
inlineTipDateText: {
|
|
fontSize: 14,
|
|
color: '#111827',
|
|
fontWeight: '800',
|
|
fontFamily: 'AliBold',
|
|
},
|
|
inlinePrimaryBtn: {
|
|
flexDirection: 'row',
|
|
alignItems: 'center',
|
|
backgroundColor: Colors.light.primary,
|
|
paddingHorizontal: 12,
|
|
paddingVertical: 8,
|
|
borderRadius: 14,
|
|
gap: 6,
|
|
},
|
|
inlinePrimaryText: {
|
|
color: '#fff',
|
|
fontSize: 13,
|
|
fontWeight: '700',
|
|
fontFamily: 'AliBold',
|
|
},
|
|
inlineSecondaryBtn: {
|
|
paddingHorizontal: 12,
|
|
paddingVertical: 8,
|
|
borderRadius: 14,
|
|
backgroundColor: '#fff',
|
|
borderWidth: 1,
|
|
borderColor: '#d1d5db',
|
|
},
|
|
inlineSecondaryText: {
|
|
color: '#111827',
|
|
fontSize: 13,
|
|
fontWeight: '700',
|
|
fontFamily: 'AliBold',
|
|
},
|
|
});
|