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 { useTranslation } from 'react-i18next'; 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(TaskQuery)); const adaptDaysToGoToUnit = (t: Task) => { const timeLeft = t.lastDone! + (t.daysToRedo! * 24 * 60 * 60 * 1000) - Date.now(); if (timeLeft < 0) return 0; // Task is overdue else if (timeLeft < 3 * 60 * 60 * 1000) return Math.ceil(timeLeft / (60 * 1000)) + " minutes"; else if (timeLeft < 24 * 60 * 60 * 1000) return Math.ceil(timeLeft / (3600 * 1000)) + " hours"; else if (timeLeft < 7 * 24 * 60 * 60 * 1000) return Math.ceil(timeLeft / (24 * 3600 * 1000)) + " days"; else if (timeLeft < 30 * 24 * 60 * 60 * 1000) return Math.ceil(timeLeft / (7 * 24 * 3600 * 1000)) + " weeks"; else return Math.ceil(timeLeft / (30 * 24 * 3600 * 1000)) + " months"; }; export function TaskItem({ task, categories, onUpdate, lightColor, darkColor, ...otherProps }: TaskItemProps) { const { t } = useTranslation(); 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( t('select_action'), t('choose_action_for_task'), [ { text: t('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: t('remove'), onPress: () => { // Remove the task console.log("Removing task:", task); if (!task?.id) return; taskRepository.delete(task.id).then(() => { toast.success(t('task_removed_successfully')); onUpdate?.(); }).catch((error) => { toast.error(t('error_removing_task')); console.error("Error removing task:", error); }); }, style: "destructive" }, { text: t('cancel'), style: "cancel" } ]); } return { LongPressHandler(); }}> {task?.title} {category?.icon + " " + category?.title + " - " + (adaptDaysToGoToUnit(task) == 0 ? "Overdue" : adaptDaysToGoToUnit(task))} { taskRepository.update(task!.id!, { ...task, lastDone: Date.now() }).then(() => { toast.success(t('task_updated_successfully')); onUpdate?.(); }).catch((error) => { toast.error(t('error_updating_task')); console.error("Error updating task:", error); }); }}> 0 ? ((daysLeft.current / (24 * 3600 * 1000)) / task.daysToRedo!) * 360 : 0} width={40} height={40} color={GetTaskColor(task!)} /> ; } 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, } }) }