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 { nanoid } from 'nanoid';
import CustomEdge from './CustomEdge';
const initialNodes = [
{
key: 'customer-sign',
id: '1',
type: 'input',
data: {
label: (
)
},
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 [addNodeCallback, setAddNodeCallback] = useState(() => () => {});
const handleAddNoteClick = () => {
setShowTabBar(true);
setAddNodeCallback(() => (selectedNode) => {
addNodeBetween(selectedNode, sourceId, targetId);
});
};
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 removeEdgesRelatedToNode = (nodeId) => {
setEdges((eds) =>
eds.filter((edge) => edge.source !== nodeId && edge.target !== nodeId)
);
};
const addNode = (option) => {
const newNodeId = nanoid(8); // Generate a unique ID for the new node
const addNoteNode = nodes.find((node) => node.id === '2');
const initialX = addNoteNode.position.x;
console.log(initialX);
const nextY =
nodes.length > 2
? getNextYPosition(initialX, 130)
: addNoteNode.position.y;
// Remove existing edges from addNoteNode
setEdges((eds) =>
eds.filter((edge) => edge.source !== '2' && edge.target !== '2')
);
if (option.id === '4') {
const repliedNode = {
id: newNodeId,
key: option.key,
data: { label: option.htmlNode },
position: { x: initialX, y: nextY }
};
const yesNode = {
id: nanoid(8),
type: 'output',
key: 'contact-exists',
data: {
label: (
)
},
position: { x: initialX - 150, y: nextY + 150 }
};
const noNode = {
id: nanoid(8),
type: '',
key: 'send-survey',
data: {
label: (
)
},
position: { x: initialX + 150, y: nextY + 150 }
};
// Di chuyển node add-note sang nhánh no
setNodes((nds) =>
nds.map((node) =>
node.id === '2'
? {
...node,
position: {
x: noNode.position.x,
y: noNode.position.y + 150
}
}
: node
)
);
// Thêm các node mới (replied, yes, no)
setNodes((nds) => [...nds, repliedNode, yesNode, noNode]);
// Kết nối các edges giữa các node
setEdges((eds) => [
...eds,
{
id: nanoid(8),
source: repliedNode.id,
target: yesNode.id,
label: 'yes'
},
{
id: nanoid(8),
source: repliedNode.id,
target: noNode.id,
label: 'no'
},
{ id: nanoid(8), source: lastNodeId, target: repliedNode.id },
{ id: nanoid(8), source: noNode.id, target: addNoteNode.id }
]);
setLastNodeId(noNode.id);
} else {
console.log(option);
// 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: initialX,
y: nodes.length > 2 ? nextY : addNoteNode.position.y
}
};
const newEdge = {
id: nanoid(8),
source: lastNodeId,
target: newNodeId
};
setNodes((nds) => [...nds, newNode]);
setEdges((eds) => [
...eds,
newEdge,
{ id: nanoid(8), source: newNodeId, target: addNoteNode.id }
]);
// setEdges((eds) => [
// ...eds,
// {
// id: uuidv4(),
// source: lastNodeId,
// data: {
// label: Add Note
, // Use HTML or React component
// onClick: handleAddNoteClick
// },
// target: newNodeId
// }
// ]);
// Cuộn tới node mới thêm
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;