Files
digital-pilates/components/CreateGoalModal.tsx
richarjiang 4382fb804f feat: 新增目标创建弹窗的重复周期选择功能
- 在目标创建弹窗中添加重复周期选择功能,支持用户选择每日、每周和每月的重复类型
- 实现每周和每月的具体日期选择,用户可自定义选择周几和每月的日期
- 更新相关样式,提升用户体验和界面美观性
- 新增图标资源,替换原有文本图标,增强视觉效果
2025-08-23 15:58:37 +08:00

916 lines
28 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { Colors } from '@/constants/Colors';
import { useColorScheme } from '@/hooks/useColorScheme';
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 } from 'react';
import {
Alert,
Image,
Modal,
Platform,
ScrollView,
StyleSheet,
Switch,
Text,
TextInput,
TouchableOpacity,
View,
} from 'react-native';
import WheelPickerExpo from 'react-native-wheel-picker-expo';
interface CreateGoalModalProps {
visible: boolean;
onClose: () => void;
onSubmit: (goalData: CreateGoalRequest) => void;
onSuccess?: () => void;
loading?: boolean;
}
const REPEAT_TYPE_OPTIONS: { value: RepeatType; label: string }[] = [
{ value: 'daily', label: '每日' },
{ value: 'weekly', label: '每周' },
{ value: 'monthly', label: '每月' },
];
const FREQUENCY_OPTIONS = Array.from({ length: 30 }, (_, i) => i + 1);
export const CreateGoalModal: React.FC<CreateGoalModalProps> = ({
visible,
onClose,
onSubmit,
onSuccess,
loading = false,
}) => {
const theme = (useColorScheme() ?? 'light') as 'light' | 'dark';
const colorTokens = Colors[theme];
// 表单状态
const [title, setTitle] = useState('');
const [description, setDescription] = useState('');
const [repeatType, setRepeatType] = useState<RepeatType>('daily');
const [frequency, setFrequency] = useState(1);
const [hasReminder, setHasReminder] = useState(false);
const [showFrequencyPicker, setShowFrequencyPicker] = useState(false);
const [showRepeatTypePicker, setShowRepeatTypePicker] = useState(false);
const [reminderTime, setReminderTime] = useState('20:00');
const [category, setCategory] = useState('');
const [priority, setPriority] = useState<GoalPriority>(5);
const [showTimePicker, setShowTimePicker] = useState(false);
const [tempSelectedTime, setTempSelectedTime] = useState<Date | null>(null);
// 周几选择状态
const [selectedWeekdays, setSelectedWeekdays] = useState<number[]>([1, 2, 3, 4, 5]); // 默认周一到周五
// 每月日期选择状态
const [selectedMonthDays, setSelectedMonthDays] = useState<number[]>([1, 15]); // 默认1号和15号
// 重置表单
const resetForm = () => {
setTitle('');
setDescription('');
setRepeatType('daily');
setFrequency(1);
setHasReminder(false);
setReminderTime('20:00');
setCategory('');
setPriority(5);
setSelectedWeekdays([1, 2, 3, 4, 5]);
setSelectedMonthDays([1, 15]);
};
// 处理关闭
const handleClose = () => {
if (!loading) {
resetForm();
onClose();
}
};
// 处理提交
const handleSubmit = () => {
if (!title.trim()) {
Alert.alert('提示', '请输入目标标题');
return;
}
// 计算startTime从reminderTime中获取小时和分钟转换为当天的分钟数
let startTime: number | undefined;
if (reminderTime) {
const [hours, minutes] = reminderTime.split(':').map(Number);
startTime = hours * 60 + minutes;
}
const goalData: CreateGoalRequest = {
title: title.trim(),
description: description.trim() || undefined,
repeatType,
frequency,
category: category.trim() || undefined,
priority,
hasReminder,
reminderTime: hasReminder ? reminderTime : undefined,
customRepeatRule: {
weekdays: repeatType === 'weekly' ? selectedWeekdays : [1, 2, 3, 4, 5, 6, 0], // 根据重复类型设置周几
dayOfMonth: repeatType === 'monthly' ? selectedMonthDays : undefined, // 根据重复类型设置月几
},
startTime,
};
console.log('goalData', goalData);
onSubmit(goalData);
// 通知父组件提交成功
if (onSuccess) {
onSuccess();
}
};
// 时间选择器
const handleTimeChange = (event: any, selectedDate?: Date) => {
if (Platform.OS === 'android') {
// Android: 用户点击系统确认按钮后自动关闭
if (event.type === 'set' && selectedDate) {
const hours = selectedDate.getHours().toString().padStart(2, '0');
const minutes = selectedDate.getMinutes().toString().padStart(2, '0');
setReminderTime(`${hours}:${minutes}`);
}
setShowTimePicker(false);
} else {
// iOS: 只在用户点击自定义确认按钮时更新
if (selectedDate) {
setTempSelectedTime(selectedDate);
}
}
};
const handleConfirmTime = () => {
setShowTimePicker(false);
if (tempSelectedTime) {
const hours = tempSelectedTime.getHours().toString().padStart(2, '0');
const minutes = tempSelectedTime.getMinutes().toString().padStart(2, '0');
setReminderTime(`${hours}:${minutes}`);
}
setTempSelectedTime(null);
};
const handleCancelTime = () => {
setShowTimePicker(false);
setTempSelectedTime(null);
};
const showTimePickerModal = () => {
setShowTimePicker(true);
};
// 获取当前时间对应的Date对象
const getCurrentTimeDate = () => {
const [hours, minutes] = reminderTime.split(':').map(Number);
const date = new Date();
date.setHours(hours, minutes, 0, 0);
return date;
};
return (
<Modal
visible={visible}
animationType="slide"
presentationStyle="pageSheet"
onRequestClose={handleClose}
>
<View style={[styles.container, { backgroundColor: colorTokens.background }]}>
{/* 渐变背景 */}
<LinearGradient
colors={['#F0F9FF', '#E0F2FE']}
style={styles.gradientBackground}
start={{ x: 0, y: 0 }}
end={{ x: 1, y: 1 }}
/>
{/* 装饰性圆圈 */}
<View style={styles.decorativeCircle1} />
<View style={styles.decorativeCircle2} />
{/* 头部 */}
<View style={styles.header}>
<TouchableOpacity onPress={handleClose} disabled={loading}>
<Ionicons name="close" size={24} color={colorTokens.text} />
</TouchableOpacity>
<Text style={[styles.title, { color: colorTokens.text }]}>
</Text>
<View style={{ width: 24 }} />
</View>
<ScrollView style={styles.content} showsVerticalScrollIndicator={false}>
{/* 目标标题输入 */}
<View style={styles.section}>
<View style={styles.iconTitleContainer}>
{/* <View style={styles.iconPlaceholder}>
<Text style={styles.iconText}>图标</Text>
</View> */}
<TextInput
style={[styles.titleInput, { color: colorTokens.text }]}
placeholder="写点什么..."
// placeholderTextColor={colorTokens.textSecondary}
value={title}
onChangeText={setTitle}
multiline
maxLength={100}
/>
</View>
{/* 装饰图案 */}
<View style={styles.decorationContainer}>
<View style={styles.decoration} />
</View>
</View>
{/* 目标重复周期 */}
<View style={[styles.optionCard, { backgroundColor: colorTokens.card }]}>
<TouchableOpacity style={styles.optionValue} onPress={() => setShowRepeatTypePicker(true)}>
<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>
<Text style={[styles.optionValueText, { color: colorTokens.textSecondary }]}>
{repeatType === 'weekly' && selectedWeekdays.length > 0
? selectedWeekdays.length <= 3
? `${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
}
</Text>
<Text style={[styles.chevron, { color: colorTokens.textSecondary }]}>
</Text>
</View>
</TouchableOpacity>
</View>
{/* 重复周期选择器弹窗 */}
<Modal
visible={showRepeatTypePicker}
transparent
animationType="fade"
onRequestClose={() => setShowRepeatTypePicker(false)}
>
<TouchableOpacity
style={styles.modalBackdrop}
activeOpacity={1}
onPress={() => setShowRepeatTypePicker(false)}
/>
<View style={styles.repeatTypeModalSheet}>
{/* 关闭按钮 */}
<TouchableOpacity
style={styles.modalCloseButton}
onPress={() => setShowRepeatTypePicker(false)}
>
<Text style={styles.modalCloseButtonText}>×</Text>
</TouchableOpacity>
{/* 标题 */}
<Text style={styles.repeatTypeModalTitle}></Text>
{/* 重复类型选择 */}
<View style={styles.repeatTypeOptions}>
{REPEAT_TYPE_OPTIONS.map((option) => (
<TouchableOpacity
key={option.value}
style={[
styles.repeatTypeButton,
repeatType === option.value && styles.repeatTypeButtonSelected
]}
onPress={() => setRepeatType(option.value)}
>
<Text style={[
styles.repeatTypeButtonText,
repeatType === option.value && styles.repeatTypeButtonTextSelected
]}>
{option.label}
</Text>
</TouchableOpacity>
))}
</View>
{/* 周几选择 - 仅在选择每周时显示 */}
{repeatType === 'weekly' && (
<View style={styles.weekdaySelection}>
<View style={styles.weekdayOptions}>
{[
{ value: 0, label: '周日' },
{ value: 1, label: '周一' },
{ value: 2, label: '周二' },
{ value: 3, label: '周三' },
{ value: 4, label: '周四' },
{ value: 5, label: '周五' },
{ value: 6, label: '周六' },
].map((weekday) => (
<TouchableOpacity
key={weekday.value}
style={[
styles.weekdayButton,
selectedWeekdays.includes(weekday.value) && styles.weekdayButtonSelected
]}
onPress={() => {
if (selectedWeekdays.includes(weekday.value)) {
setSelectedWeekdays(selectedWeekdays.filter(day => day !== weekday.value));
} else {
setSelectedWeekdays([...selectedWeekdays, weekday.value]);
}
}}
>
<Text style={[
styles.weekdayButtonText,
selectedWeekdays.includes(weekday.value) && styles.weekdayButtonTextSelected
]}>
{weekday.label}
</Text>
</TouchableOpacity>
))}
</View>
</View>
)}
{/* 每月日期选择 - 仅在选择每月时显示 */}
{repeatType === 'monthly' && (
<View style={styles.monthDaySelection}>
<View style={styles.monthDayGrid}>
{Array.from({ length: 31 }, (_, i) => i + 1).map((day) => (
<TouchableOpacity
key={day}
style={[
styles.monthDayGridItem,
selectedMonthDays.includes(day) && styles.monthDayGridItemSelected
]}
onPress={() => {
if (selectedMonthDays.includes(day)) {
setSelectedMonthDays(selectedMonthDays.filter(d => d !== day));
} else {
setSelectedMonthDays([...selectedMonthDays, day]);
}
}}
activeOpacity={0.8}
>
<Text style={[
styles.monthDayGridText,
selectedMonthDays.includes(day) && styles.monthDayGridTextSelected
]}>
{day}
</Text>
</TouchableOpacity>
))}
</View>
</View>
)}
{/* 完成按钮 */}
<TouchableOpacity
style={styles.repeatTypeCompleteButton}
onPress={() => setShowRepeatTypePicker(false)}
>
<Text style={styles.repeatTypeCompleteButtonText}></Text>
</TouchableOpacity>
</View>
</Modal>
{/* 频率设置 */}
<View style={[styles.optionCard, { backgroundColor: colorTokens.card }]}>
<TouchableOpacity style={styles.optionValue} onPress={() => setShowFrequencyPicker(true)}>
<View style={styles.optionHeader}>
<View style={styles.optionIcon}>
<Image
source={require('@/assets/images/icons/icon-fire.png')}
style={styles.optionIconImage}
/>
</View>
<Text style={[styles.optionLabel, { color: colorTokens.text }]}>
</Text>
<Text style={[styles.optionValueText, { color: colorTokens.textSecondary }]}>
{frequency}
</Text>
<Text style={[styles.chevron, { color: colorTokens.textSecondary }]}>
</Text>
</View>
</TouchableOpacity>
</View>
{/* 频率选择器弹窗 */}
<Modal
visible={showFrequencyPicker}
transparent
animationType="fade"
onRequestClose={() => setShowFrequencyPicker(false)}
>
<TouchableOpacity
style={styles.modalBackdrop}
activeOpacity={1}
onPress={() => setShowFrequencyPicker(false)}
/>
<View style={styles.modalSheet}>
<View style={{ height: 200 }}>
<WheelPickerExpo
height={200}
width={150}
initialSelectedIndex={frequency - 1}
items={FREQUENCY_OPTIONS.map(num => ({ label: num.toString(), value: num }))}
onChange={({ item }) => setFrequency(item.value)}
backgroundColor={colorTokens.card}
// selectedStyle={{ borderColor: colorTokens.primary, borderWidth: 2 }}
haptics
/>
</View>
{Platform.OS === 'ios' && (
<View style={styles.modalActions}>
<TouchableOpacity
style={[styles.modalBtn]}
onPress={() => setShowFrequencyPicker(false)}
>
<Text style={styles.modalBtnText}></Text>
</TouchableOpacity>
<TouchableOpacity
style={[styles.modalBtn, styles.modalBtnPrimary]}
onPress={() => setShowFrequencyPicker(false)}
>
<Text style={[styles.modalBtnText, styles.modalBtnTextPrimary]}></Text>
</TouchableOpacity>
</View>
)}
</View>
</Modal>
{/* 提醒设置 */}
<View style={[styles.optionCard, { backgroundColor: colorTokens.card }]}>
<View style={styles.optionHeader}>
<View style={styles.optionIcon}>
<Image
source={require('@/assets/images/icons/icon-bell.png')}
style={styles.optionIconImage}
/>
</View>
<Text style={[styles.optionLabel, { color: colorTokens.text }]}>
</Text>
<Switch
value={hasReminder}
onValueChange={setHasReminder}
trackColor={{ false: '#E5E5E5', true: '#6366F1' }}
thumbColor={hasReminder ? '#FFFFFF' : '#FFFFFF'}
/>
</View>
</View>
{/* 时间设置 */}
<View style={[styles.optionCard, { backgroundColor: colorTokens.card }]}>
<View style={styles.optionHeader}>
<View style={styles.optionIcon}>
<Image
source={require('@/assets/images/icons/icon-clock.png')}
style={styles.optionIconImage}
/>
</View>
<Text style={[styles.optionLabel, { color: colorTokens.text }]}>
</Text>
<TouchableOpacity
style={[styles.optionValue]}
onPress={showTimePickerModal}
>
<Text style={[styles.optionValueText, { color: colorTokens.textSecondary }]}>
{reminderTime}
</Text>
<Text style={[styles.chevron, { color: colorTokens.textSecondary }]}>
</Text>
</TouchableOpacity>
</View>
</View>
{/* 时间选择器弹窗 */}
<Modal
visible={showTimePicker}
transparent
animationType="fade"
onRequestClose={() => setShowTimePicker(false)}
>
<TouchableOpacity
style={styles.modalBackdrop}
activeOpacity={1}
onPress={handleCancelTime}
/>
<View style={styles.modalSheet}>
<DateTimePicker
value={tempSelectedTime || getCurrentTimeDate()}
mode="time"
is24Hour={true}
display={Platform.OS === 'ios' ? 'spinner' : 'default'}
onChange={handleTimeChange}
/>
{Platform.OS === 'ios' && (
<View style={styles.modalActions}>
<TouchableOpacity
style={[styles.modalBtn]}
onPress={handleCancelTime}
>
<Text style={styles.modalBtnText}></Text>
</TouchableOpacity>
<TouchableOpacity
style={[styles.modalBtn, styles.modalBtnPrimary]}
onPress={handleConfirmTime}
>
<Text style={[styles.modalBtnText, styles.modalBtnTextPrimary]}></Text>
</TouchableOpacity>
</View>
)}
</View>
</Modal>
{/* 描述输入(可选) */}
<View style={[styles.optionCard, { backgroundColor: colorTokens.card }]}>
<TextInput
style={[styles.descriptionInput, { color: colorTokens.text }]}
placeholder="添加描述(可选)"
placeholderTextColor={colorTokens.textSecondary}
value={description}
onChangeText={setDescription}
multiline
maxLength={500}
/>
</View>
</ScrollView>
{/* 保存按钮 */}
<View style={styles.footer}>
<TouchableOpacity
style={[
styles.saveButton,
{ opacity: loading || !title.trim() ? 0.5 : 1 }
]}
onPress={handleSubmit}
disabled={loading || !title.trim()}
>
<Text style={styles.saveButtonText}>
{loading ? '保存中...' : '保存'}
</Text>
</TouchableOpacity>
</View>
</View>
</Modal>
);
};
const styles = StyleSheet.create({
gradientBackground: {
position: 'absolute',
left: 0,
right: 0,
top: 0,
bottom: 0,
opacity: 0.6,
},
decorativeCircle1: {
position: 'absolute',
top: -20,
right: -20,
width: 60,
height: 60,
borderRadius: 30,
backgroundColor: '#0EA5E9',
opacity: 0.1,
},
decorativeCircle2: {
position: 'absolute',
bottom: -15,
left: -15,
width: 40,
height: 40,
borderRadius: 20,
backgroundColor: '#0EA5E9',
opacity: 0.05,
},
container: {
flex: 1,
},
header: {
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-between',
paddingHorizontal: 20,
paddingTop: 60,
paddingBottom: 20,
},
cancelButton: {
fontSize: 24,
fontWeight: '600',
},
title: {
fontSize: 18,
fontWeight: '600',
},
content: {
flex: 1,
paddingHorizontal: 20,
},
section: {
},
iconTitleContainer: {
flexDirection: 'row',
alignItems: 'flex-start',
backgroundColor: '#FFFFFF',
borderRadius: 16,
padding: 16,
},
iconPlaceholder: {
width: 60,
height: 60,
borderRadius: 30,
backgroundColor: '#F3F4F6',
alignItems: 'center',
justifyContent: 'center',
marginRight: 16,
},
iconText: {
fontSize: 12,
color: '#9CA3AF',
fontWeight: '500',
},
titleInput: {
flex: 1,
fontSize: 16,
fontWeight: '500',
minHeight: 60,
textAlignVertical: 'top',
},
decorationContainer: {
alignItems: 'flex-end',
paddingRight: 20,
},
decoration: {
width: 80,
height: 60,
backgroundColor: '#E0E7FF',
borderRadius: 40,
opacity: 0.6,
},
optionCard: {
borderRadius: 16,
marginBottom: 12,
overflow: 'hidden',
},
optionHeader: {
flexDirection: 'row',
alignItems: 'center',
padding: 16,
},
optionIcon: {
width: 32,
height: 32,
borderRadius: 16,
backgroundColor: '#F3F4F6',
alignItems: 'center',
justifyContent: 'center',
marginRight: 12,
},
optionIconText: {
fontSize: 16,
},
optionIconImage: {
width: 20,
height: 20,
resizeMode: 'contain',
},
optionLabel: {
flex: 1,
fontSize: 16,
fontWeight: '500',
},
optionValue: {
flexDirection: 'row',
alignItems: 'center',
},
optionValueText: {
fontSize: 16,
fontWeight: '500',
marginRight: 8,
},
chevron: {
fontSize: 20,
fontWeight: '300',
},
descriptionInput: {
padding: 16,
fontSize: 16,
minHeight: 80,
textAlignVertical: 'top',
},
footer: {
padding: 20,
paddingBottom: 40,
},
saveButton: {
backgroundColor: '#6366F1',
borderRadius: 16,
paddingVertical: 16,
alignItems: 'center',
},
saveButtonText: {
color: '#FFFFFF',
fontSize: 18,
fontWeight: '600',
},
modalBackdrop: {
...StyleSheet.absoluteFillObject,
backgroundColor: 'rgba(0,0,0,0.35)',
},
modalSheet: {
position: 'absolute',
left: 0,
right: 0,
bottom: 0,
padding: 16,
backgroundColor: '#FFFFFF',
justifyContent: 'center',
alignItems: 'center',
borderTopLeftRadius: 16,
borderTopRightRadius: 16,
},
modalActions: {
flexDirection: 'row',
justifyContent: 'flex-end',
marginTop: 8,
gap: 12,
},
modalBtn: {
paddingHorizontal: 14,
paddingVertical: 10,
borderRadius: 10,
backgroundColor: '#F1F5F9',
},
modalBtnPrimary: {
backgroundColor: '#6366F1',
},
modalBtnText: {
color: '#334155',
fontWeight: '700',
},
modalBtnTextPrimary: {
color: '#FFFFFF',
fontWeight: '700',
},
// 重复类型选择器弹窗样式
repeatTypeModalSheet: {
position: 'absolute',
left: 20,
right: 20,
top: '50%',
transform: [{ translateY: -300 }],
backgroundColor: '#FFFFFF',
borderRadius: 16,
padding: 24,
alignItems: 'center',
maxHeight: 500,
},
modalCloseButton: {
position: 'absolute',
top: 16,
left: 16,
width: 24,
height: 24,
alignItems: 'center',
justifyContent: 'center',
},
modalCloseButtonText: {
fontSize: 20,
color: '#666666',
fontWeight: '300',
},
repeatTypeModalTitle: {
fontSize: 18,
fontWeight: '600',
color: '#333333',
marginBottom: 20,
textAlign: 'center',
},
repeatTypeOptions: {
flexDirection: 'row',
flexWrap: 'wrap',
justifyContent: 'center',
gap: 8,
marginBottom: 20,
},
repeatTypeButton: {
paddingHorizontal: 16,
paddingVertical: 10,
borderRadius: 20,
backgroundColor: '#F5F5F5',
borderWidth: 1,
borderColor: '#E5E5E5',
marginHorizontal: 4,
},
repeatTypeButtonSelected: {
backgroundColor: '#E6E6FA',
borderColor: '#8A2BE2',
},
repeatTypeButtonText: {
fontSize: 14,
color: '#666666',
fontWeight: '500',
},
repeatTypeButtonTextSelected: {
color: '#8A2BE2',
fontWeight: '600',
},
weekdaySelection: {
width: '100%',
marginBottom: 20,
},
weekdayOptions: {
flexDirection: 'row',
flexWrap: 'wrap',
justifyContent: 'center',
gap: 6,
},
weekdayButton: {
paddingHorizontal: 12,
paddingVertical: 8,
borderRadius: 16,
backgroundColor: '#F5F5F5',
borderWidth: 1,
borderColor: '#E5E5E5',
marginHorizontal: 2,
},
weekdayButtonSelected: {
backgroundColor: '#8A2BE2',
borderColor: '#8A2BE2',
},
weekdayButtonText: {
fontSize: 12,
color: '#666666',
fontWeight: '500',
},
weekdayButtonTextSelected: {
color: '#FFFFFF',
fontWeight: '600',
},
// 每月日期选择样式 - 日历网格布局
monthDaySelection: {
width: '100%',
marginBottom: 20,
},
monthDayGrid: {
flexDirection: 'row',
flexWrap: 'wrap',
justifyContent: 'flex-start',
paddingHorizontal: 8,
},
monthDayGridItem: {
width: 36,
height: 36,
borderRadius: 18,
backgroundColor: '#F5F5F5',
alignItems: 'center',
justifyContent: 'center',
marginBottom: 10,
marginRight: 8,
},
monthDayGridItemSelected: {
backgroundColor: '#8A2BE2',
},
monthDayGridText: {
fontSize: 12,
fontWeight: '600',
color: '#666666',
},
monthDayGridTextSelected: {
color: '#FFFFFF',
},
repeatTypeCompleteButton: {
width: '100%',
backgroundColor: '#8A2BE2',
borderRadius: 20,
paddingVertical: 14,
alignItems: 'center',
marginTop: 10,
},
repeatTypeCompleteButtonText: {
color: '#FFFFFF',
fontSize: 16,
fontWeight: '600',
},
});
export default CreateGoalModal;