"use client"; import React, { useState, useRef, useEffect } from "react"; import { Button } from "../components/ui/button"; import { Select } from "../components/ui/select"; import { Textarea } from "../components/ui/textarea"; import { Label } from "../components/ui/label"; import { Slider } from "../components/ui/slider"; import { ColorPicker } from "../components/ui/color-picker"; import { Checkbox } from "../components/ui/checkbox"; // Helper function to download image function downloadImage(dataUrl: string, filename: string) { const link = document.createElement('a'); link.href = dataUrl; link.download = filename; document.body.appendChild(link); link.click(); document.body.removeChild(link); } // Import types (we'll need to export these from page.tsx) type BackgroundNode = any; type ClothesNode = any; type BlendNode = any; type EditNode = any; type CameraNode = any; type AgeNode = any; type FaceNode = any; function cx(...args: Array) { return args.filter(Boolean).join(" "); } // Reusable drag hook for all nodes function useNodeDrag(node: any, onUpdatePosition?: (id: string, x: number, y: number) => void) { const [localPos, setLocalPos] = useState({ x: node.x, y: node.y }); const dragging = useRef(false); const start = useRef<{ sx: number; sy: number; ox: number; oy: number } | null>(null); useEffect(() => { setLocalPos({ x: node.x, y: node.y }); }, [node.x, node.y]); const onPointerDown = (e: React.PointerEvent) => { e.stopPropagation(); dragging.current = true; start.current = { sx: e.clientX, sy: e.clientY, ox: localPos.x, oy: localPos.y }; (e.currentTarget as HTMLElement).setPointerCapture(e.pointerId); }; const onPointerMove = (e: React.PointerEvent) => { if (!dragging.current || !start.current) return; const dx = e.clientX - start.current.sx; const dy = e.clientY - start.current.sy; const newX = start.current.ox + dx; const newY = start.current.oy + dy; setLocalPos({ x: newX, y: newY }); if (onUpdatePosition) onUpdatePosition(node.id, newX, newY); }; const onPointerUp = (e: React.PointerEvent) => { dragging.current = false; start.current = null; (e.currentTarget as HTMLElement).releasePointerCapture(e.pointerId); }; return { localPos, onPointerDown, onPointerMove, onPointerUp }; } function Port({ className, nodeId, isOutput, onStartConnection, onEndConnection }: { className?: string; nodeId?: string; isOutput?: boolean; onStartConnection?: (nodeId: string) => void; onEndConnection?: (nodeId: string) => void; }) { const handlePointerDown = (e: React.PointerEvent) => { e.stopPropagation(); if (isOutput && nodeId && onStartConnection) { onStartConnection(nodeId); } }; const handlePointerUp = (e: React.PointerEvent) => { e.stopPropagation(); if (!isOutput && nodeId && onEndConnection) { onEndConnection(nodeId); } }; return (
); } export function BackgroundNodeView({ node, onDelete, onUpdate, onStartConnection, onEndConnection, onProcess, onUpdatePosition, }: any) { const { localPos, onPointerDown, onPointerMove, onPointerUp } = useNodeDrag(node, onUpdatePosition); const handleImageUpload = (e: React.ChangeEvent) => { if (e.target.files?.length) { const reader = new FileReader(); reader.onload = () => { onUpdate(node.id, { customBackgroundImage: reader.result }); }; reader.readAsDataURL(e.target.files[0]); } }; const handleImagePaste = (e: React.ClipboardEvent) => { const items = e.clipboardData.items; for (let i = 0; i < items.length; i++) { if (items[i].type.startsWith("image/")) { const file = items[i].getAsFile(); if (file) { const reader = new FileReader(); reader.onload = () => { onUpdate(node.id, { customBackgroundImage: reader.result }); }; reader.readAsDataURL(file); return; } } } const text = e.clipboardData.getData("text"); if (text && (text.startsWith("http") || text.startsWith("data:image"))) { onUpdate(node.id, { customBackgroundImage: text }); } }; const handleDrop = (e: React.DragEvent) => { e.preventDefault(); const files = e.dataTransfer.files; if (files && files.length) { const reader = new FileReader(); reader.onload = () => { onUpdate(node.id, { customBackgroundImage: reader.result }); }; reader.readAsDataURL(files[0]); } }; return (
e.preventDefault()} onPaste={handleImagePaste} >
BACKGROUND
{node.backgroundType === "color" && ( onUpdate(node.id, { backgroundColor: (e.target as HTMLInputElement).value })} /> )} {node.backgroundType === "image" && ( )} {node.backgroundType === "upload" && (
{node.customBackgroundImage ? (
Custom Background
) : ( )}
)} {node.backgroundType === "custom" && (