taskeep-app/components/categoryItem.tsx
2025-07-22 14:04:38 +02:00

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,
}
})
}