import { OperatorI } from "@/pages/OperatorMarket/operator.model"; import React, { useState } from "react"; export function useDragOperators({ operators, setOperators, }: { operators: OperatorI[]; setOperators: (operators: OperatorI[]) => void; }) { const [draggingItem, setDraggingItem] = useState(null); const [draggingSource, setDraggingSource] = useState< "library" | "sort" | null >(null); const [insertPosition, setInsertPosition] = useState< "above" | "below" | null >(null); const handleDragStart = ( e: React.DragEvent, item: OperatorI, source: "library" | "sort" ) => { setDraggingItem({ ...item, originalId: item.id, }); setDraggingSource(source); e.dataTransfer.effectAllowed = "move"; }; const handleDragEnd = () => { setDraggingItem(null); setInsertPosition(null); }; const handleContainerDragOver = (e: React.DragEvent) => { e.preventDefault(); }; const handleContainerDragLeave = (e: React.DragEvent) => { if (!e.currentTarget.contains(e.relatedTarget)) { setInsertPosition(null); } }; const handleItemDragOver = (e: React.DragEvent) => { e.preventDefault(); e.stopPropagation(); const rect = e.currentTarget.getBoundingClientRect(); const mouseY = e.clientY; const elementMiddle = rect.top + rect.height / 2; const newPosition = mouseY < elementMiddle ? "above" : "below"; setInsertPosition(newPosition); }; const handleItemDragLeave = (e: React.DragEvent) => { if (!e.currentTarget.contains(e.relatedTarget)) { setInsertPosition(null); } }; const handleDropToContainer = (e: React.DragEvent) => { e.preventDefault(); if (!draggingItem) return; if (draggingSource === "library") { const exists = operators.some((item) => item.id === draggingItem.id); if (!exists) { setOperators([...operators, draggingItem]); } } resetDragState(); }; const handleItemDrop = (e: React.DragEvent, targetIndex: number) => { e.preventDefault(); e.stopPropagation(); if (!draggingItem) return; if (draggingSource === "library") { if (targetIndex !== -1) { const insertIndex = insertPosition === "above" ? targetIndex : targetIndex + 1; const exists = operators.some((item) => item.id === draggingItem.id); if (!exists) { const newRightItems = [...operators]; newRightItems.splice(insertIndex, 0, draggingItem); setOperators(newRightItems); } } } else if (draggingSource === "sort") { const draggedIndex = operators.findIndex( (item) => item.id === draggingItem.id ); if ( draggedIndex !== -1 && targetIndex !== -1 && draggedIndex !== targetIndex ) { const newItems = [...operators]; const [draggedOperator] = newItems.splice(draggedIndex, 1); let insertIndex = insertPosition === "above" ? targetIndex : targetIndex + 1; if (draggedIndex < insertIndex) { insertIndex--; } newItems.splice(insertIndex, 0, draggedOperator); setOperators(newItems); } } resetDragState(); }; const resetDragState = () => { setDraggingItem(null); setInsertPosition(null); }; return { handleDragStart, handleDragEnd, handleContainerDragOver, handleContainerDragLeave, handleItemDragOver, handleItemDragLeave, handleItemDrop, handleDropToContainer, }; }