import React, { useRef, useState } from 'react'; import { useDrag, useDrop } from 'react-dnd'; import { Edit, Trash2, RefreshCw, Tag, User, Bot, Clipboard } from 'lucide-react'; import { Task } from './TaskTableView'; import { ItemTypes, getAssigneeIcon, getAssigneeGlow, getOrderColor, getOrderGlow } from '../../lib/task-utils'; import { copyToClipboard } from '../../utils/clipboard'; import { useToast } from '../../contexts/ToastContext'; export interface DraggableTaskCardProps { task: Task; index: number; onView: () => void; onComplete: () => void; onDelete: (task: Task) => void; onTaskReorder: (taskId: string, targetIndex: number, status: Task['status']) => void; tasksInStatus: Task[]; allTasks?: Task[]; hoveredTaskId?: string | null; onTaskHover?: (taskId: string | null) => void; } export const DraggableTaskCard = ({ task, index, onView, onDelete, onTaskReorder, allTasks = [], hoveredTaskId, onTaskHover, }: DraggableTaskCardProps) => { const { showToast } = useToast(); const [{ isDragging }, drag] = useDrag({ type: ItemTypes.TASK, item: { id: task.id, status: task.status, index }, collect: (monitor) => ({ isDragging: !!monitor.isDragging() }) }); const [, drop] = useDrop({ accept: ItemTypes.TASK, hover: (draggedItem: { id: string; status: Task['status']; index: number }, monitor) => { if (!monitor.isOver({ shallow: true })) return; if (draggedItem.id === task.id) return; if (draggedItem.status !== task.status) return; const draggedIndex = draggedItem.index; const hoveredIndex = index; if (draggedIndex === hoveredIndex) return; console.log('BOARD HOVER: Moving task', draggedItem.id, 'from index', draggedIndex, 'to', hoveredIndex, 'in status', task.status); // Move the task immediately for visual feedback (same pattern as table view) onTaskReorder(draggedItem.id, hoveredIndex, task.status); // Update the dragged item's index to prevent re-triggering draggedItem.index = hoveredIndex; } }); const [isFlipped, setIsFlipped] = useState(false); const toggleFlip = (e: React.MouseEvent) => { e.stopPropagation(); setIsFlipped(!isFlipped); }; // Calculate hover effects for parent-child relationships const getRelatedTaskIds = () => { const relatedIds = new Set(); return relatedIds; }; const relatedTaskIds = getRelatedTaskIds(); const isHighlighted = hoveredTaskId ? relatedTaskIds.has(hoveredTaskId) || hoveredTaskId === task.id : false; const handleMouseEnter = () => { onTaskHover?.(task.id); }; const handleMouseLeave = () => { onTaskHover?.(null); }; // Card styling - using CSS-based height animation for better scrolling // Card styling constants const cardScale = 'scale-100'; const cardOpacity = 'opacity-100'; // Subtle highlight effect for related tasks - applied to the card, not parent const highlightGlow = isHighlighted ? 'border-cyan-400/50 shadow-[0_0_8px_rgba(34,211,238,0.2)]' : ''; // Simplified hover effect - just a glowing border const hoverEffectClasses = 'group-hover:border-cyan-400/70 dark:group-hover:border-cyan-500/50 group-hover:shadow-[0_0_15px_rgba(34,211,238,0.4)] dark:group-hover:shadow-[0_0_15px_rgba(34,211,238,0.6)]'; // Base card styles with proper rounded corners const cardBaseStyles = 'bg-gradient-to-b from-white/80 to-white/60 dark:from-white/10 dark:to-black/30 border border-gray-200 dark:border-gray-700 rounded-lg'; // Transition settings const transitionStyles = 'transition-all duration-200 ease-in-out'; return (
drag(drop(node))} style={{ perspective: '1000px', transformStyle: 'preserve-3d' }} className={`flip-card w-full min-h-[140px] cursor-move relative ${cardScale} ${cardOpacity} ${isDragging ? 'opacity-50 scale-90' : ''} ${transitionStyles} group`} onMouseEnter={handleMouseEnter} onMouseLeave={handleMouseLeave} >
{/* Front side with subtle hover effect */}
{/* Priority indicator */}
{/* Content container with fixed padding - exactly matching back side structure */}
{task.feature}
{/* Task order display */}
{task.task_order}
{/* Action buttons group */}

{task.title}

{/* Spacer to push assignee section to bottom */}
{getAssigneeIcon(task.assignee?.name || 'User')}
{task.assignee?.name || 'User'}
{/* Back side */} {/* Back side with same hover effect */}
{/* Priority indicator */}
{/* Content container with fixed padding */}

{task.title}

{/* Description container with absolute positioning inside parent bounds */}

{task.description}

); };