import React, { createContext, useContext, useState, ReactNode, useEffect } from 'react'; type PageType = 'home' | 'about' | 'blog' | 'careers' | 'privacy' | 'terms' | 'faq' | 'contact'; interface RouterContextType { currentPage: PageType; navigateTo: (page: PageType, hash?: string) => void; } const RouterContext = createContext(undefined); // Map page types to URL paths const pageToPath: Record = { home: '/', about: '/about', blog: '/blog', careers: '/careers', privacy: '/privacy', terms: '/terms', faq: '/faq', contact: '/contact', }; // Map URL paths to page types const pathToPage: Record = { '/': 'home', '/about': 'about', '/blog': 'blog', '/careers': 'careers', '/privacy': 'privacy', '/terms': 'terms', '/faq': 'faq', '/contact': 'contact', }; // Helper function to scroll to an element with retry logic function scrollToElement(elementId: string, initialDelay: number = 150) { let attempts = 0; const maxAttempts = 10; const tryScroll = () => { const element = document.getElementById(elementId); if (element) { element.scrollIntoView({ behavior: 'smooth', block: 'start' }); return true; } return false; }; // Try immediately setTimeout(() => { if (!tryScroll()) { // If element not found, retry with increasing delays const retryInterval = setInterval(() => { attempts++; if (tryScroll() || attempts >= maxAttempts) { clearInterval(retryInterval); } }, 100); } }, initialDelay); } export function RouterProvider({ children }: { children: ReactNode }) { // Initialize page based on current URL path const getInitialPage = (): PageType => { const path = window.location.pathname; return pathToPage[path] || 'home'; }; const [currentPage, setCurrentPage] = useState(getInitialPage); // Handle initial page load useEffect(() => { const pathname = window.location.pathname; // Ensure pathname is normalized if (pathname === '' || pathname === null) { window.history.replaceState({ page: 'home' }, '', '/'); } }, []); const navigateTo = (page: PageType, hash?: string) => { setCurrentPage(page); const path = pageToPath[page]; const url = hash ? `${path}#${hash}` : path; // Update browser URL without reloading window.history.pushState({ page }, '', url); if (hash) { // If there's a hash, scroll to the section scrollToElement(hash, 150); } else { window.scrollTo({ top: 0, behavior: 'smooth' }); } }; // Handle browser back/forward buttons useEffect(() => { const handlePopState = (event: PopStateEvent) => { const path = window.location.pathname; const page = pathToPage[path] || 'home'; setCurrentPage(page); // Handle hash if present const hash = window.location.hash.replace('#', ''); if (hash) { scrollToElement(hash); } else { window.scrollTo({ top: 0, behavior: 'smooth' }); } }; window.addEventListener('popstate', handlePopState); return () => { window.removeEventListener('popstate', handlePopState); }; }, []); // Handle initial hash on page load (separate effect to run after render) useEffect(() => { const hash = window.location.hash.replace('#', ''); if (hash) { // Use longer delay for initial page load to ensure all components are mounted scrollToElement(hash, 800); } }, [currentPage]); // Additional effect to handle hash on first mount useEffect(() => { const hash = window.location.hash.replace('#', ''); if (hash) { // Extra attempt with even longer delay for slow network connections scrollToElement(hash, 1200); } }, []); return ( {children} ); } export function useRouter() { const context = useContext(RouterContext); if (context === undefined) { throw new Error('useRouter must be used within a RouterProvider'); } return context; }