@@ -4,7 +4,7 @@ import { CreateGoalRequest, GoalPriority, RepeatType } from '@/types/goals';
import { Ionicons } from '@expo/vector-icons' ;
import DateTimePicker from '@react-native-community/datetimepicker' ;
import { LinearGradient } from 'expo-linear-gradient' ;
import React , { useState , useEffect } from 'react' ;
import React , { useEffect , useState } from 'react' ;
import {
Alert ,
Image ,
@@ -71,6 +71,11 @@ export const CreateGoalModal: React.FC<CreateGoalModalProps> = ({
initialData ? . customRepeatRule ? . dayOfMonth || [ 1 , 15 ]
) ; // 默认1号和15号
// 结束日期选择状态
const [ endDate , setEndDate ] = useState < string | null > ( initialData ? . endDate || null ) ;
const [ showDatePicker , setShowDatePicker ] = useState ( false ) ;
const [ tempSelectedDate , setTempSelectedDate ] = useState < Date | null > ( null ) ;
// 当 initialData 变化时更新表单状态
useEffect ( ( ) = > {
if ( initialData ) {
@@ -84,6 +89,7 @@ export const CreateGoalModal: React.FC<CreateGoalModalProps> = ({
setPriority ( initialData . priority || 5 ) ;
setSelectedWeekdays ( initialData . customRepeatRule ? . weekdays || [ 1 , 2 , 3 , 4 , 5 ] ) ;
setSelectedMonthDays ( initialData . customRepeatRule ? . dayOfMonth || [ 1 , 15 ] ) ;
setEndDate ( initialData . endDate || null ) ;
}
} , [ initialData ] ) ;
@@ -99,6 +105,7 @@ export const CreateGoalModal: React.FC<CreateGoalModalProps> = ({
setPriority ( 5 ) ;
setSelectedWeekdays ( [ 1 , 2 , 3 , 4 , 5 ] ) ;
setSelectedMonthDays ( [ 1 , 15 ] ) ;
setEndDate ( null ) ;
} ;
// 处理关闭
@@ -139,6 +146,7 @@ export const CreateGoalModal: React.FC<CreateGoalModalProps> = ({
dayOfMonth : repeatType === 'monthly' ? selectedMonthDays : undefined , // 根据重复类型设置月几
} ,
startTime ,
endDate : endDate || undefined ,
} ;
console . log ( 'goalData' , goalData ) ;
@@ -196,6 +204,55 @@ export const CreateGoalModal: React.FC<CreateGoalModalProps> = ({
return date ;
} ;
// 日期选择器处理
const handleDateChange = ( event : any , selectedDate? : Date ) = > {
if ( Platform . OS === 'android' ) {
if ( event . type === 'set' && selectedDate ) {
const isoDate = selectedDate . toISOString ( ) . split ( 'T' ) [ 0 ] ;
setEndDate ( isoDate ) ;
}
setShowDatePicker ( false ) ;
} else {
if ( selectedDate ) {
setTempSelectedDate ( selectedDate ) ;
}
}
} ;
const handleConfirmDate = ( ) = > {
setShowDatePicker ( false ) ;
if ( tempSelectedDate ) {
const isoDate = tempSelectedDate . toISOString ( ) . split ( 'T' ) [ 0 ] ;
setEndDate ( isoDate ) ;
}
setTempSelectedDate ( null ) ;
} ;
const handleCancelDate = ( ) = > {
setShowDatePicker ( false ) ;
setTempSelectedDate ( null ) ;
} ;
const showDatePickerModal = ( ) = > {
setShowDatePicker ( true ) ;
} ;
// 获取当前结束日期对应的Date对象
const getCurrentEndDate = ( ) = > {
if ( endDate ) {
return new Date ( endDate + 'T00:00:00' ) ;
}
const tomorrow = new Date ( ) ;
tomorrow . setDate ( tomorrow . getDate ( ) + 1 ) ;
return tomorrow ;
} ;
// 格式化显示日期
const formatDisplayDate = ( dateString : string ) = > {
const date = new Date ( dateString + 'T00:00:00' ) ;
return ` ${ date . getFullYear ( ) } 年 ${ ( date . getMonth ( ) + 1 ) . toString ( ) . padStart ( 2 , '0' ) } 月 ${ date . getDate ( ) . toString ( ) . padStart ( 2 , '0' ) } 日 ` ;
} ;
return (
< Modal
visible = { visible }
@@ -268,10 +325,10 @@ export const CreateGoalModal: React.FC<CreateGoalModalProps> = ({
? ` ${ REPEAT_TYPE_OPTIONS . find ( opt = > opt . value === repeatType ) ? . label } ${ selectedWeekdays . map ( day = > [ '周日' , '周一' , '周二' , '周三' , '周四' , '周五' , '周六' ] [ day ] ) . join ( ' ' ) } `
: ` ${ REPEAT_TYPE_OPTIONS . find ( opt = > opt . value === repeatType ) ? . label } ${ selectedWeekdays . slice ( 0 , 2 ) . map ( day = > [ '周日' , '周一' , '周二' , '周三' , '周四' , '周五' , '周六' ] [ day ] ) . join ( ' ' ) } 等 ${ selectedWeekdays . length } 天 `
: repeatType === 'monthly' && selectedMonthDays . length > 0
? selectedMonthDays . length <= 3
? ` ${ REPEAT_TYPE_OPTIONS . find ( opt = > opt . value === repeatType ) ? . label } ${ selectedMonthDays . map ( day = > ` ${ day } 号 ` ) . join ( ' ' ) } `
: ` ${ REPEAT_TYPE_OPTIONS . find ( opt = > opt . value === repeatType ) ? . label } ${ selectedMonthDays . slice ( 0 , 2 ) . map ( day = > ` ${ day } 号 ` ) . join ( ' ' ) } 等 ${ selectedMonthDays . length } 天 `
: REPEAT_TYPE_OPTIONS . find ( opt = > opt . value === repeatType ) ? . label
? selectedMonthDays . length <= 3
? ` ${ REPEAT_TYPE_OPTIONS . find ( opt = > opt . value === repeatType ) ? . label } ${ selectedMonthDays . map ( day = > ` ${ day } 号 ` ) . join ( ' ' ) } `
: ` ${ REPEAT_TYPE_OPTIONS . find ( opt = > opt . value === repeatType ) ? . label } ${ selectedMonthDays . slice ( 0 , 2 ) . map ( day = > ` ${ day } 号 ` ) . join ( ' ' ) } 等 ${ selectedMonthDays . length } 天 `
: REPEAT_TYPE_OPTIONS . find ( opt = > opt . value === repeatType ) ? . label
}
< / Text >
< Text style = { [ styles . chevron , { color : colorTokens.textSecondary } ] } >
@@ -414,9 +471,9 @@ export const CreateGoalModal: React.FC<CreateGoalModalProps> = ({
< View style = { styles . optionHeader } >
< View style = { styles . optionIcon } >
< Image
source = { require ( '@/assets/images/icons/icon-fire.png' ) }
style = { styles . optionIconImage }
/ >
source = { require ( '@/assets/images/icons/icon-fire.png' ) }
style = { styles . optionIconImage }
/ >
< / View >
< Text style = { [ styles . optionLabel , { color : colorTokens.text } ] } >
频 率
@@ -480,9 +537,9 @@ export const CreateGoalModal: React.FC<CreateGoalModalProps> = ({
< View style = { styles . optionHeader } >
< View style = { styles . optionIcon } >
< Image
source = { require ( '@/assets/images/icons/icon-bell.png' ) }
style = { styles . optionIconImage }
/ >
source = { require ( '@/assets/images/icons/icon-bell.png' ) }
style = { styles . optionIconImage }
/ >
< / View >
< Text style = { [ styles . optionLabel , { color : colorTokens.text } ] } >
提 醒
@@ -501,9 +558,9 @@ export const CreateGoalModal: React.FC<CreateGoalModalProps> = ({
< View style = { styles . optionHeader } >
< View style = { styles . optionIcon } >
< Image
source = { require ( '@/assets/images/icons/icon-clock.png' ) }
style = { styles . optionIconImage }
/ >
source = { require ( '@/assets/images/icons/icon-clock.png' ) }
style = { styles . optionIconImage }
/ >
< / View >
< Text style = { [ styles . optionLabel , { color : colorTokens.text } ] } >
时 间
@@ -522,6 +579,40 @@ export const CreateGoalModal: React.FC<CreateGoalModalProps> = ({
< / View >
< / View >
{ /* 结束日期设置 */ }
< View style = { [ styles . optionCard , { backgroundColor : colorTokens.card } ] } >
< View style = { styles . optionHeader } >
< View style = { styles . optionIcon } >
< Image
source = { require ( '@/assets/images/icons/icon-calender.png' ) }
style = { styles . optionIconImage }
/ >
< / View >
< Text style = { [ styles . optionLabel , { color : colorTokens.text } ] } >
结 束 日 期
< / Text >
< TouchableOpacity
style = { [ styles . optionValue ] }
onPress = { showDatePickerModal }
>
< Text style = { [ styles . optionValueText , { color : colorTokens.textSecondary } ] } >
{ endDate ? formatDisplayDate ( endDate ) : '无限制' }
< / Text >
< Text style = { [ styles . chevron , { color : colorTokens.textSecondary } ] } >
›
< / Text >
< / TouchableOpacity >
< / View >
{ endDate && (
< TouchableOpacity
style = { styles . clearEndDateButton }
onPress = { ( ) = > setEndDate ( null ) }
>
< Text style = { styles . clearEndDateText } > 清 除 结 束 日 期 < / Text >
< / TouchableOpacity >
) }
< / View >
{ /* 时间选择器弹窗 */ }
< Modal
visible = { showTimePicker }
@@ -561,6 +652,46 @@ export const CreateGoalModal: React.FC<CreateGoalModalProps> = ({
< / View >
< / Modal >
{ /* 日期选择器弹窗 */ }
< Modal
visible = { showDatePicker }
transparent
animationType = "fade"
onRequestClose = { ( ) = > setShowDatePicker ( false ) }
>
< TouchableOpacity
style = { styles . modalBackdrop }
activeOpacity = { 1 }
onPress = { handleCancelDate }
/ >
< View style = { styles . modalSheet } >
< DateTimePicker
value = { tempSelectedDate || getCurrentEndDate ( ) }
mode = "date"
display = { Platform . OS === 'ios' ? 'calendar' : 'default' }
onChange = { handleDateChange }
minimumDate = { new Date ( ) }
locale = "zh-CN"
/ >
{ Platform . OS === 'ios' && (
< View style = { styles . modalActions } >
< TouchableOpacity
style = { [ styles . modalBtn ] }
onPress = { handleCancelDate }
>
< Text style = { styles . modalBtnText } > 取 消 < / Text >
< / TouchableOpacity >
< TouchableOpacity
style = { [ styles . modalBtn , styles . modalBtnPrimary ] }
onPress = { handleConfirmDate }
>
< Text style = { [ styles . modalBtnText , styles . modalBtnTextPrimary ] } > 确 定 < / Text >
< / TouchableOpacity >
< / View >
) }
< / View >
< / Modal >
{ /* 描述输入(可选) */ }
< View style = { [ styles . optionCard , { backgroundColor : colorTokens.card } ] } >
< TextInput
@@ -933,6 +1064,19 @@ const styles = StyleSheet.create({
fontSize : 16 ,
fontWeight : '600' ,
} ,
// 清除结束日期按钮样式
clearEndDateButton : {
paddingHorizontal : 16 ,
paddingVertical : 8 ,
alignItems : 'center' ,
borderTopWidth : 1 ,
borderTopColor : '#F1F5F9' ,
} ,
clearEndDateText : {
color : '#EF4444' ,
fontSize : 14 ,
fontWeight : '500' ,
} ,
} ) ;
export default CreateGoalModal ;