import React, { useState, useEffect } from 'react'; import { View, Text, StyleSheet, Modal, TextInput, TouchableOpacity, ScrollView, Switch, } from 'react-native'; import { Ionicons } from '@expo/vector-icons'; import DateTimePicker from '@react-native-community/datetimepicker'; import { theme } from '../theme'; import { Event } from '../types'; import { safeParseDate } from '../utils/recurrence'; interface EventModalProps { visible: boolean; event: Event | null; onClose: () => void; onSave: (event: Partial) => void; } export default function EventModal({ visible, event, onClose, onSave, }: EventModalProps) { const [title, setTitle] = useState(''); const [content, setContent] = useState(''); const [startDate, setStartDate] = useState(new Date()); const [endDate, setEndDate] = useState(null); const [enableReminder, setEnableReminder] = useState(true); const [remindDate, setRemindDate] = useState(new Date()); const [recurrenceType, setRecurrenceType] = useState<'NONE' | 'DAILY' | 'WEEKLY'>('NONE'); const [showStartPicker, setShowStartPicker] = useState(false); const [showEndPicker, setShowEndPicker] = useState(false); const [showRemindPicker, setShowRemindPicker] = useState(false); useEffect(() => { if (event) { setTitle(event.title); setContent(event.content || ''); setStartDate(safeParseDate(event.start)); setEndDate(event.end ? safeParseDate(event.end) : null); setEnableReminder(!!event.remindAt); setRemindDate(event.remindAt ? safeParseDate(event.remindAt) : new Date()); if (event.recurrence?.startsWith('DAILY')) { setRecurrenceType('DAILY'); } else if (event.recurrence?.startsWith('WEEKLY')) { setRecurrenceType('WEEKLY'); } else { setRecurrenceType('NONE'); } } else { resetForm(); } }, [event, visible]); const resetForm = () => { setTitle(''); setContent(''); setStartDate(new Date()); setEndDate(null); setEnableReminder(true); setRemindDate(new Date()); setRecurrenceType('NONE'); }; const handleSave = () => { if (!title.trim()) { alert('请输入标题'); return; } let recurrence = ''; if (recurrenceType === 'DAILY') { recurrence = 'DAILY;interval=1'; } else if (recurrenceType === 'WEEKLY') { recurrence = 'WEEKLY;interval=1'; } const eventData: Partial = { title: title.trim(), content: content.trim(), start: startDate.toISOString(), end: endDate ? endDate.toISOString() : null, allDay: false, remindAt: enableReminder ? remindDate.toISOString() : null, recurrence: recurrence || null, completed: event?.completed || false, }; onSave(eventData); }; const formatDate = (date: Date) => { return date.toLocaleDateString('zh-CN', { year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', }); }; return ( {event ? '编辑事件' : '新建事件'} 保存 标题 内容 开始时间 setShowStartPicker(true)} > {formatDate(startDate)} 结束时间(可选) setShowEndPicker(true)} > {endDate ? formatDate(endDate) : '未设置'} {endDate && ( setEndDate(null)} style={styles.clearButton} > )} 启用提醒 {enableReminder && ( 提醒时间 setShowRemindPicker(true)} > {formatDate(remindDate)} )} 重复 {[ { label: '不重复', value: 'NONE' }, { label: '每天', value: 'DAILY' }, { label: '每周', value: 'WEEKLY' }, ].map((option) => ( setRecurrenceType(option.value as any)} > {option.label} ))} {showStartPicker && ( { setShowStartPicker(false); if (date) setStartDate(date); }} /> )} {showEndPicker && ( { setShowEndPicker(false); if (date) setEndDate(date); }} /> )} {showRemindPicker && ( { setShowRemindPicker(false); if (date) setRemindDate(date); }} /> )} ); } const styles = StyleSheet.create({ overlay: { flex: 1, backgroundColor: 'rgba(0, 0, 0, 0.5)', justifyContent: 'flex-end', }, container: { backgroundColor: theme.colors.background, borderTopLeftRadius: theme.borderRadius.xl, borderTopRightRadius: theme.borderRadius.xl, maxHeight: '90%', }, header: { flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', padding: theme.spacing.md, borderBottomWidth: 1, borderBottomColor: theme.colors.border, }, headerTitle: { ...theme.typography.h3, color: theme.colors.text, }, saveButton: { ...theme.typography.body, color: theme.colors.primary, fontWeight: '600', }, content: { padding: theme.spacing.md, }, field: { marginBottom: theme.spacing.lg, }, label: { ...theme.typography.body, color: theme.colors.text, marginBottom: theme.spacing.sm, }, input: { backgroundColor: theme.colors.surface, borderRadius: theme.borderRadius.md, padding: theme.spacing.md, color: theme.colors.text, fontSize: 16, }, textArea: { height: 100, textAlignVertical: 'top', }, dateButton: { backgroundColor: theme.colors.surface, borderRadius: theme.borderRadius.md, padding: theme.spacing.md, flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', }, dateButtonText: { ...theme.typography.body, color: theme.colors.text, }, clearButton: { marginLeft: theme.spacing.sm, }, switchField: { flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', marginBottom: theme.spacing.lg, }, recurrenceOptions: { flexDirection: 'row', gap: theme.spacing.sm, }, recurrenceButton: { flex: 1, paddingVertical: theme.spacing.sm, paddingHorizontal: theme.spacing.md, backgroundColor: theme.colors.surface, borderRadius: theme.borderRadius.md, alignItems: 'center', borderWidth: 1, borderColor: theme.colors.border, }, recurrenceButtonActive: { borderColor: theme.colors.primary, backgroundColor: theme.colors.surfaceVariant, }, recurrenceButtonText: { ...theme.typography.bodySmall, color: theme.colors.text, }, recurrenceButtonTextActive: { color: theme.colors.primary, fontWeight: '600', }, });