import { useState, useCallback, useEffect } from 'react'; import { ReactFlow, addEdge, Controls, Background, BackgroundVariant, SelectionMode } from '@xyflow/react'; import '@xyflow/react/dist/style.css'; import { FiUser, FiMail, FiCheckCircle, FiList } from 'react-icons/fi'; import { FaShuffle } from 'react-icons/fa6'; import '../assets/css/style.css'; import Tabbar from './Tabbar.tsx'; import ShowPopup from './ShowPopup.tsx'; import { v4 as uuidv4 } from 'uuid'; const initialNodes = [ { key: 'customer-sign', id: '1', type: 'input', data: { label: (
Customer signs up to
) }, position: { x: 250, y: 100 } }, { id: '2', data: { label: 'Add Note' }, position: { x: 250, y: 250 } } ]; // Nội dung cho mỗi node const nodeContents = { 'send-email': ` `, 'customer-sign': ` `, ifelse: ` `, 'contact-exists': ` `, 'send-survey': ` ` }; const NoteFlow = () => { const [nodes, setNodes] = useState(initialNodes); const [edges, setEdges] = useState([ { id: 'e1-2', source: '1', target: '2' } // Kết nối node "Add Note" với node mặc định ban đầu ]); const [showTabBar, setShowTabBar] = useState(false); const [lastNodeId, setLastNodeId] = useState('1'); const [nodeToDelete, setNodeToDelete] = useState(null); const [showPopup, setShowPopup] = useState(false); const [selectedNodeContent, setSelectedNodeContent] = useState(''); const handleAddNoteClick = () => { setShowTabBar(true); const handleNodeSelect = (selectedNode) => { addNodeBetween(selectedNode, sourceId, targetId); }; setAddNodeCallback(() => addNodeBetweenWithIds); }; const onNodeClick = (event, node) => { if (node.id === '2') { // Check if the clicked node is "Add Note" setShowTabBar(true); } else { // Hiển thị popup khi click vào bất kỳ node nào const content = nodeContents[node.key]; // Lấy nội dung tương ứng của node setSelectedNodeContent(content); // Cập nhật nội dung cho popup setShowPopup(true); // Mở popup } }; const onNodeContextMenu = useCallback((event, node) => { event.preventDefault(); // Ngăn không cho menu chuột phải mặc định hiện ra setNodeToDelete(node); }, []); const handleNodeDelete = () => { if (nodeToDelete) { setNodes((nds) => nds.filter((node) => node.id !== nodeToDelete.id)); setEdges((eds) => eds.filter( (edge) => edge.source !== nodeToDelete.id && edge.target !== nodeToDelete.id ) ); setNodeToDelete(null); } }; // Function to get a unique y position const getUniqueYPosition = (xPosition, baseY, spacing) => { const existingYPositions = nodes .filter((node) => node.position.x === xPosition) .map((node) => node.position.y); let newYPosition = baseY; while (existingYPositions.includes(newYPosition)) { newYPosition += spacing; } return newYPosition; }; const getNextYPosition = (xPosition, spacing) => { const nodesInColumn = nodes.filter((node) => node.position.x === xPosition); if (nodesInColumn.length === 0) return 0; // Return 0 if there are no nodes const lastNode = nodesInColumn[nodesInColumn.length - 1]; return lastNode.position.y + spacing; }; const addNode = (option) => { const newNodeId = uuidv4(); // Generate a unique ID for the new node const addNoteNode = nodes.find((node) => node.id === '2'); const initialX = addNoteNode.position.x; const nextY = nodes.length > 2 ? getNextYPosition(initialX, 130) : addNoteNode.position.y; if (option.id === '4') { // Handle specific option case setNodes((nds) => nds.filter((node) => node.id !== '2')); const repliedNode = { id: newNodeId, key: option.key, data: { label: option.htmlNode }, position: { x: option.position.x, y: nextY } }; const yesNode = { id: uuidv4(), type: 'output', key: 'contact-exists', data: { label: (
Contact Exists
) }, position: { x: option.position.x - 150, y: nextY + 150 } }; const noNode = { id: uuidv4(), type: 'output', key: 'send-survey', data: { label: (
Send survey
) }, position: { x: option.position.x + 150, y: nextY + 150 } }; setNodes((nds) => [...nds, repliedNode, yesNode, noNode]); setEdges((eds) => [ ...eds, { id: uuidv4(), source: repliedNode.id, target: yesNode.id, label: 'yes', animated: false }, { id: uuidv4(), source: repliedNode.id, target: noNode.id, label: 'no', animated: false }, { id: uuidv4(), source: lastNodeId, target: repliedNode.id } ]); } else { // Add new node logic if (addNoteNode) { const initialX = addNoteNode.position.x; setNodes((nds) => nds.map((node) => node.id === '2' ? { ...node, position: { x: initialX, y: nextY + 130 } } : node ) ); } const newNode = { id: newNodeId, key: option.key, data: { label: option.htmlNode }, position: { x: option.position.x, y: nodes.length > 2 ? nextY : addNoteNode.position.y } }; console.log(getNextYPosition(option.position.x, 130)); setNodes((nds) => [...nds, newNode]); setEdges((eds) => [ ...eds, { id: uuidv4(), source: lastNodeId, target: newNodeId } ]); setLastNodeId(newNodeId); } setShowTabBar(false); }; const hidePopup = () => { setShowPopup(false); }; const addPopup = (node) => { const content = nodeContents[node.id]; // Lấy nội dung từ nodeContents dựa trên ID node setSelectedNodeContent(content); // Cập nhật nội dung được chọn }; return (
{showTabBar && } {nodeToDelete && (
)} {showPopup && ( setShowPopup(false)} /> )}
); }; export default NoteFlow;