feat(ui): 添加设置弹窗功能并重构水摄入设置界面
- 添加设置弹窗状态管理 - 实现设置按钮点击处理函数 - 在头部添加设置图标按钮 - 移除原有的设置行界面,改为弹窗形式展示 - 添加新的样式定义支持设置弹窗布局 - 优化设置项的展示和交互体验
This commit is contained in:
@@ -37,7 +37,8 @@ const WaterSettings: React.FC<WaterSettingsProps> = () => {
|
||||
const [dailyGoal, setDailyGoal] = useState<string>('2000');
|
||||
const [quickAddAmount, setQuickAddAmount] = useState<string>('250');
|
||||
|
||||
// 编辑弹窗状态
|
||||
// 设置弹窗状态
|
||||
const [settingsModalVisible, setSettingsModalVisible] = useState(false);
|
||||
const [goalModalVisible, setGoalModalVisible] = useState(false);
|
||||
const [quickAddModalVisible, setQuickAddModalVisible] = useState(false);
|
||||
|
||||
@@ -49,19 +50,24 @@ const WaterSettings: React.FC<WaterSettingsProps> = () => {
|
||||
const { waterRecords, dailyWaterGoal, updateWaterGoal, removeWaterRecord } = useWaterDataByDate(selectedDate);
|
||||
|
||||
|
||||
const goalPresets = [1500, 2000, 2500, 3000, 3500, 4000];
|
||||
const quickAddPresets = [100, 150, 200, 250, 300, 350, 400, 500];
|
||||
|
||||
|
||||
// 处理设置按钮点击
|
||||
const handleSettingsPress = () => {
|
||||
setSettingsModalVisible(true);
|
||||
};
|
||||
|
||||
// 打开饮水目标弹窗时初始化临时值
|
||||
const openGoalModal = () => {
|
||||
setTempGoal(parseInt(dailyGoal));
|
||||
setSettingsModalVisible(false);
|
||||
setGoalModalVisible(true);
|
||||
};
|
||||
|
||||
// 打开快速添加弹窗时初始化临时值
|
||||
const openQuickAddModal = () => {
|
||||
setTempQuickAdd(parseInt(quickAddAmount));
|
||||
setSettingsModalVisible(false);
|
||||
setQuickAddModalVisible(true);
|
||||
};
|
||||
|
||||
@@ -224,6 +230,15 @@ const WaterSettings: React.FC<WaterSettingsProps> = () => {
|
||||
// 这里会通过路由自动处理返回
|
||||
router.back();
|
||||
}}
|
||||
right={
|
||||
<TouchableOpacity
|
||||
style={styles.settingsButton}
|
||||
onPress={handleSettingsPress}
|
||||
activeOpacity={0.7}
|
||||
>
|
||||
<Ionicons name="settings-outline" size={24} color={colorTokens.text} />
|
||||
</TouchableOpacity>
|
||||
}
|
||||
/>
|
||||
|
||||
<KeyboardAvoidingView
|
||||
@@ -235,44 +250,6 @@ const WaterSettings: React.FC<WaterSettingsProps> = () => {
|
||||
contentContainerStyle={styles.scrollContent}
|
||||
showsVerticalScrollIndicator={false}
|
||||
>
|
||||
{/* 第一部分:饮水配置 */}
|
||||
<View style={styles.section}>
|
||||
<Text style={[styles.sectionTitle, { color: colorTokens.text }]}>饮水配置</Text>
|
||||
|
||||
{/* 设置目标部分 */}
|
||||
<TouchableOpacity
|
||||
style={[styles.settingRow, { backgroundColor: colorTokens.pageBackgroundEmphasis }]}
|
||||
onPress={openGoalModal}
|
||||
activeOpacity={0.8}
|
||||
>
|
||||
<View style={styles.settingLeft}>
|
||||
<Text style={[styles.settingTitle, { color: colorTokens.text }]}>每日饮水目标</Text>
|
||||
<Text style={[styles.settingValue, { color: colorTokens.textSecondary }]}>{dailyGoal}ml</Text>
|
||||
</View>
|
||||
<View style={styles.settingRight}>
|
||||
<Ionicons name="chevron-forward" size={16} color={colorTokens.icon} />
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
|
||||
{/* 快速添加默认值设置部分 */}
|
||||
<TouchableOpacity
|
||||
style={[styles.settingRow, { backgroundColor: colorTokens.pageBackgroundEmphasis, marginTop: 24 }]}
|
||||
onPress={openQuickAddModal}
|
||||
activeOpacity={0.8}
|
||||
>
|
||||
<View style={styles.settingLeft}>
|
||||
<Text style={[styles.settingTitle, { color: colorTokens.text }]}>快速添加默认值</Text>
|
||||
<Text style={[styles.settingSubtitle, { color: colorTokens.textSecondary }]}>
|
||||
{`设置点击右上角"+"按钮时添加的默认饮水量`}
|
||||
</Text>
|
||||
<Text style={[styles.settingValue, { color: colorTokens.textSecondary }]}>{quickAddAmount}ml</Text>
|
||||
</View>
|
||||
<View style={styles.settingRight}>
|
||||
<Ionicons name="chevron-forward" size={16} color={colorTokens.icon} />
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
|
||||
</View>
|
||||
|
||||
{/* 第二部分:饮水记录 */}
|
||||
<View style={styles.section}>
|
||||
@@ -311,6 +288,52 @@ const WaterSettings: React.FC<WaterSettingsProps> = () => {
|
||||
</ScrollView>
|
||||
</KeyboardAvoidingView>
|
||||
|
||||
{/* 设置主弹窗 */}
|
||||
<Modal
|
||||
visible={settingsModalVisible}
|
||||
transparent
|
||||
animationType="fade"
|
||||
onRequestClose={() => setSettingsModalVisible(false)}
|
||||
>
|
||||
<Pressable style={styles.modalBackdrop} onPress={() => setSettingsModalVisible(false)} />
|
||||
<View style={styles.settingsModalSheet}>
|
||||
<View style={styles.modalHandle} />
|
||||
<Text style={[styles.settingsModalTitle, { color: colorTokens.text }]}>饮水设置</Text>
|
||||
|
||||
{/* 菜单项 */}
|
||||
<View style={styles.settingsMenuContainer}>
|
||||
<TouchableOpacity style={styles.settingsMenuItem} onPress={openGoalModal}>
|
||||
<View style={styles.settingsMenuItemLeft}>
|
||||
<View style={[styles.settingsIconContainer, { backgroundColor: 'rgba(147, 112, 219, 0.1)' }]}>
|
||||
<Ionicons name="flag-outline" size={20} color="#9370DB" />
|
||||
</View>
|
||||
<View style={styles.settingsMenuItemContent}>
|
||||
<Text style={[styles.settingsMenuItemTitle, { color: colorTokens.text }]}>每日饮水目标</Text>
|
||||
<Text style={[styles.settingsMenuItemValue, { color: colorTokens.textSecondary }]}>{dailyWaterGoal || dailyGoal}ml</Text>
|
||||
</View>
|
||||
</View>
|
||||
<Ionicons name="chevron-forward" size={20} color="#CCCCCC" />
|
||||
</TouchableOpacity>
|
||||
|
||||
<TouchableOpacity style={[styles.settingsMenuItem, { borderBottomWidth: 0 }]} onPress={openQuickAddModal}>
|
||||
<View style={styles.settingsMenuItemLeft}>
|
||||
<View style={[styles.settingsIconContainer, { backgroundColor: 'rgba(147, 112, 219, 0.1)' }]}>
|
||||
<Ionicons name="add-outline" size={20} color="#9370DB" />
|
||||
</View>
|
||||
<View style={styles.settingsMenuItemContent}>
|
||||
<Text style={[styles.settingsMenuItemTitle, { color: colorTokens.text }]}>快速添加默认值</Text>
|
||||
<Text style={[styles.settingsMenuItemSubtitle, { color: colorTokens.textSecondary }]}>
|
||||
设置点击"+"按钮时添加的默认饮水量
|
||||
</Text>
|
||||
<Text style={[styles.settingsMenuItemValue, { color: colorTokens.textSecondary }]}>{quickAddAmount}ml</Text>
|
||||
</View>
|
||||
</View>
|
||||
<Ionicons name="chevron-forward" size={20} color="#CCCCCC" />
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
</View>
|
||||
</Modal>
|
||||
|
||||
{/* 饮水目标编辑弹窗 */}
|
||||
<Modal
|
||||
visible={goalModalVisible}
|
||||
@@ -452,79 +475,6 @@ const styles = StyleSheet.create({
|
||||
fontWeight: '400',
|
||||
lineHeight: 18,
|
||||
},
|
||||
input: {
|
||||
borderRadius: 12,
|
||||
paddingHorizontal: 16,
|
||||
paddingVertical: 14,
|
||||
fontSize: 16,
|
||||
fontWeight: '500',
|
||||
marginBottom: 16,
|
||||
},
|
||||
settingRow: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'space-between',
|
||||
paddingVertical: 16,
|
||||
paddingHorizontal: 16,
|
||||
borderRadius: 12,
|
||||
marginBottom: 16,
|
||||
},
|
||||
settingLeft: {
|
||||
flex: 1,
|
||||
},
|
||||
settingTitle: {
|
||||
fontSize: 16,
|
||||
fontWeight: '500',
|
||||
marginBottom: 4,
|
||||
},
|
||||
settingSubtitle: {
|
||||
fontSize: 14,
|
||||
marginBottom: 8,
|
||||
},
|
||||
settingValue: {
|
||||
fontSize: 16,
|
||||
},
|
||||
settingRight: {
|
||||
marginLeft: 12,
|
||||
},
|
||||
quickAmountsContainer: {
|
||||
marginBottom: 15,
|
||||
},
|
||||
quickAmountsWrapper: {
|
||||
flexDirection: 'row',
|
||||
gap: 10,
|
||||
paddingRight: 10,
|
||||
},
|
||||
quickAmountButton: {
|
||||
paddingHorizontal: 20,
|
||||
paddingVertical: 8,
|
||||
borderRadius: 20,
|
||||
minWidth: 70,
|
||||
alignItems: 'center',
|
||||
shadowColor: '#000',
|
||||
shadowOffset: { width: 0, height: 1 },
|
||||
shadowOpacity: 0.05,
|
||||
shadowRadius: 2,
|
||||
elevation: 1,
|
||||
},
|
||||
quickAmountText: {
|
||||
fontSize: 15,
|
||||
fontWeight: '500',
|
||||
},
|
||||
saveButton: {
|
||||
paddingVertical: 14,
|
||||
borderRadius: 12,
|
||||
alignItems: 'center',
|
||||
marginTop: 24,
|
||||
shadowOffset: { width: 0, height: 2 },
|
||||
shadowOpacity: 0.25,
|
||||
shadowRadius: 4,
|
||||
elevation: 3,
|
||||
},
|
||||
saveButtonText: {
|
||||
fontSize: 16,
|
||||
fontWeight: '700',
|
||||
},
|
||||
// 饮水记录相关样式
|
||||
recordsList: {
|
||||
gap: 12,
|
||||
@@ -700,6 +650,80 @@ const styles = StyleSheet.create({
|
||||
modalBtnTextPrimary: {
|
||||
// color will be set dynamically
|
||||
},
|
||||
settingsButton: {
|
||||
width: 32,
|
||||
height: 32,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
},
|
||||
settingsModalSheet: {
|
||||
position: 'absolute',
|
||||
left: 0,
|
||||
right: 0,
|
||||
bottom: 0,
|
||||
padding: 16,
|
||||
backgroundColor: '#FFFFFF',
|
||||
borderTopLeftRadius: 16,
|
||||
borderTopRightRadius: 16,
|
||||
shadowColor: '#000000',
|
||||
shadowOffset: { width: 0, height: -2 },
|
||||
shadowOpacity: 0.1,
|
||||
shadowRadius: 8,
|
||||
elevation: 16,
|
||||
},
|
||||
settingsModalTitle: {
|
||||
fontSize: 18,
|
||||
fontWeight: '600',
|
||||
textAlign: 'center',
|
||||
marginBottom: 20,
|
||||
},
|
||||
settingsMenuContainer: {
|
||||
backgroundColor: '#FFFFFF',
|
||||
borderRadius: 12,
|
||||
shadowColor: '#000',
|
||||
shadowOffset: { width: 0, height: 1 },
|
||||
shadowOpacity: 0.05,
|
||||
shadowRadius: 4,
|
||||
elevation: 2,
|
||||
overflow: 'hidden',
|
||||
},
|
||||
settingsMenuItem: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'space-between',
|
||||
paddingVertical: 14,
|
||||
paddingHorizontal: 16,
|
||||
borderBottomWidth: 1,
|
||||
borderBottomColor: '#F1F3F4',
|
||||
},
|
||||
settingsMenuItemLeft: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
flex: 1,
|
||||
},
|
||||
settingsIconContainer: {
|
||||
width: 32,
|
||||
height: 32,
|
||||
borderRadius: 6,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
marginRight: 12,
|
||||
},
|
||||
settingsMenuItemContent: {
|
||||
flex: 1,
|
||||
},
|
||||
settingsMenuItemTitle: {
|
||||
fontSize: 15,
|
||||
fontWeight: '500',
|
||||
marginBottom: 2,
|
||||
},
|
||||
settingsMenuItemSubtitle: {
|
||||
fontSize: 12,
|
||||
marginBottom: 4,
|
||||
},
|
||||
settingsMenuItemValue: {
|
||||
fontSize: 14,
|
||||
},
|
||||
});
|
||||
|
||||
export default WaterSettings;
|
||||
|
||||
@@ -150,6 +150,7 @@ const WaterIntakeCard: React.FC<WaterIntakeCardProps> = ({
|
||||
};
|
||||
|
||||
|
||||
|
||||
return (
|
||||
<TouchableOpacity
|
||||
style={[styles.container, style]}
|
||||
@@ -260,6 +261,7 @@ const WaterIntakeCard: React.FC<WaterIntakeCardProps> = ({
|
||||
</Text>
|
||||
</View>
|
||||
|
||||
|
||||
</TouchableOpacity>
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user