"use client"; import { useCallback, useRef } from "react"; import { Handle, Position, NodeProps, Node } from "@xyflow/react"; import { BaseNode } from "./BaseNode"; import { useCommentNavigation } from "@/hooks/useCommentNavigation"; import { useWorkflowStore } from "@/store/workflowStore"; import { ImageInputNodeData } from "@/types"; type ImageInputNodeType = Node; export function ImageInputNode({ id, data, selected }: NodeProps) { const nodeData = data; const commentNavigation = useCommentNavigation(id); const updateNodeData = useWorkflowStore((state) => state.updateNodeData); const fileInputRef = useRef(null); const handleFileChange = useCallback( (e: React.ChangeEvent) => { const file = e.target.files?.[0]; if (!file) return; if (!file.type.match(/^image\/(png|jpeg|webp)$/)) { alert("Unsupported format. Use PNG, JPG, or WebP."); return; } if (file.size > 10 * 1024 * 1024) { alert("Image too large. Maximum size is 10MB."); return; } const reader = new FileReader(); reader.onload = (event) => { const base64 = event.target?.result as string; const img = new Image(); img.onload = () => { updateNodeData(id, { image: base64, imageRef: undefined, filename: file.name, dimensions: { width: img.width, height: img.height }, }); }; img.src = base64; }; reader.readAsDataURL(file); }, [id, updateNodeData] ); const handleDrop = useCallback( (e: React.DragEvent) => { e.preventDefault(); e.stopPropagation(); const file = e.dataTransfer.files?.[0]; if (!file) return; const dt = new DataTransfer(); dt.items.add(file); if (fileInputRef.current) { fileInputRef.current.files = dt.files; fileInputRef.current.dispatchEvent(new Event("change", { bubbles: true })); } }, [] ); const handleDragOver = useCallback((e: React.DragEvent) => { e.preventDefault(); e.stopPropagation(); }, []); const handleRemove = useCallback(() => { updateNodeData(id, { image: null, imageRef: undefined, filename: null, dimensions: null, }); }, [id, updateNodeData]); return ( {/* Reference input handle for visual links from Split Grid node */} {nodeData.image ? (
{nodeData.filename
) : (
fileInputRef.current?.click()} onKeyDown={(e) => { if (e.key === "Enter" || e.key === " ") { e.preventDefault(); fileInputRef.current?.click(); } }} onDrop={handleDrop} onDragOver={handleDragOver} className="w-full h-full bg-neutral-900/40 flex flex-col items-center justify-center cursor-pointer hover:bg-neutral-900/60 transition-colors" > Drop image
)}
); }