diff --git a/src/components/Tutorial.jsx b/src/components/Tutorial.jsx index 15cbbaa..5be2285 100644 --- a/src/components/Tutorial.jsx +++ b/src/components/Tutorial.jsx @@ -135,6 +135,29 @@ const Tutorial = ({ } ]; + const handleNext = () => { + if (step === STEPS.length - 2) { // Finish step + // Open Login Modal + setIsLoginOpen(true); + // Wait a bit for modal to open then next + setTimeout(() => setStep(s => s + 1), 500); + } else if (step >= STEPS.length - 1) { + // End + setStep(-2); + setIsVisible(false); + } else { + setStep(s => s + 1); + } + }; + + const handleSkip = (dontShowAgain) => { + if (dontShowAgain) { + localStorage.setItem('rail_tutorial_skipped', 'true'); + } + setStep(-2); + setIsVisible(false); + }; + // Initialization check useEffect(() => { const skipped = localStorage.getItem('rail_tutorial_skipped'); @@ -325,111 +348,6 @@ const Tutorial = ({ return () => observer.disconnect(); }, [rect, step]); - // Strict Positioning Logic - useLayoutEffect(() => { - if (step < 0 || step >= STEPS.length || !rect || !tooltipRef.current) return; - - const currentStep = STEPS[step]; - const PADDING = 20; - - // Measure ACTUAL tooltip dimensions - const CARD_W = tooltipRef.current.offsetWidth || 384; - const CARD_H = tooltipRef.current.offsetHeight || 250; - - let top, left, transform = 'none'; - - if (currentStep.position === 'bottom') { - top = rect.top + rect.height + 20; - left = rect.left; - } else if (currentStep.position === 'top') { - top = rect.top - CARD_H - 20; - left = rect.left; - } else if (currentStep.position === 'right') { - top = rect.top; - left = rect.left + rect.width + 20; - } else if (currentStep.position === 'left') { - top = rect.top; - left = rect.left - CARD_W - 20; - } else { // center - top = '50%'; - left = '50%'; - transform = 'translate(-50%, -50%)'; - } - - // --- Strict Boundary Logic --- - const winH = window.innerHeight; - const winW = window.innerWidth; - - if (typeof top === 'number') { - // 1. Flip Logic (Vertical) - // If overflow bottom, try flip top - if (top + CARD_H > winH - PADDING) { - if (currentStep.position === 'bottom') { - const flippedTop = rect.top - CARD_H - 20; - // Only flip if there is space on top - if (flippedTop > PADDING) top = flippedTop; - } - } - // If overflow top (e.g. from flip or 'top' pos), try flip bottom - if (top < PADDING) { - if (currentStep.position === 'top') { - const flippedBottom = rect.top + rect.height + 20; - if (flippedBottom + CARD_H < winH - PADDING) top = flippedBottom; - } - } - - // 2. Clamp Logic (Vertical) - Final fallback - if (top < PADDING) top = PADDING; - if (top + CARD_H > winH - PADDING) top = winH - CARD_H - PADDING; - } - - if (typeof left === 'number') { - // 1. Flip Logic (Horizontal) - if (left + CARD_W > winW - PADDING) { - if (currentStep.position === 'right') { - const flippedLeft = rect.left - CARD_W - 20; - if (flippedLeft > PADDING) left = flippedLeft; - } - } - if (left < PADDING) { - if (currentStep.position === 'left') { - const flippedRight = rect.left + rect.width + 20; - if (flippedRight + CARD_W < winW - PADDING) left = flippedRight; - } - } - - // 2. Clamp Logic (Horizontal) - if (left < PADDING) left = PADDING; - if (left + CARD_W > winW - PADDING) left = winW - CARD_W - PADDING; - } - - setTooltipPos({ top, left, transform }); - - }, [rect, step]); // Re-run when rect changes (target moves) or step changes (content changes) - - const handleNext = () => { - if (step === STEPS.length - 2) { // Finish step - // Open Login Modal - setIsLoginOpen(true); - // Wait a bit for modal to open then next - setTimeout(() => setStep(s => s + 1), 500); - } else if (step >= STEPS.length - 1) { - // End - setStep(-2); - setIsVisible(false); - } else { - setStep(s => s + 1); - } - }; - - const handleSkip = (dontShowAgain) => { - if (dontShowAgain) { - localStorage.setItem('rail_tutorial_skipped', 'true'); - } - setStep(-2); - setIsVisible(false); - }; - if (!isVisible || step < 0) return null; const currentStep = STEPS[step]; @@ -460,7 +378,10 @@ const Tutorial = ({