Newer
Older
cortex-hub / ui / client-app / src / components / CodeChangePlan.js
import { createPortal } from 'react-dom';
import { useRef, useState } from 'react';
import ReactMarkdown from 'react-markdown';
import './CodeChangePlan.css';
import { FaPlus, FaTrash, FaEdit } from 'react-icons/fa';

// Tooltip component
const StepDetails = ({ stepItem, position }) => {
  const style = {
    position: 'absolute',
    top: position?.top ?? 0,
    left: position?.left ?? 0,
  };

  return (
    <div className="step-details-popdown" style={style}>
      <div className="tooltip-action">
        {stepItem.action === 'create' && <FaPlus className="create-icon" />}
        {stepItem.action === 'delete' && <FaTrash className="delete-icon" />}
        {stepItem.action === 'modify' && <FaEdit className="modify-icon" />}
        <span>
          {stepItem.action === 'create'
            ? 'Create File'
            : stepItem.action === 'delete'
            ? 'Delete File'
            : stepItem.action === 'modify'
            ? 'Modify File'
            : stepItem.action}
        </span>
      </div>
      <div className="tooltip-file-path">{stepItem.file_path}</div>
    </div>
  );
};

// Main component
const CodeChangePlan = ({ steps }) => {
  const [hoveredStepIndex, setHoveredStepIndex] = useState(null);
  const [tooltipPosition, setTooltipPosition] = useState(null);
  const stepRefs = useRef([]);

  const handleMouseEnter = (index) => {
    const stepElement = stepRefs.current[index];
    if (stepElement) {
      const rect = stepElement.getBoundingClientRect();
    //   const tooltipPadding = 10;

      setTooltipPosition({
        top: rect.bottom + window.scrollY + 6,  // 6px spacing
        left: rect.left + window.scrollX,
        });
    }
    setHoveredStepIndex(index);
  };

  const handleMouseLeave = () => {
    setHoveredStepIndex(null);
    setTooltipPosition(null);
  };

  return (
    <>
      <ul className="code-change-plan">
        {steps.map((step, index) => (
          <li
            key={index}
            className="code-change-plan-step"
            onMouseEnter={() => handleMouseEnter(index)}
            onMouseLeave={handleMouseLeave}
            ref={(el) => (stepRefs.current[index] = el)}
          >
            <ReactMarkdown>{step.change_instruction}</ReactMarkdown>
          </li>
        ))}
      </ul>

      {hoveredStepIndex !== null &&
        createPortal(
          <StepDetails
            stepItem={steps[hoveredStepIndex]}
            position={tooltipPosition}
          />,
          document.body
        )}
    </>
  );
};

export default CodeChangePlan;