import React, { useRef, useState } from "react"; import { useDrop } from "react-dnd"; import Rect from "./rect"; export default function Canvas(props) { const [dragging, setDragging] = useState(-1); const [linking, setLinking] = useState(false); const [line, setLine] = useState({ startX: 0, startY: 0, endX: 0, endY: 0, }); const [offset, setOffset] = useState({ x: 0, y: 0 }); const [onRect, setOnRect] = useState(false); const [panning, setPanning] = useState(false); const [panOffset, setPanOffset] = useState({ x: 0, y: 0 }); const [cursor, setCursor] = useState("default"); const canvas = useRef(null); const handleMouseDownRect = (e, id) => { const { clientX, clientY } = e; const table = props.tables.find((t) => t.id === id); setOffset({ x: clientX - table.x, y: clientY - table.y, }); setDragging(id); }; const handleMouseMove = (e) => { if (linking) { const rect = canvas.current.getBoundingClientRect(); const offsetX = rect.left; const offsetY = rect.top; setLine({ ...line, endX: e.clientX - offsetX, endY: e.clientY - offsetY, }); return; } if (panning) { const dx = e.clientX - panOffset.x; const dy = e.clientY - panOffset.y; setPanOffset({ x: e.clientX, y: e.clientY }); const updatedTables = props.tables.map((t) => ({ ...t, x: t.x + dx, y: t.y + dy, })); props.setTables(updatedTables); } else if (dragging >= 0) { const updatedTables = props.tables.map((t) => { if (t.id === dragging) { const updatedTable = { ...t, x: e.clientX - offset.x, y: e.clientY - offset.y, }; return updatedTable; } return t; }); props.setTables(updatedTables); } }; const handleMouseDown = (e) => { if (dragging < 0) { if (!onRect) { setPanning(true); setPanOffset({ x: e.clientX, y: e.clientY }); setCursor("grabbing"); } } }; const handleMouseUp = () => { setDragging(-1); setPanning(false); setCursor("default"); setLinking(false); }; const deleteTable = (id) => { const updatedTables = [...props.tables]; updatedTables.splice(id, 1); props.setTables(updatedTables); }; const handleGripField = (id) => { setPanning(false); setDragging(-1); setLinking(true); handleLinking(); }; const handleLinking = () => {}; const [, drop] = useDrop( () => ({ accept: "CARD", drop: (item, monitor) => { const offset = monitor.getClientOffset(); const canvasRect = canvas.current.getBoundingClientRect(); const x = offset.x - canvasRect.left - 100 * 0.5; const y = offset.y - canvasRect.top - 100 * 0.5; const newTable = { id: props.tables.length + 1, name: `Table ${props.tables.length + 1}`, x: x, y: y, fields: [ { name: "id", type: "UUID", default: "", primary: true, unique: true, notNull: true, increment: true, }, ], }; props.setTables((prev) => [...prev, newTable]); props.setCode((prev) => prev === "" ? `CREATE TABLE \`${newTable.name}\`;` : `${prev}\n\nCREATE TABLE \`${newTable.name}\`;` ); }, collect: (monitor) => ({ isOver: !!monitor.isOver(), }), }), [props.tables] ); return (
{props.tables.map((table, i) => ( handleMouseDownRect(e, table.id)} onDelete={deleteTable} /> ))} {linking && ( )}
); }