134 lines
5.2 KiB
TypeScript
134 lines
5.2 KiB
TypeScript
import { Alert, ColorSchemeName, Pressable, StyleSheet, useColorScheme, type ViewProps } from 'react-native';
|
|
|
|
import { toast } from '@backpackapp-io/react-native-toast';
|
|
import { Text } from '@react-navigation/elements';
|
|
import { useRouter } from 'expo-router';
|
|
import { useRef } from 'react';
|
|
import { useThemeColor } from '../hooks/useThemeColor';
|
|
import { Category } from '../models/category';
|
|
import { Task, TaskQuery } from '../models/task';
|
|
import { TaskRepository } from '../repositories/TaskRepository';
|
|
import { SQLiteDataService } from '../services/data/sqliteDataService';
|
|
import { GetTaskColor } from '../utils/colors';
|
|
import { ThemedView } from './ThemedView';
|
|
import ClockProgress from './clockProgress';
|
|
|
|
export type TaskItemProps = ViewProps & {
|
|
lightColor?: string;
|
|
darkColor?: string;
|
|
task: Task;
|
|
onUpdate: () => void;
|
|
categories: Category[];
|
|
};
|
|
|
|
const taskRepository = new TaskRepository(new SQLiteDataService<Task>(TaskQuery));
|
|
|
|
export function TaskItem({ task, categories, onUpdate, lightColor, darkColor, ...otherProps }: TaskItemProps) {
|
|
const backgroundColor = useThemeColor({ light: lightColor, dark: darkColor }, 'background');
|
|
const router = useRouter();
|
|
const daysLeft = useRef(task.daysToRedo! * 24 * 3600 * 1000 - (Date.now() - task.lastDone!));
|
|
const colorScheme = useColorScheme();
|
|
const category = categories?.find((c) => {
|
|
return c.id === task?.category;
|
|
});
|
|
|
|
const LongPressHandler = () => {
|
|
//select edit or remove
|
|
console.log("Long pressed task:", task);
|
|
Alert.alert(
|
|
"Select action",
|
|
"Choose an action for the task",
|
|
[
|
|
{
|
|
text: "Edit",
|
|
onPress: () => {
|
|
// Navigate to edit task form
|
|
console.log("Editing task:", task);
|
|
if (!task?.id) return;
|
|
router.push({ pathname: "./taskForm", params: { task: JSON.stringify(task) } });
|
|
}
|
|
},
|
|
{
|
|
text: "Remove",
|
|
onPress: () => {
|
|
// Remove the task
|
|
console.log("Removing task:", task);
|
|
if (!task?.id) return;
|
|
taskRepository.delete(task.id).then(() => {
|
|
toast.success("Task removed successfully");
|
|
onUpdate?.();
|
|
}).catch((error) => {
|
|
toast.success("Error removing task");
|
|
console.error("Error removing task:", error);
|
|
});
|
|
},
|
|
style: "destructive"
|
|
},
|
|
{ text: "Cancel", style: "cancel" }
|
|
]);
|
|
}
|
|
|
|
return <Pressable onLongPress={() => {
|
|
LongPressHandler();
|
|
}}>
|
|
<ThemedView style={[{ backgroundColor }, styles(colorScheme).taskItemMain, {
|
|
borderLeftColor: GetTaskColor(task!)
|
|
}]} {...otherProps}>
|
|
<ThemedView style={[{ backgroundColor }, styles(colorScheme).taskItemSubcontainer]}>
|
|
<Text style={styles(colorScheme).taskItemTitle}>
|
|
{task?.title}
|
|
</Text>
|
|
<Text style={styles(colorScheme).taskItemText}>
|
|
{category?.icon + " " + category?.title + " - " + Math.ceil(daysLeft.current / (3600 * 1000))} hours left
|
|
</Text>
|
|
</ThemedView>
|
|
<Pressable style={styles(colorScheme).checkButton} onPress={() => {
|
|
|
|
taskRepository.update(task!.id!, { ...task, lastDone: Date.now() }).then(() => {
|
|
toast.success("Task updated successfully");
|
|
onUpdate?.();
|
|
}).catch((error) => {
|
|
toast.error("Error updating task");
|
|
console.error("Error updating task:", error);
|
|
});
|
|
}}>
|
|
<ClockProgress degree={((daysLeft.current / (24 * 3600 * 1000)) / task.daysToRedo!) * 360} width={40} height={40} color={GetTaskColor(task!)} />
|
|
</Pressable>
|
|
</ThemedView></Pressable>;
|
|
}
|
|
|
|
|
|
const styles = (theme: ColorSchemeName) => {
|
|
return StyleSheet.create({
|
|
taskItemMain: {
|
|
borderLeftWidth: 20,
|
|
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: 'column',
|
|
backgroundColor: 'transparent'
|
|
},
|
|
taskItemText: {
|
|
color: theme === 'dark' ? '#fff' : '#000',
|
|
fontSize: 15,
|
|
marginBottom: 4,
|
|
},
|
|
taskItemTitle: {
|
|
fontWeight: 'bold',
|
|
fontSize: 20,
|
|
marginBottom: 4,
|
|
color: theme === 'dark' ? '#fff' : '#000',
|
|
},
|
|
checkButton: {
|
|
width: 40,
|
|
height: 40,
|
|
}
|
|
})
|
|
} |