129 lines
5.0 KiB
TypeScript
129 lines
5.0 KiB
TypeScript
import { Alert, ColorSchemeName, Pressable, StyleSheet, useColorScheme, type ViewProps } from 'react-native';
|
|
|
|
import { Text } from '@react-navigation/elements';
|
|
import { useRouter } from 'expo-router';
|
|
import { useThemeColor } from '../hooks/useThemeColor';
|
|
import { Category, CategoryQuery } from '../models/category';
|
|
import { Task, TaskQuery } from '../models/task';
|
|
import { CategoryRepository } from '../repositories/CategoryRepository';
|
|
import { TaskRepository } from '../repositories/TaskRepository';
|
|
import { SQLiteDataService } from '../services/data/sqliteDataService';
|
|
import { GetTaskColor } from '../utils/colors';
|
|
import { ThemedText } from './ThemedText';
|
|
import { ThemedView } from './ThemedView';
|
|
|
|
export type CategoryItemProps = ViewProps & {
|
|
lightColor?: string;
|
|
darkColor?: string;
|
|
category: Category;
|
|
onUpdate: () => void;
|
|
categories: Category[];
|
|
};
|
|
|
|
const categoryRepository = new CategoryRepository(new SQLiteDataService<Category>(CategoryQuery));
|
|
const taskRepository = new TaskRepository(new SQLiteDataService<Task>(TaskQuery));
|
|
|
|
export function CategoryItem({ category, categories, onUpdate, lightColor, darkColor, ...otherProps }: CategoryItemProps) {
|
|
const backgroundColor = useThemeColor({ light: lightColor, dark: darkColor }, 'background');
|
|
const router = useRouter();
|
|
const colorScheme = useColorScheme();
|
|
|
|
const LongPressHandler = () => {
|
|
//select edit or remove
|
|
console.log("Long pressed task:", category);
|
|
Alert.alert(
|
|
"Select action",
|
|
"Choose an action for the task",
|
|
[
|
|
{
|
|
text: "Edit",
|
|
onPress: () => {
|
|
// Navigate to edit task form
|
|
console.log("Editing category:", category);
|
|
if (!category?.id) return;
|
|
router.push({ pathname: "../categoryForm", params: { category: JSON.stringify(category) } });
|
|
}
|
|
},
|
|
{
|
|
text: "Remove",
|
|
onPress: () => {
|
|
// Remove the task
|
|
taskRepository.findAll().then((tasks) => {
|
|
const tasksInCategory = tasks.filter(task => task.category === category.id);
|
|
if (tasksInCategory.length > 0) {
|
|
Alert.alert(
|
|
"Cannot delete category",
|
|
"This category has tasks assigned to it. Please remove or reassign tasks before deleting the category.",
|
|
[{ text: "OK" }]
|
|
);
|
|
} else {
|
|
categoryRepository.delete(category.id!).then(() => {
|
|
onUpdate?.();
|
|
}).catch((error) => {
|
|
console.error("Error removing category:", error);
|
|
});
|
|
}
|
|
}).catch((error) => {
|
|
console.error("Error fetching tasks:", error);
|
|
});
|
|
},
|
|
style: "destructive"
|
|
},
|
|
{ text: "Cancel", style: "cancel" }
|
|
]);
|
|
}
|
|
|
|
return <Pressable onLongPress={() => {
|
|
LongPressHandler();
|
|
}}>
|
|
<ThemedView style={[{ backgroundColor }, styles(colorScheme).taskItemMain, {
|
|
borderLeftColor: GetTaskColor(category!)
|
|
}]} {...otherProps}>
|
|
<ThemedView style={[{ backgroundColor }, styles(colorScheme).taskItemSubcontainer]}>
|
|
<ThemedText style={styles(colorScheme).taskItemTitle}>
|
|
{category.icon}
|
|
</ThemedText>
|
|
<Text style={styles(colorScheme).taskItemTitle}>
|
|
{category?.title}
|
|
</Text>
|
|
</ThemedView>
|
|
</ThemedView >
|
|
</Pressable >;
|
|
}
|
|
|
|
|
|
const styles = (theme: ColorSchemeName) => {
|
|
return StyleSheet.create({
|
|
taskItemMain: {
|
|
borderLeftWidth: 0,
|
|
borderColor: 'color-mix(in oklab, #a71e14 100%, white)',
|
|
flexDirection: 'row',
|
|
padding: 16,
|
|
borderRadius: 8,
|
|
marginBottom: 8,
|
|
backgroundColor: theme === 'dark' ? '#555' : '#f0f0f0',
|
|
justifyContent: 'space-between',
|
|
alignItems: 'center',
|
|
},
|
|
taskItemSubcontainer: {
|
|
flexDirection: 'row',
|
|
backgroundColor: 'transparent',
|
|
gap: 12,
|
|
},
|
|
taskItemText: {
|
|
color: theme === 'dark' ? '#fff' : '#000',
|
|
fontSize: 16,
|
|
marginBottom: 4,
|
|
},
|
|
taskItemTitle: {
|
|
fontWeight: 'bold',
|
|
fontSize: 20,
|
|
marginBottom: 4,
|
|
color: theme === 'dark' ? '#fff' : '#000',
|
|
},
|
|
checkButton: {
|
|
width: 40,
|
|
height: 40,
|
|
}
|
|
})
|
|
} |