import { HeaderBar } from '@/components/ui/HeaderBar'; import { Colors } from '@/constants/Colors'; import { useAppDispatch, useAppSelector } from '@/hooks/redux'; import { useColorScheme } from '@/hooks/useColorScheme'; import { getMoodOptions, MoodType } from '@/services/moodCheckins'; import { createMoodRecord, deleteMoodRecord, fetchDailyMoodCheckins, selectMoodRecordsByDate, updateMoodRecord } from '@/store/moodSlice'; import dayjs from 'dayjs'; import { LinearGradient } from 'expo-linear-gradient'; import { router, useLocalSearchParams } from 'expo-router'; import React, { useEffect, useState } from 'react'; import { Alert, SafeAreaView, ScrollView, StyleSheet, Text, TextInput, TouchableOpacity, View, } from 'react-native'; export default function MoodEditScreen() { const theme = (useColorScheme() ?? 'light') as 'light' | 'dark'; const colorTokens = Colors[theme]; const params = useLocalSearchParams(); const dispatch = useAppDispatch(); const { date, moodId } = params; const selectedDate = date as string || dayjs().format('YYYY-MM-DD'); const [selectedMood, setSelectedMood] = useState(''); const [intensity, setIntensity] = useState(5); const [description, setDescription] = useState(''); const [isLoading, setIsLoading] = useState(false); const [isDeleting, setIsDeleting] = useState(false); const [existingMood, setExistingMood] = useState(null); const moodOptions = getMoodOptions(); // 从 Redux 获取数据 const moodRecords = useAppSelector(selectMoodRecordsByDate(selectedDate)); const loading = useAppSelector(state => state.mood.loading); // 初始化数据 useEffect(() => { // 加载当前日期的心情记录 dispatch(fetchDailyMoodCheckins(selectedDate)); }, [selectedDate, dispatch]); // 当 moodRecords 更新时,查找现有记录 useEffect(() => { if (moodId && moodRecords.length > 0) { const mood = moodRecords.find((c: any) => c.id === moodId) || moodRecords[0]; setExistingMood(mood); setSelectedMood(mood.moodType); setIntensity(mood.intensity); setDescription(mood.description || ''); } }, [moodId, moodRecords]); const handleSave = async () => { if (!selectedMood) { Alert.alert('提示', '请选择心情'); return; } try { setIsLoading(true); if (existingMood) { // 更新现有记录 await dispatch(updateMoodRecord({ id: existingMood.id, moodType: selectedMood, intensity, description: description.trim() || undefined, })).unwrap(); } else { // 创建新记录 await dispatch(createMoodRecord({ moodType: selectedMood, intensity, description: description.trim() || undefined, checkinDate: selectedDate, })).unwrap(); } Alert.alert('成功', existingMood ? '心情记录已更新' : '心情记录已保存', [ { text: '确定', onPress: () => router.back() } ]); } catch (error) { console.error('保存心情失败:', error); Alert.alert('错误', '保存心情失败,请重试'); } finally { setIsLoading(false); } }; const handleDelete = async () => { if (!existingMood) return; Alert.alert( '确认删除', '确定要删除这条心情记录吗?', [ { text: '取消', style: 'cancel' }, { text: '删除', style: 'destructive', onPress: async () => { try { setIsDeleting(true); await dispatch(deleteMoodRecord({ id: existingMood.id })).unwrap(); Alert.alert('成功', '心情记录已删除', [ { text: '确定', onPress: () => router.back() } ]); } catch (error) { console.error('删除心情失败:', error); Alert.alert('错误', '删除心情失败,请重试'); } finally { setIsDeleting(false); } }, }, ] ); }; const renderIntensitySlider = () => { return ( 心情强度: {intensity} {[1, 2, 3, 4, 5, 6, 7, 8, 9, 10].map((level) => ( = level && styles.intensityDotActive ]} onPress={() => setIntensity(level)} /> ))} 轻微 强烈 ); }; // 使用统一的渐变背景色 const backgroundGradientColors = [colorTokens.backgroundGradientStart, colorTokens.backgroundGradientEnd] as const; return ( router.back()} withSafeTop={false} transparent={true} tone="light" /> {/* 日期显示 */} {dayjs(selectedDate).format('YYYY年M月D日')} {/* 心情选择 */} 选择心情 {moodOptions.map((mood, index) => ( setSelectedMood(mood.type)} > {mood.emoji} {mood.label} ))} {/* 心情强度选择 */} {selectedMood && ( 心情强度 {renderIntensitySlider()} )} {/* 心情描述 */} {selectedMood && ( 心情描述(可选) {description.length}/200 )} {/* 底部按钮 */} {existingMood && ( {isDeleting ? '删除中...' : '删除记录'} )} {isLoading ? '保存中...' : existingMood ? '更新心情' : '保存心情'} ); } const styles = StyleSheet.create({ container: { flex: 1, }, gradientBackground: { position: 'absolute', left: 0, right: 0, top: 0, bottom: 0, }, safeArea: { flex: 1, }, content: { flex: 1, }, dateSection: { backgroundColor: '#fff', margin: 16, borderRadius: 16, padding: 16, alignItems: 'center', }, dateTitle: { fontSize: 24, fontWeight: '700', color: '#192126', }, moodSection: { backgroundColor: '#fff', margin: 16, marginTop: 0, borderRadius: 16, padding: 16, }, sectionTitle: { fontSize: 18, fontWeight: '600', color: '#333', marginBottom: 16, }, moodOptions: { flexDirection: 'row', flexWrap: 'wrap', justifyContent: 'space-between', }, moodOption: { width: '30%', alignItems: 'center', paddingVertical: 16, marginBottom: 16, borderRadius: 12, backgroundColor: '#f8f8f8', }, selectedMoodOption: { backgroundColor: '#e8f5e8', borderWidth: 2, borderColor: Colors.light.accentGreen, }, moodEmoji: { fontSize: 24, marginBottom: 8, }, moodLabel: { fontSize: 14, color: '#333', }, intensitySection: { backgroundColor: '#fff', margin: 16, marginTop: 0, borderRadius: 16, padding: 16, }, intensityContainer: { alignItems: 'center', }, intensityLabel: { fontSize: 16, fontWeight: '600', color: '#333', marginBottom: 12, }, intensitySlider: { flexDirection: 'row', justifyContent: 'space-between', width: '100%', marginBottom: 8, }, intensityDot: { width: 20, height: 20, borderRadius: 10, backgroundColor: '#ddd', }, intensityDotActive: { backgroundColor: Colors.light.accentGreen, }, intensityLabels: { flexDirection: 'row', justifyContent: 'space-between', width: '100%', }, intensityLabelText: { fontSize: 12, color: '#666', }, descriptionSection: { backgroundColor: '#fff', margin: 16, marginTop: 0, borderRadius: 16, padding: 16, }, descriptionInput: { borderWidth: 1, borderColor: '#ddd', borderRadius: 8, padding: 12, fontSize: 16, minHeight: 80, textAlignVertical: 'top', }, characterCount: { fontSize: 12, color: '#999', textAlign: 'right', marginTop: 4, }, footer: { padding: 16, backgroundColor: '#fff', }, saveButton: { backgroundColor: Colors.light.accentGreen, borderRadius: 12, paddingVertical: 16, alignItems: 'center', marginTop: 8, }, deleteButton: { backgroundColor: '#F44336', borderRadius: 12, paddingVertical: 16, alignItems: 'center', }, disabledButton: { backgroundColor: '#ccc', }, saveButtonText: { color: '#fff', fontSize: 16, fontWeight: '600', }, deleteButtonText: { color: '#fff', fontSize: 16, fontWeight: '600', }, });