"use client"; import { useState } from "react"; import { useSortable } from "@dnd-kit/sortable"; import { CSS } from "@dnd-kit/utilities"; import { Card, CardContent, CardTitle } from "@/components/ui/card"; import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, } from "@/components/ui/dialog"; import { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuItem, } from "@/components/ui/dropdown-menu"; import { TodoForm } from "@/components/todo-form"; import { Icons } from "@/components/icons"; import { cn } from "@/lib/utils"; import type { Todo, Tag } from "@/services/api-types"; import Image from "next/image"; interface TodoCardProps { todo: Todo; tags: Tag[]; onUpdate: (todo: Partial) => Promise; onDelete: () => void; onAttachmentsChanged?: (attachments: string[]) => void; isDraggable?: boolean; } export function TodoCard({ todo, tags, onUpdate, onDelete, onAttachmentsChanged, isDraggable = false, }: TodoCardProps) { const [isEditDialogOpen, setIsEditDialogOpen] = useState(false); const [isViewDialogOpen, setIsViewDialogOpen] = useState(false); // Drag and drop logic const { attributes, listeners, setNodeRef, transform, transition, isDragging, } = useSortable({ id: todo.id, disabled: !isDraggable, }); const style = { transform: CSS.Transform.toString(transform), transition, opacity: isDragging ? 0.5 : 1, }; // --- Helper Functions --- const getStatusColor = (status: string) => { switch (status) { case "pending": return "border-l-4 border-l-amber-500"; case "in-progress": return "border-l-4 border-l-sky-500"; case "completed": return "border-l-4 border-l-emerald-500"; default: return "border-l-4 border-l-slate-400"; } }; // const getStatusIcon = (status: string) => { // switch (status) { // case "pending": // return ; // case "in-progress": // return ; // case "completed": // return ; // default: // return ; // } // }; const formatDate = (dateString?: string | null) => { if (!dateString) return ""; const date = new Date(dateString); return date.toLocaleDateString(); }; const todoTags = tags.filter((tag) => todo.tagIds?.includes(tag.id)); const hasAttachments = !!todo.attachmentUrl; const hasSubtasks = todo.subtasks && todo.subtasks.length > 0; const completedSubtasks = todo.subtasks?.filter((s) => s.completed).length ?? 0; // --- Event Handlers --- const handleStatusToggle = () => { const newStatus = todo.status === "completed" ? "pending" : "completed"; onUpdate({ status: newStatus }); }; // --- Rendering --- const coverImage = todo.attachmentUrl && todo.attachmentUrl.match(/\.(jpg|jpeg|png|gif|webp)$/i) ? todo.attachmentUrl : null; return ( <> !isDraggable && setIsViewDialogOpen(true)} > {/* Optional Cover Image */} {coverImage && (
Todo Attachment
)} {/* Title and Menu */}
{todo.title} {!isDraggable && ( open && setIsViewDialogOpen(false)} > e.stopPropagation()} > setIsViewDialogOpen(true)}> View setIsEditDialogOpen(true)}> Edit Delete )}
{/* Description (optional, truncated) */} {todo.description && (

{todo.description}

)} {/* Badges and Indicators */}
{todoTags.map((tag) => ( {tag.name} ))} {hasSubtasks && ( {completedSubtasks}/{todo.subtasks.length} )} {hasAttachments && ( 1 )} {todo.deadline && ( {formatDate(todo.deadline)} )}
{/* Bottom Row: Created Date & Status Toggle */}
{todo.createdAt ? formatDate(todo.createdAt) : ""}
{/* Edit Dialog */} Edit Todo Make changes to your task, add attachments, and save. { await onUpdate(updatedTodoData); setIsEditDialogOpen(false); }} onAttachmentsChanged={onAttachmentsChanged} /> {/* View Dialog */}
{todo.status.replace("-", " ")} {todo.deadline && ( {formatDate(todo.deadline)} )}
{todo.title} Created {formatDate(todo.createdAt)} {/* Cover Image */} {coverImage && (
{todo.title}
)} {/* Content Section */}
{/* Description */} {todo.description && (
{todo.description}
)} {/* Tags */} {todoTags.length > 0 && (

TAGS

{todoTags.map((tag) => ( {tag.name} ))}
)} {/* Subtasks */} {hasSubtasks && (

SUBTASKS ({completedSubtasks}/{todo.subtasks.length})

    {todo.subtasks.map((subtask) => (
  • {subtask.completed && ( )}
    {subtask.description}
  • ))}
)} {/* Attachments */} {hasAttachments && (

ATTACHMENT

{todo.attachmentUrl && ( )}
)}
{/* Footer Actions */}
); }