hey here when a user drags a blcok from the component to the graph it should be able to be dropped anywhere between the workoutblocoks in the graphs adjusting and moving according tothe drop everyother functionality shoudwork wotj it the same as before 
"""
// App.js
import React, { useState, useCallback, useRef } from 'react';
import { DndProvider } from 'react-dnd';
import { HTML5Backend } from 'react-dnd-html5-backend';
import Header from './Header';
import WorkoutBlocks from './WorkoutBlocks';
import Graph from './Graph';
import ColumnsList from './ColumnsList';

function App() {
  const [graphBlocks, setGraphBlocks] = useState([]);
  const idRef = useRef(0); // Persistent ID counter

  // Function to add a new block to the Graph at a specific index
  const addBlockToGraph = useCallback((block, index = graphBlocks.length) => {
    if (!block || !block.type || typeof block.height !== 'number') {
      console.error('Invalid block:', block);
      return;
    }

    const newBlock = { ...block, id: idRef.current++ };
    setGraphBlocks((prevBlocks) => {
      const updatedBlocks = [...prevBlocks];
      const insertIndex =
        index >= 0 && index <= updatedBlocks.length ? index : updatedBlocks.length;
      updatedBlocks.splice(insertIndex, 0, newBlock);
      return updatedBlocks;
    });
  }, [graphBlocks.length]);

  // Function to move (rearrange) a block within the Graph
  const moveGraphBlock = useCallback((dragIndex, hoverIndex) => {
    setGraphBlocks((prevBlocks) => {
      const updatedBlocks = [...prevBlocks];
      const [removed] = updatedBlocks.splice(dragIndex, 1);
      updatedBlocks.splice(hoverIndex, 0, removed);
      return updatedBlocks;
    });
  }, []);


  return (
    <DndProvider backend={HTML5Backend}>
      <div className="justify-center min-h-screen bg-[#F8F8F8] w-full p-4">
        <Header />

        {/* Main content */}
        <div className="flex justify-between mx-6 my-3 items-start">
          {/* Workout blocks card */}
          <WorkoutBlocks />

          {/* Graph and Columns List */}
          <div className="w-full ml-6">
            <Graph
              blocks={graphBlocks}
              addBlockToGraph={addBlockToGraph}
              moveBlock={moveGraphBlock}
            />
            <ColumnsList blocks={graphBlocks} />
          </div>
        </div>
      </div>
    </DndProvider>
  );
}

export default App;
"""
"""
// ColumnsList.js
import React from 'react';

const ColumnsList = ({ blocks }) => {
  return (
    <div className="mt-4 overflow-y-auto max-h-full bg-white rounded-lg shadow-md p-4">
      <h3 className="text-lg font-semibold mb-2">Current Columns</h3>
      {blocks.length === 0 ? (
        <p className="text-gray-500">No columns added yet.</p>
      ) : (
        <ul className="space-y-2">
          {blocks.map((block, index) => (
            <li key={block.id} className="flex items-center">
              <span className="mr-2 font-medium">Column {index + 1}:</span>
              <span>{block.type}</span>
            </li>
          ))}
        </ul>
      )}
    </div>
  );
};

export default ColumnsList;
""
""
// constants.js
export const ItemTypes = {
    WORKOUT_BLOCK: 'WORKOUT_BLOCK',
    GRAPH_BLOCK: 'GRAPH_BLOCK',
  };
""
""
// Graph.js
import React from 'react';
import GraphBlock from './GraphBlock';
import { useDrop } from 'react-dnd';
import { ItemTypes } from './constants';

const Graph = ({ blocks, addBlockToGraph, moveBlock, removeBlock }) => {
  // Universal drop target for adding to empty graph or at the end
  const [{ isOver, canDrop }, drop] = useDrop({
    accept: ItemTypes.WORKOUT_BLOCK,
    drop: (item, monitor) => {
      if (!monitor.didDrop()) {
        // If dropped directly on the graph (not on a GraphBlock), add to the end
        addBlockToGraph(item, blocks.length);
      }
    },
    canDrop: (item, monitor) => {
      return true; // Allow dropping
    },
    collect: (monitor) => ({
      isOver: monitor.isOver(),
      canDrop: monitor.canDrop(),
    }),
  });

  const isActive = isOver && canDrop;

  return (
    <div
      ref={drop} // Universal drop target
      className={`graph-container relative w-full h-[300px] bg-[#EAEAEA] rounded-lg shadow-md p-4 mb-4 ${
        isActive ? 'bg-[#D3D3D3]' : ''
      }`}
    >
      {/* Bar Graph */}
      <div className="absolute inset-0 flex items-end space-x-2 px-2">
        {blocks.map((block, index) => (
          <GraphBlock
            key={block.id}
            id={block.id}
            index={index}
            block={block}
            moveBlock={moveBlock}
            removeBlock={removeBlock}
            addBlockToGraph={addBlockToGraph}
            totalBlocks={blocks.length}
          />
        ))}
      </div>

      {/* X-Axis Labels */}
      <div className="absolute bottom-0 w-full flex justify-between text-xs mt-1">
        {blocks.map((_, index) => (
          <span key={index}>{index + 1} km</span>
        ))}
      </div>

      {/* Y-Axis Labels */}
      <div className="absolute left-0 top-0 h-full flex flex-col justify-between text-xs mr-1">
        <span>100%</span>
        <span>75%</span>
        <span>50%</span>
        <span>25%</span>
        <span>0%</span>
      </div>
    </div>
  );
};

export default Graph;
"""
""
// GraphBlock.js
import React, { useRef, useState } from 'react';
import { useDrag, useDrop } from 'react-dnd';
import { ItemTypes } from './constants';

