"use client"; import { ArrowUpIcon } from "lucide-react"; import { useEffect, useState, useCallback } from "react"; import Link from "next/link"; import { cn } from "@/lib/utils"; interface ScrollToTopProps { className?: string; showIcon?: boolean; offset?: number; // Optional offset in pixels from the trigger point } export function ScrollToTop({ className, showIcon = true, offset = 0 }: ScrollToTopProps) { const [isVisible, setIsVisible] = useState(false); const checkScroll = useCallback(() => { // Calculate 50% of viewport height const halfViewportHeight = window.innerHeight * 0.5; // Check if scrolled past half viewport height (plus any offset) const scrolledPastHalfViewport = window.scrollY > (halfViewportHeight + offset); // Only update state if it changes to prevent unnecessary re-renders if (scrolledPastHalfViewport !== isVisible) { setIsVisible(scrolledPastHalfViewport); } }, [isVisible, offset]); useEffect(() => { // Initial check checkScroll(); // Set up scroll listener with debounce for better performance let timeoutId: NodeJS.Timeout; const handleScroll = () => { if (timeoutId) clearTimeout(timeoutId); timeoutId = setTimeout(checkScroll, 100); }; window.addEventListener('scroll', handleScroll, { passive: true }); // Cleanup return () => { window.removeEventListener('scroll', handleScroll); if (timeoutId) clearTimeout(timeoutId); }; }, [checkScroll]); const scrollToTop = useCallback((e: React.MouseEvent) => { e.preventDefault(); window.scrollTo({ top: 0, behavior: 'smooth' }); }, []); if (!isVisible) return null; return (