From 72ea8416fd74eed79c3dfbdbcc5e0d92b7b20671 Mon Sep 17 00:00:00 2001 From: Graham Darcey Date: Mon, 4 Aug 2025 09:49:00 -0400 Subject: [PATCH] fixes issue w/ tooltip that negatively affects production envs only --- app/bay/page.tsx | 92 +------- app/bay/tooltip.module.css | 45 +++- components/common/MultiPartProgressBar.tsx | 231 ++------------------- components/common/Tooltip.tsx | 138 +++--------- 4 files changed, 92 insertions(+), 414 deletions(-) diff --git a/app/bay/page.tsx b/app/bay/page.tsx index 2f5ed8f9..9f94fa8f 100644 --- a/app/bay/page.tsx +++ b/app/bay/page.tsx @@ -1064,35 +1064,7 @@ export function BayWithReviewMode({ session, status, router, impersonationData } > { - if (el) { - console.log('🚨 Bay: SHIP TOOLTIP mounted with MASSIVE dimensions:', { - width: el.offsetWidth, - height: el.offsetHeight, - clientWidth: el.clientWidth, - clientHeight: el.clientHeight, - scrollWidth: el.scrollWidth, - scrollHeight: el.scrollHeight, - boundingRect: el.getBoundingClientRect(), - className: el.className, - computedStyles: { - width: window.getComputedStyle(el).width, - height: window.getComputedStyle(el).height, - position: window.getComputedStyle(el).position, - display: window.getComputedStyle(el).display, - zIndex: window.getComputedStyle(el).zIndex, - overflow: window.getComputedStyle(el).overflow, - pointerEvents: window.getComputedStyle(el).pointerEvents - }, - childElements: Array.from(el.children).map(child => ({ - tagName: child.tagName, - className: child.className, - width: child.offsetWidth, - height: child.offsetHeight - })) - }); - } - }} + > { - console.log('🚨 Bay: Ship image MOUSE ENTER - tooltip showing'); - console.log('🚨 Bay: Mouse event target vs currentTarget:', { - target: e.target, - currentTarget: e.currentTarget, - targetDimensions: { - width: (e.target as HTMLElement).offsetWidth, - height: (e.target as HTMLElement).offsetHeight - }, - currentTargetDimensions: { - width: e.currentTarget.offsetWidth, - height: e.currentTarget.offsetHeight - } - }); + // Mouse enter handled by tooltip }} onMouseLeave={(e) => { - console.log('🚨 Bay: Ship image MOUSE LEAVE - tooltip hiding'); + // Mouse leave handled by tooltip }} />
{ - console.log('🔍 Bay: Progress bar container clicked'); setIsProgressModalOpen(true); }} title="When this progress bar reaches 100%, you're eligible for going to the island!" - onMouseEnter={(e) => { - console.log('🚨 Bay: Progress bar container MOUSE ENTER:', { - clientX: e.clientX, - clientY: e.clientY, - targetWidth: e.currentTarget.offsetWidth, - targetHeight: e.currentTarget.offsetHeight, - zIndex: window.getComputedStyle(e.currentTarget).zIndex, - pointerEvents: window.getComputedStyle(e.currentTarget).pointerEvents - }); - }} - onMouseMove={(e) => { - // Only log occasionally to avoid spam - if (Math.random() < 0.1) { - console.log('🚨 Bay: Mouse moving over progress bar area'); - } - }} - ref={(el) => { - if (el) { - console.log('🚨 Bay: Progress bar container mounted - checking for overlap issues:', { - width: el.offsetWidth, - height: el.offsetHeight, - boundingRect: el.getBoundingClientRect(), - computedStyles: { - display: window.getComputedStyle(el).display, - visibility: window.getComputedStyle(el).visibility, - opacity: window.getComputedStyle(el).opacity, - position: window.getComputedStyle(el).position, - zIndex: window.getComputedStyle(el).zIndex, - pointerEvents: window.getComputedStyle(el).pointerEvents, - flexGrow: window.getComputedStyle(el).flexGrow - }, - className: el.className, - // Check if elements are overlapping - siblingElements: Array.from(el.parentElement?.children || []).map((sibling, i) => ({ - index: i, - isCurrentElement: sibling === el, - tagName: sibling.tagName, - className: sibling.className, - boundingRect: sibling.getBoundingClientRect(), - zIndex: window.getComputedStyle(sibling).zIndex - })) - }); - } - }} + > {(() => { console.log('🔍 Bay: About to render MultiPartProgressBar with:', { diff --git a/app/bay/tooltip.module.css b/app/bay/tooltip.module.css index 7f527931..25c134e1 100644 --- a/app/bay/tooltip.module.css +++ b/app/bay/tooltip.module.css @@ -9,14 +9,17 @@ visibility: hidden; opacity: 0; width: max-content; - max-width: 280px; + max-width: 200px; background-color: #333; color: #fff; text-align: center; - padding: 10px 14px; + padding: 8px 12px; border-radius: 6px; - font-size: 13px; - line-height: 1.4; + font-size: 14px; + + /* Position the tooltip */ + position: absolute; + z-index: 100; /* Animation */ transition: opacity 0.3s; @@ -25,7 +28,39 @@ display: none; } -/* Show the tooltip on hover - removed since now handled by JavaScript */ +/* Position: top (default) */ +.top { + bottom: 125%; + left: 50%; + transform: translateX(-50%); +} + +/* Position: bottom */ +.bottom { + top: 125%; + left: 50%; + transform: translateX(-50%); +} + +/* Position: left */ +.left { + right: 125%; + top: 50%; + transform: translateY(-50%); +} + +/* Position: right */ +.right { + left: 125%; + top: 50%; + transform: translateY(-50%); +} + +/* Show the tooltip on hover */ +.tooltipContainer:hover .tooltipContent { + visibility: visible; + opacity: 1; +} /* Arrow indicators for each position */ .top::after { diff --git a/components/common/MultiPartProgressBar.tsx b/components/common/MultiPartProgressBar.tsx index e1e173fe..d63d394c 100644 --- a/components/common/MultiPartProgressBar.tsx +++ b/components/common/MultiPartProgressBar.tsx @@ -41,7 +41,7 @@ export function calculateProgressSegmentsFromData({ const metrics = progressMetrics || { shippedHours: 0, viralHours: 0, otherHours: 0, totalHours: 0, totalPercentage: 0, rawHours: 0, currency: 0, purchasedProgressHours: 0, totalProgressWithPurchased: 0, totalPercentageWithPurchased: 0 }; if (!projects || !Array.isArray(projects)) { - console.log('ProgressBar: No projects data, showing empty state'); + return [{ value: 100, color: '#e5e7eb', tooltip: 'No projects found', status: 'pending' }]; } @@ -51,8 +51,7 @@ export function calculateProgressSegmentsFromData({ const otherPercentage = (metrics.otherHours / 60) * 100; const purchasedPercentage = metrics.purchasedProgressHours || 0; - console.log(`ProgressBar: Progress breakdown - Shipped: ${shippedPercentage.toFixed(1)}%, Viral: ${viralPercentage.toFixed(1)}%, Other: ${otherPercentage.toFixed(1)}%, Purchased: ${purchasedPercentage.toFixed(1)}%`); - + // Create segments array const segments: ProgressSegment[] = []; if (metrics.shippedHours > 0) { @@ -130,69 +129,14 @@ export default function MultiPartProgressBar({ // Memoize computedSegments to avoid infinite update loop const computedSegments = useMemo(() => { const result = segments || calculateProgressSegmentsFromData({ projects, progressMetrics }); - console.log('ProgressBar: Calculated', result.length, 'segments with total value:', result.reduce((sum, s) => sum + s.value, 0)); + return result; }, [segments, projects, progressMetrics]); const [processedSegments, setProcessedSegments] = useState>([]); const [totalValue, setTotalValue] = useState(0); const [maxValue, setMaxValue] = useState(0); - // Log CSS modules loading on mount and check actual CSS properties - useEffect(() => { - console.log('🚨 CSS MODULES DEEP ANALYSIS:', { - stylesImported: !!styles, - stylesKeys: Object.keys(styles || {}), - containerClass: styles?.container, - trackClass: styles?.track, - segmentClass: styles?.segment, - animatedClass: styles?.animated, - roundedClass: styles?.rounded, - allStyles: styles - }); - - // Check if CSS classes actually apply the expected styles - const testDiv = document.createElement('div'); - testDiv.className = styles?.container || ''; - document.body.appendChild(testDiv); - - const containerStyles = window.getComputedStyle(testDiv); - console.log('🚨 ACTUAL CSS PROPERTIES FOR CONTAINER CLASS:', { - className: testDiv.className, - width: containerStyles.width, - margin: containerStyles.margin, - position: containerStyles.position, - display: containerStyles.display, - allComputedStyles: { - width: containerStyles.width, - height: containerStyles.height, - margin: containerStyles.margin, - padding: containerStyles.padding, - position: containerStyles.position, - display: containerStyles.display, - boxSizing: containerStyles.boxSizing - } - }); - - testDiv.className = styles?.track || ''; - const trackStyles = window.getComputedStyle(testDiv); - console.log('🚨 ACTUAL CSS PROPERTIES FOR TRACK CLASS:', { - className: testDiv.className, - width: trackStyles.width, - backgroundColor: trackStyles.backgroundColor, - display: trackStyles.display, - flexDirection: trackStyles.flexDirection, - allComputedStyles: { - width: trackStyles.width, - height: trackStyles.height, - backgroundColor: trackStyles.backgroundColor, - display: trackStyles.display, - flexDirection: trackStyles.flexDirection, - overflow: trackStyles.overflow - } - }); - - document.body.removeChild(testDiv); - }, []); + // Process segments and calculate widths useEffect(() => { @@ -214,54 +158,19 @@ export default function MultiPartProgressBar({ }; }); - console.log(`ProgressBar: Processed ${processed.length} segments, widths:`, processed.map(s => s.width).join(', ')); + setProcessedSegments(processed); }, [computedSegments, max]); // Log when rendering - console.log(`ProgressBar: Rendering ${processedSegments.length} segments`); + return (
{ if (el) { - // Trace the entire width inheritance chain - let current = el; - let chain = []; - let depth = 0; - - while (current && depth < 10) { - const computed = window.getComputedStyle(current); - chain.push({ - depth, - tagName: current.tagName, - className: current.className, - offsetWidth: current.offsetWidth, - offsetHeight: current.offsetHeight, - computedWidth: computed.width, - computedHeight: computed.height, - display: computed.display, - flex: computed.flex, - flexGrow: computed.flexGrow, - flexShrink: computed.flexShrink, - flexBasis: computed.flexBasis, - position: computed.position, - boxSizing: computed.boxSizing - }); - current = current.parentElement; - depth++; - } - - console.log('🚨 WIDTH INHERITANCE CHAIN ANALYSIS:', { - progressBarContainer: { - width: el.offsetWidth, - height: el.offsetHeight, - className: el.className - }, - fullChain: chain, - rootCause: chain.find(c => c.offsetWidth === 0) || 'No zero-width parent found' - }); + // Container element mounted } }} > @@ -270,39 +179,7 @@ export default function MultiPartProgressBar({ style={{ height: `${height}px` }} ref={(el) => { if (el) { - console.log('🚨 TRACK VISIBILITY CHECK:', { - width: el.offsetWidth, - height: el.offsetHeight, - className: el.className, - inlineHeight: `${height}px`, - boundingRect: el.getBoundingClientRect(), - computedStyles: { - width: window.getComputedStyle(el).width, - height: window.getComputedStyle(el).height, - backgroundColor: window.getComputedStyle(el).backgroundColor, - display: window.getComputedStyle(el).display, - flexDirection: window.getComputedStyle(el).flexDirection, - overflow: window.getComputedStyle(el).overflow, - visibility: window.getComputedStyle(el).visibility, - opacity: window.getComputedStyle(el).opacity, - border: window.getComputedStyle(el).border, - padding: window.getComputedStyle(el).padding, - margin: window.getComputedStyle(el).margin - }, - trackClass: styles.track, - roundedClass: styles.rounded, - hasTrackClass: !!styles.track, - childrenCount: el.children.length, - actualChildrenInfo: Array.from(el.children).map((child, i) => ({ - index: i, - tagName: child.tagName, - className: child.className, - offsetWidth: child.offsetWidth, - offsetHeight: child.offsetHeight, - computedBackground: window.getComputedStyle(child).backgroundColor - })), - isTrackVisible: el.offsetWidth > 0 && el.offsetHeight > 0 - }); + // Track element mounted } }} > @@ -326,97 +203,21 @@ export default function MultiPartProgressBar({ data-tooltip={segment.tooltip} data-tooltip-position={tooltipPosition} data-status={segment.status} - onMouseEnter={(e) => { - console.log(`🔍 ProgressBar: Segment ${index} MOUSE ENTER:`, { - width: segment.width, - actualWidth: segment.actualWidth, - backgroundColor: segment.color, - tooltip: segment.tooltip, - className: segmentClassName, - hasDataTooltip: !!segment.tooltip, - elementWidth: e.currentTarget.offsetWidth, - elementHeight: e.currentTarget.offsetHeight, - computedStyles: { - position: window.getComputedStyle(e.currentTarget).position, - cursor: window.getComputedStyle(e.currentTarget).cursor, - zIndex: window.getComputedStyle(e.currentTarget).zIndex, - display: window.getComputedStyle(e.currentTarget).display, - visibility: window.getComputedStyle(e.currentTarget).visibility - } - }); - - // Check tooltip pseudo-element after a short delay - setTimeout(() => { - const pseudoElement = window.getComputedStyle(e.currentTarget, '::after'); - console.log(`🔍 ProgressBar: Segment ${index} tooltip pseudo-element check:`, { - content: pseudoElement.content, - display: pseudoElement.display, - position: pseudoElement.position, - backgroundColor: pseudoElement.backgroundColor, - color: pseudoElement.color, - zIndex: pseudoElement.zIndex, - transform: pseudoElement.transform, - bottom: pseudoElement.bottom, - top: pseudoElement.top, - left: pseudoElement.left - }); - }, 10); - }} + onMouseEnter={(e) => { + // Segment mouse enter + }} onMouseLeave={(e) => { - console.log(`🔍 ProgressBar: Segment ${index} MOUSE LEAVE`); + }} onMouseOver={(e) => { - console.log(`🔍 ProgressBar: Segment ${index} MOUSE OVER - tooltip should show`); + }} onMouseOut={(e) => { - console.log(`🔍 ProgressBar: Segment ${index} MOUSE OUT - tooltip should hide`); + }} ref={(el) => { if (el && index === 0) { - console.log('🚨 SEGMENT VISIBILITY CHECK:', { - offsetWidth: el.offsetWidth, - offsetHeight: el.offsetHeight, - clientWidth: el.clientWidth, - clientHeight: el.clientHeight, - scrollWidth: el.scrollWidth, - scrollHeight: el.scrollHeight, - className: el.className, - hasTooltipAttr: el.hasAttribute('data-tooltip'), - tooltipValue: el.getAttribute('data-tooltip'), - boundingRect: el.getBoundingClientRect(), - computedStyles: { - width: window.getComputedStyle(el).width, - height: window.getComputedStyle(el).height, - display: window.getComputedStyle(el).display, - position: window.getComputedStyle(el).position, - backgroundColor: window.getComputedStyle(el).backgroundColor, - visibility: window.getComputedStyle(el).visibility, - opacity: window.getComputedStyle(el).opacity, - zIndex: window.getComputedStyle(el).zIndex, - border: window.getComputedStyle(el).border, - borderRadius: window.getComputedStyle(el).borderRadius, - transform: window.getComputedStyle(el).transform, - overflow: window.getComputedStyle(el).overflow - }, - inlineStyles: el.style.cssText, - actualBackgroundColor: segment.color, - actualWidth: segment.width, - isVisible: el.offsetWidth > 0 && el.offsetHeight > 0 - }); - - // Check if element is actually visible in viewport - const rect = el.getBoundingClientRect(); - const isInViewport = ( - rect.top >= 0 && - rect.left >= 0 && - rect.bottom <= window.innerHeight && - rect.right <= window.innerWidth - ); - console.log('🚨 VIEWPORT VISIBILITY:', { - isInViewport, - rect, - windowSize: { width: window.innerWidth, height: window.innerHeight } - }); + // First segment element mounted } }} /> @@ -451,4 +252,4 @@ export default function MultiPartProgressBar({ )}
); -} \ No newline at end of file +} diff --git a/components/common/Tooltip.tsx b/components/common/Tooltip.tsx index f3461e96..6a5ee15c 100644 --- a/components/common/Tooltip.tsx +++ b/components/common/Tooltip.tsx @@ -11,143 +11,69 @@ interface TooltipProps { } const Tooltip: React.FC = ({ content, children, position = 'auto', className = '' }) => { - const containerRef = useRef(null); - const [isVisible, setIsVisible] = useState(false); - const [tooltipStyle, setTooltipStyle] = useState({}); + const tooltipRef = useRef(null); const [tooltipPosition, setTooltipPosition] = useState<'top' | 'right' | 'bottom' | 'left'>('top'); - // Function to update tooltip position based on container position + // Function to determine the best position for the tooltip const updateTooltipPosition = () => { - if (!containerRef.current) return; + if (!tooltipRef.current) return; - const container = containerRef.current; - const containerRect = container.getBoundingClientRect(); + const tooltip = tooltipRef.current; + const rect = tooltip.getBoundingClientRect(); const viewportHeight = window.innerHeight; const viewportWidth = window.innerWidth; + const scrollY = window.scrollY; // Default to top position let newPosition: 'top' | 'right' | 'bottom' | 'left' = 'top'; - let newStyle: React.CSSProperties = {}; // If fixed position was specified, use it if (position !== 'auto') { newPosition = position as 'top' | 'right' | 'bottom' | 'left'; } else { - // Determine best position based on available space - if (containerRect.bottom > viewportHeight - 100) { + // Near the bottom of the viewport, show above + if (rect.bottom > viewportHeight - 100) { newPosition = 'top'; - } else if (containerRect.top < 100) { + } + // Near the top of the viewport, show below + else if (rect.top < 100) { newPosition = 'bottom'; - } else if (containerRect.left < 150) { + } + // Near the left edge, show to the right + else if (rect.left < 100) { newPosition = 'right'; - } else if (containerRect.right > viewportWidth - 150) { + } + // Near the right edge, show to the left + else if (rect.right > viewportWidth - 100) { newPosition = 'left'; } } - // Calculate positioning based on container's viewport position - switch (newPosition) { - case 'top': - newStyle = { - position: 'fixed', - top: containerRect.top - 10, - left: containerRect.left + containerRect.width / 2, - transform: 'translate(-50%, -100%)', - zIndex: 10000 - }; - break; - case 'bottom': - newStyle = { - position: 'fixed', - top: containerRect.bottom + 10, - left: containerRect.left + containerRect.width / 2, - transform: 'translate(-50%, 0)', - zIndex: 10000 - }; - break; - case 'left': - newStyle = { - position: 'fixed', - top: containerRect.top + containerRect.height / 2, - left: containerRect.left - 10, - transform: 'translate(-100%, -50%)', - zIndex: 10000 - }; - break; - case 'right': - newStyle = { - position: 'fixed', - top: containerRect.top + containerRect.height / 2, - left: containerRect.right + 10, - transform: 'translate(0, -50%)', - zIndex: 10000 - }; - break; - } - setTooltipPosition(newPosition); - setTooltipStyle(newStyle); - }; - - const handleMouseEnter = () => { - setIsVisible(true); - updateTooltipPosition(); - }; - - const handleMouseLeave = () => { - setIsVisible(false); }; - // Update position on scroll and resize + // Update position on mount and window resize useEffect(() => { - if (isVisible) { - updateTooltipPosition(); - } - - const handleScroll = () => { - if (isVisible) { - updateTooltipPosition(); - } - }; - - const handleResize = () => { - if (isVisible) { - updateTooltipPosition(); - } - }; + // Initial position update + updateTooltipPosition(); - window.addEventListener('scroll', handleScroll, { passive: true }); - window.addEventListener('resize', handleResize); + // Update on resize + window.addEventListener('resize', updateTooltipPosition); + window.addEventListener('scroll', updateTooltipPosition); return () => { - window.removeEventListener('scroll', handleScroll); - window.removeEventListener('resize', handleResize); + window.removeEventListener('resize', updateTooltipPosition); + window.removeEventListener('scroll', updateTooltipPosition); }; - }, [isVisible]); + }, []); return ( - <> - - {children} - - {isVisible && ( -
- {content} -
- )} - +
+ {children} +
+ {content} +
+
); };