const GraphBlock = ({
  id,
  index,
  block,
  moveBlock,
  removeBlock,
  addBlockToGraph,
  totalBlocks,
}) => {
  const ref = useRef(null);
  const [isOverCurrent, setIsOverCurrent] = useState(false);
  const [insertBefore, setInsertBefore] = useState(false);
  const [hasDropped, setHasDropped] = useState(false); // New state to prevent multiple drops

  const [, drop] = useDrop({
    accept: [ItemTypes.GRAPH_BLOCK, ItemTypes.WORKOUT_BLOCK],
    hover(item, monitor) {
      if (!ref.current) {
        return;
      }

      const hoverBoundingRect = ref.current.getBoundingClientRect();
      const hoverMiddleX = (hoverBoundingRect.right - hoverBoundingRect.left) / 2;
      const clientOffset = monitor.getClientOffset();
      const hoverClientX = clientOffset.x - hoverBoundingRect.left;

      if (item.type === ItemTypes.GRAPH_BLOCK) {
        const dragIndex = item.index;
        const hoverIndex = index;

        if (dragIndex === hoverIndex) {
          return;
        }

        // Determine the direction of the move
        if (dragIndex < hoverIndex && hoverClientX < hoverMiddleX) {
          return;
        }
        if (dragIndex > hoverIndex && hoverClientX > hoverMiddleX) {
          return;
        }

        // Perform the move
        moveBlock(dragIndex, hoverIndex);

        // Update the index for the dragged item
        item.index = hoverIndex;
      }

      if (item.type === ItemTypes.WORKOUT_BLOCK && !hasDropped) {
        const hoverIndex = index;

        // Determine whether to insert before or after based on mouse position
        if (hoverClientX < hoverMiddleX) {
          setInsertBefore(true);
          addBlockToGraph(item, hoverIndex);
        } else {
          setInsertBefore(false);
          addBlockToGraph(item, hoverIndex + 1);
        }

        setHasDropped(true);
      }
    },
    drop(item, monitor) {
      if (item.type === ItemTypes.WORKOUT_BLOCK && hasDropped) {
        // Reset the flag after drop
        setHasDropped(false);
      }
    },
    collect: (monitor) => {
      const isOver = monitor.isOver({ shallow: true });
      setIsOverCurrent(isOver);
      return {};
    },
  });

  const [{ isDragging }, drag] = useDrag({
    type: ItemTypes.GRAPH_BLOCK,
    item: { type: ItemTypes.GRAPH_BLOCK, id, index },
    collect: (monitor) => ({
      isDragging: monitor.isDragging(),
    }),
  });

  // Connect drag and drop
  drag(drop(ref));

  const handleRemove = () => {
    removeBlock(id);
  };

  // Safety check
  if (!block) {
    console.error(`GraphBlock with id ${id} is undefined`);
    return null;
  }

  return (
    <>
      {/* Placeholder */}
      {isOverCurrent && (
        <div
          className={`absolute ${
            insertBefore ? 'left-0 transform -translate-x-full' : 'right-0 transform translate-x-full'
          } top-0 h-full w-2 bg-blue-500 opacity-50`}
        ></div>
      )}

      <div
        ref={ref}
        className={`relative bg-[#4339F280] rounded cursor-move flex flex-col items-center transition-all duration-200
          ${isOverCurrent ? 'border-2 border-blue-500' : ''}
        `}
        style={{
          width: `calc(${100 / totalBlocks}% - 8px)`, // Even width distribution
          height: `${block.height}%`,
          marginRight: index !== totalBlocks - 1 ? '8px' : '0',
          opacity: isDragging ? 0.5 : 1,
        }}
      >
        {/* Remove Button */}
        <button
          onClick={handleRemove}
          className="absolute top-1 right-1 text-red-500 hover:text-red-700 text-xs"
          title="Remove Block"
        >
          &times;
        </button>
      </div>
    </>
  );
};

