feat: complete dashboard widgets, fix tooltips, integrate chatbot, and update docs
This commit is contained in:
@@ -0,0 +1,69 @@
|
||||
import React, { useState, useRef, useEffect } from 'react';
|
||||
import { createPortal } from 'react-dom';
|
||||
import { Info } from 'lucide-react';
|
||||
|
||||
export const InfoTooltip = ({ text }) => {
|
||||
const [isVisible, setIsVisible] = useState(false);
|
||||
const [coords, setCoords] = useState({ top: 0, left: 0 });
|
||||
const triggerRef = useRef(null);
|
||||
|
||||
const updatePosition = () => {
|
||||
if (triggerRef.current) {
|
||||
const rect = triggerRef.current.getBoundingClientRect();
|
||||
setCoords({
|
||||
top: rect.top - 10, // Default to slightly above
|
||||
left: rect.left + rect.width / 2
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const handleMouseEnter = () => {
|
||||
updatePosition();
|
||||
setIsVisible(true);
|
||||
};
|
||||
|
||||
const handleMouseLeave = () => {
|
||||
setIsVisible(false);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (isVisible) {
|
||||
window.addEventListener('scroll', updatePosition);
|
||||
window.addEventListener('resize', updatePosition);
|
||||
}
|
||||
return () => {
|
||||
window.removeEventListener('scroll', updatePosition);
|
||||
window.removeEventListener('resize', updatePosition);
|
||||
};
|
||||
}, [isVisible]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<div
|
||||
ref={triggerRef}
|
||||
onMouseEnter={handleMouseEnter}
|
||||
onMouseLeave={handleMouseLeave}
|
||||
className="cursor-help inline-flex items-center justify-center ml-2"
|
||||
>
|
||||
<Info size={14} className="text-zinc-400" />
|
||||
</div>
|
||||
|
||||
{isVisible && createPortal(
|
||||
<div
|
||||
className="fixed z-[9999] w-48 p-2 bg-zinc-900 text-xs text-zinc-100 rounded-lg shadow-xl border border-zinc-700 text-center pointer-events-none transition-opacity duration-200"
|
||||
style={{
|
||||
top: coords.top,
|
||||
left: coords.left,
|
||||
transform: 'translate(-50%, -100%)', // Centered and above
|
||||
opacity: 1
|
||||
}}
|
||||
>
|
||||
{text}
|
||||
{/* Tiny triangle pointer */}
|
||||
<div className="absolute left-1/2 -translate-x-1/2 top-full w-0 h-0 border-l-[6px] border-l-transparent border-r-[6px] border-r-transparent border-t-[6px] border-t-zinc-900"></div>
|
||||
</div>,
|
||||
document.body
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user