import { useState, useEffect } from "react" export function useDebounce(value: T, delay: number): T { const [debouncedValue, setDebouncedValue] = useState(value) useEffect(() => { const handler = setTimeout(() => { setDebouncedValue(value) }, delay) return () => { clearTimeout(handler) } }, [value, delay]) return debouncedValue } export function useLocalStorage(key: string, initialValue: T) { const [storedValue, setStoredValue] = useState(() => { if (typeof window === "undefined") { return initialValue } try { const item = window.localStorage.getItem(key) return item ? JSON.parse(item) : initialValue } catch (error) { console.error(`Error reading localStorage key "${key}":`, error) return initialValue } }) const setValue = (value: T | ((val: T) => T)) => { try { const valueToStore = value instanceof Function ? value(storedValue) : value setStoredValue(valueToStore) if (typeof window !== "undefined") { window.localStorage.setItem(key, JSON.stringify(valueToStore)) } } catch (error) { console.error(`Error setting localStorage key "${key}":`, error) } } return [storedValue, setValue] as const } export function useIntersectionObserver( elementRef: React.RefObject, options: IntersectionObserverInit = {} ) { const [isIntersecting, setIsIntersecting] = useState(false) useEffect(() => { const element = elementRef.current if (!element) return const observer = new IntersectionObserver(([entry]) => { setIsIntersecting(entry.isIntersecting) }, options) observer.observe(element) return () => { observer.unobserve(element) } }, [elementRef, options]) return isIntersecting }