|
|
|
|
@ -76,6 +76,8 @@ export default function TaskDetailScreen() {
|
|
|
|
|
const [recurrence, setRecurrence] = useState<string | null>(null);
|
|
|
|
|
const [subtasks, setSubtasks] = useState<SubtaskData[]>([]);
|
|
|
|
|
const [newSubtask, setNewSubtask] = useState('');
|
|
|
|
|
const [editingSubtaskId, setEditingSubtaskId] = useState<string | null>(null);
|
|
|
|
|
const [editingTitle, setEditingTitle] = useState('');
|
|
|
|
|
const [availableTags, setAvailableTags] = useState<{ id: string; name: string; color: string }[]>([]);
|
|
|
|
|
const [selectedTagIds, setSelectedTagIds] = useState<string[]>([]);
|
|
|
|
|
const [lists, setLists] = useState<{ id: string; name: string; color: string | null; icon: string | null; isInbox: boolean }[]>([]);
|
|
|
|
|
@ -162,6 +164,38 @@ export default function TaskDetailScreen() {
|
|
|
|
|
loadSubtasks();
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const handleEditSubtask = (sub: SubtaskData) => {
|
|
|
|
|
setEditingSubtaskId(sub.id);
|
|
|
|
|
setEditingTitle(sub.title);
|
|
|
|
|
Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const handleSaveSubtaskEdit = async () => {
|
|
|
|
|
if (!editingSubtaskId) return;
|
|
|
|
|
const trimmed = editingTitle.trim();
|
|
|
|
|
if (trimmed) {
|
|
|
|
|
await updateTask(editingSubtaskId, { title: trimmed });
|
|
|
|
|
loadSubtasks();
|
|
|
|
|
}
|
|
|
|
|
setEditingSubtaskId(null);
|
|
|
|
|
setEditingTitle('');
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const handleDeleteSubtask = (subtaskId: string) => {
|
|
|
|
|
Alert.alert(t('task.deleteSubtaskConfirm'), '', [
|
|
|
|
|
{ text: t('common.cancel'), style: 'cancel' },
|
|
|
|
|
{
|
|
|
|
|
text: t('common.delete'),
|
|
|
|
|
style: 'destructive',
|
|
|
|
|
onPress: async () => {
|
|
|
|
|
await deleteTask(subtaskId);
|
|
|
|
|
Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Medium);
|
|
|
|
|
loadSubtasks();
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
]);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const handleDateChange = (_: DateTimePickerEvent, date?: Date) => {
|
|
|
|
|
setShowDatePicker(Platform.OS === 'ios');
|
|
|
|
|
if (date) setDueDate(date);
|
|
|
|
|
@ -373,7 +407,8 @@ export default function TaskDetailScreen() {
|
|
|
|
|
{subtasks.map((sub) => (
|
|
|
|
|
<Pressable
|
|
|
|
|
key={sub.id}
|
|
|
|
|
onPress={() => handleToggleSubtask(sub.id)}
|
|
|
|
|
onPress={() => editingSubtaskId === sub.id ? undefined : handleToggleSubtask(sub.id)}
|
|
|
|
|
onLongPress={() => handleEditSubtask(sub)}
|
|
|
|
|
className={`flex-row items-center border-b py-2.5 ${isDark ? 'border-[#3A3A3A]' : 'border-[#E5E7EB]'}`}
|
|
|
|
|
>
|
|
|
|
|
<View
|
|
|
|
|
@ -385,12 +420,31 @@ export default function TaskDetailScreen() {
|
|
|
|
|
>
|
|
|
|
|
{sub.completed && <Text className="text-xs text-white" style={{ fontFamily: 'Inter_700Bold' }}>✓</Text>}
|
|
|
|
|
</View>
|
|
|
|
|
<Text
|
|
|
|
|
className={`text-base ${sub.completed ? 'line-through ' + (isDark ? 'text-[#A0A0A0]' : 'text-[#9CA3AF]') : isDark ? 'text-[#F5F5F5]' : 'text-[#1A1A1A]'}`}
|
|
|
|
|
style={{ fontFamily: 'Inter_400Regular' }}
|
|
|
|
|
{editingSubtaskId === sub.id ? (
|
|
|
|
|
<TextInput
|
|
|
|
|
value={editingTitle}
|
|
|
|
|
onChangeText={setEditingTitle}
|
|
|
|
|
onSubmitEditing={handleSaveSubtaskEdit}
|
|
|
|
|
onBlur={handleSaveSubtaskEdit}
|
|
|
|
|
autoFocus
|
|
|
|
|
className={`flex-1 text-base ${isDark ? 'text-[#F5F5F5]' : 'text-[#1A1A1A]'}`}
|
|
|
|
|
style={{ fontFamily: 'Inter_400Regular' }}
|
|
|
|
|
/>
|
|
|
|
|
) : (
|
|
|
|
|
<Text
|
|
|
|
|
className={`flex-1 text-base ${sub.completed ? 'line-through ' + (isDark ? 'text-[#A0A0A0]' : 'text-[#9CA3AF]') : isDark ? 'text-[#F5F5F5]' : 'text-[#1A1A1A]'}`}
|
|
|
|
|
style={{ fontFamily: 'Inter_400Regular' }}
|
|
|
|
|
>
|
|
|
|
|
{sub.title}
|
|
|
|
|
</Text>
|
|
|
|
|
)}
|
|
|
|
|
<Pressable
|
|
|
|
|
onPress={() => handleDeleteSubtask(sub.id)}
|
|
|
|
|
className="ml-2 p-1.5"
|
|
|
|
|
hitSlop={{ top: 8, bottom: 8, left: 8, right: 8 }}
|
|
|
|
|
>
|
|
|
|
|
{sub.title}
|
|
|
|
|
</Text>
|
|
|
|
|
<X size={16} color={isDark ? '#A0A0A0' : '#9CA3AF'} />
|
|
|
|
|
</Pressable>
|
|
|
|
|
</Pressable>
|
|
|
|
|
))}
|
|
|
|
|
|
|
|
|
|
|