export default GraphBlock;
""
""
// WorkoutBlocks.js
import React from 'react';
import { useDrag } from 'react-dnd';
import { FiInfo } from 'react-icons/fi';
import { ItemTypes } from './constants';

const WorkoutBlock = ({ children, type, height }) => {
  const [{ isDragging }, drag] = useDrag({
    type: ItemTypes.WORKOUT_BLOCK,
    item: { type, height },
    collect: (monitor) => ({
      isDragging: monitor.isDragging(),
    }),
  });

  return (
    <div
      ref={drag}
      className={`relative bg-gray-200 rounded-lg overflow-hidden h-20 cursor-pointer ${
        isDragging ? 'opacity-50' : 'opacity-100'
      }`}
    >
      {children}
    </div>
  );
};

const WorkoutBlocks = () => {
  return (
    <div className="bg-white p-6 rounded-lg shadow-md max-w-sm w-full">
      <div className="flex justify-between items-center mb-3">
        <h2 className="text-lg font-semibold">Drag Blocks to Build Workout</h2>
        <FiInfo className="text-gray-400 text-2xl" />
      </div>

      <hr className="border-gray-300 mb-4" />

      <div className="grid grid-cols-2 gap-3">
        <WorkoutBlock type="block50" height={50}>
          <div className="absolute bottom-0 w-full h-1/2" style={{ background: '#4339F280' }}></div>
        </WorkoutBlock>

        <WorkoutBlock type="block75" height={75}>
          <div className="absolute bottom-0 w-full h-3/4" style={{ background: '#4339F280' }}></div>
        </WorkoutBlock>

        <WorkoutBlock type="block30" height={30}>
          <div className="absolute bottom-0 w-full h-1/3" style={{ background: '#4339F280' }}></div>
        </WorkoutBlock>

        {/* Single block with two columns */}
        <WorkoutBlock type="block60_40" height={60}>
          <div className="flex h-full gap-1 transform scale-y-[-1]">
            <div className="w-1/2 h-3/5" style={{ background: '#4339F280' }}></div>
            <div className="w-1/2 h-2/5" style={{ background: '#4339F280' }}></div>
          </div>
        </WorkoutBlock>

        {/* Single block with four columns */}
        <WorkoutBlock type="block80_60_40_20" height={80}>
          <div className="flex h-full gap-1 transform scale-y-[-1]">
            <div className="w-1/4 h-1/5" style={{ background: '#4339F280' }}></div>
            <div className="w-1/4 h-2/5" style={{ background: '#4339F280' }}></div>
            <div className="w-1/4 h-3/5" style={{ background: '#4339F280' }}></div>
            <div className="w-1/4 h-4/5" style={{ background: '#4339F280' }}></div>
          </div>
        </WorkoutBlock>

        {/* Another single block with reversed four columns */}
        <WorkoutBlock type="block20_40_60_80" height={20}>
          <div className="flex h-full gap-1 transform scale-y-[-1]">
            <div className="w-1/4 h-4/5" style={{ background: '#4339F280' }}></div>
            <div className="w-1/4 h-3/5" style={{ background: '#4339F280' }}></div>
            <div className="w-1/4 h-2/5" style={{ background: '#4339F280' }}></div>
            <div className="w-1/4 h-1/5" style={{ background: '#4339F280' }}></div>
          </div>
        </WorkoutBlock>
      </div>
    </div>
  );
};

export default WorkoutBlocks;
"""