Add functionality to delete tasks with a confirmation dialog
Implement task deletion with optimistic UI updates, confirmation dialogs using Shadcn UI's AlertDialog, and API integration for backend task removal. Includes i18n support for delete confirmation messages. Replit-Commit-Author: Agent Replit-Commit-Session-Id: ceced2fc-aa46-458d-ba87-ddd4b7bb1518 Replit-Commit-Checkpoint-Type: intermediate_checkpoint Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/659922a9-0087-461c-90dd-6d9a58b81d4d/ceced2fc-aa46-458d-ba87-ddd4b7bb1518/nn5bWKE
This commit is contained in:
@@ -6,6 +6,16 @@ import { Toaster } from "@/components/ui/toaster";
|
||||
import { TooltipProvider } from "@/components/ui/tooltip";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Card } from "@/components/ui/card";
|
||||
import {
|
||||
AlertDialog,
|
||||
AlertDialogAction,
|
||||
AlertDialogCancel,
|
||||
AlertDialogContent,
|
||||
AlertDialogDescription,
|
||||
AlertDialogFooter,
|
||||
AlertDialogHeader,
|
||||
AlertDialogTitle,
|
||||
} from "@/components/ui/alert-dialog";
|
||||
|
||||
// Components
|
||||
import BottomNavigation from './components/BottomNavigation';
|
||||
@@ -98,6 +108,7 @@ function App() {
|
||||
const [isCreateModalOpen, setIsCreateModalOpen] = useState(false);
|
||||
const [isTaskDetailsOpen, setIsTaskDetailsOpen] = useState(false);
|
||||
const [selectedTask, setSelectedTask] = useState<Task | null>(null);
|
||||
const [deleteTaskId, setDeleteTaskId] = useState<string | null>(null);
|
||||
|
||||
// Fetch tasks and labels from server on mount
|
||||
useEffect(() => {
|
||||
@@ -229,6 +240,44 @@ function App() {
|
||||
console.log('Task details saved:', updatedTask.title);
|
||||
};
|
||||
|
||||
const handleTaskDelete = async (taskId: string) => {
|
||||
setDeleteTaskId(taskId);
|
||||
};
|
||||
|
||||
const confirmTaskDelete = async () => {
|
||||
if (!deleteTaskId) return;
|
||||
|
||||
// Optimistic deletion - remove from UI immediately
|
||||
const taskToDelete = tasks.find(task => task.id === deleteTaskId);
|
||||
setTasks(prev => prev.filter(task => task.id !== deleteTaskId));
|
||||
|
||||
// Close task details modal if the deleted task was open
|
||||
if (selectedTask?.id === deleteTaskId) {
|
||||
handleTaskDetailsClose();
|
||||
}
|
||||
|
||||
setDeleteTaskId(null);
|
||||
|
||||
try {
|
||||
const response = await fetch(`/api/tasks/${deleteTaskId}`, {
|
||||
method: 'DELETE'
|
||||
});
|
||||
|
||||
// 404 is acceptable - task doesn't exist on backend (seeded task)
|
||||
if (!response.ok && response.status !== 404) {
|
||||
throw new Error('Failed to delete task');
|
||||
}
|
||||
|
||||
console.log('Task deleted:', deleteTaskId);
|
||||
} catch (error) {
|
||||
console.error('Error deleting task:', error);
|
||||
// Restore task on error
|
||||
if (taskToDelete) {
|
||||
setTasks(prev => [...prev, taskToDelete]);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const handleCreateFromTemplate = (templateId: string, startDate: Date, projectName: string) => {
|
||||
console.log('Creating project from template:', { templateId, startDate, projectName });
|
||||
// In a real app, this would create multiple tasks based on the template
|
||||
@@ -242,6 +291,7 @@ function App() {
|
||||
tasks={tasks}
|
||||
onTaskUpdate={handleTaskUpdate}
|
||||
onTaskEdit={handleTaskClick}
|
||||
onTaskDelete={handleTaskDelete}
|
||||
onStartTimer={startTimer}
|
||||
onStopTimer={stopTimer}
|
||||
/>
|
||||
@@ -264,6 +314,7 @@ function App() {
|
||||
onTaskStatusChange={handleTaskStatusChange}
|
||||
onTaskUpdate={handleTaskUpdate}
|
||||
onTaskClick={handleTaskClick}
|
||||
onTaskDelete={handleTaskDelete}
|
||||
onStartTimer={startTimer}
|
||||
onStopTimer={stopTimer}
|
||||
/>
|
||||
@@ -354,6 +405,30 @@ function App() {
|
||||
onSave={handleTaskDetailsSave}
|
||||
labels={labels}
|
||||
/>
|
||||
|
||||
{/* Delete Confirmation Dialog */}
|
||||
<AlertDialog open={deleteTaskId !== null} onOpenChange={(open) => !open && setDeleteTaskId(null)}>
|
||||
<AlertDialogContent data-testid="dialog-delete-confirmation">
|
||||
<AlertDialogHeader>
|
||||
<AlertDialogTitle>{t('deleteConfirmation.title')}</AlertDialogTitle>
|
||||
<AlertDialogDescription>
|
||||
{t('deleteConfirmation.description')}
|
||||
</AlertDialogDescription>
|
||||
</AlertDialogHeader>
|
||||
<AlertDialogFooter>
|
||||
<AlertDialogCancel data-testid="button-cancel-delete">
|
||||
{t('deleteConfirmation.cancel')}
|
||||
</AlertDialogCancel>
|
||||
<AlertDialogAction
|
||||
onClick={confirmTaskDelete}
|
||||
className="bg-destructive text-destructive-foreground hover:bg-destructive/90"
|
||||
data-testid="button-confirm-delete"
|
||||
>
|
||||
{t('deleteConfirmation.confirm')}
|
||||
</AlertDialogAction>
|
||||
</AlertDialogFooter>
|
||||
</AlertDialogContent>
|
||||
</AlertDialog>
|
||||
</div>
|
||||
|
||||
<Toaster />
|
||||
|
||||
Reference in New Issue
Block a user