|
|
|
|
|
import { renderHomePage, getHomePageSidebar } from './pages/HomePage.js'; |
|
|
import { renderAreaPage, getAreaPageSidebar } from './pages/AreaPage.js'; |
|
|
import { renderResourcesPage, getResourcesPageSidebar } from './pages/ResourcesPage.js'; |
|
|
|
|
|
class Router { |
|
|
constructor() { |
|
|
this.routes = { |
|
|
'/': 'home', |
|
|
'/home': 'home', |
|
|
'/efficiency': 'efficiency', |
|
|
'/personal': 'personal', |
|
|
'/rights': 'rights', |
|
|
'/ecosystems': 'ecosystems', |
|
|
'/about': 'resources' |
|
|
}; |
|
|
|
|
|
this.currentPage = null; |
|
|
this.init(); |
|
|
} |
|
|
|
|
|
init() { |
|
|
|
|
|
this.loadPage(window.location.pathname); |
|
|
|
|
|
|
|
|
window.addEventListener('popstate', (e) => { |
|
|
const path = window.location.pathname; |
|
|
const hash = window.location.hash; |
|
|
const fullUrl = path + hash; |
|
|
|
|
|
|
|
|
this.navigateToUrl(fullUrl); |
|
|
}); |
|
|
|
|
|
|
|
|
window.addEventListener('hashchange', (e) => { |
|
|
const hash = window.location.hash.substring(1); |
|
|
if (hash) { |
|
|
|
|
|
setTimeout(() => this.scrollToSection(hash), 100); |
|
|
} |
|
|
}); |
|
|
|
|
|
|
|
|
const initialHash = window.location.hash.substring(1); |
|
|
if (initialHash) { |
|
|
setTimeout(() => this.scrollToSection(initialHash), 200); |
|
|
} |
|
|
|
|
|
|
|
|
this.initializeNavigation(); |
|
|
} |
|
|
|
|
|
async loadPage(path) { |
|
|
const route = this.routes[path] || 'home'; |
|
|
|
|
|
if (this.currentPage === route) { |
|
|
|
|
|
return; |
|
|
} |
|
|
|
|
|
this.currentPage = route; |
|
|
|
|
|
try { |
|
|
switch (route) { |
|
|
case 'home': |
|
|
await this.loadHomePage(); |
|
|
break; |
|
|
case 'efficiency': |
|
|
case 'personal': |
|
|
case 'rights': |
|
|
case 'ecosystems': |
|
|
await this.loadAreaPage(route); |
|
|
break; |
|
|
case 'resources': |
|
|
await this.loadResourcesPage(); |
|
|
break; |
|
|
default: |
|
|
await this.loadHomePage(); |
|
|
} |
|
|
|
|
|
} catch (error) { |
|
|
console.error('Error loading page:', error); |
|
|
|
|
|
await this.loadHomePage(); |
|
|
} |
|
|
|
|
|
return Promise.resolve(); |
|
|
} |
|
|
|
|
|
async loadHomePage() { |
|
|
const mainContent = document.getElementById('main-content'); |
|
|
const leftSidebar = document.getElementById('left-sidebar'); |
|
|
|
|
|
if (!mainContent) { |
|
|
return; |
|
|
} |
|
|
|
|
|
try { |
|
|
|
|
|
const homePage = renderHomePage(); |
|
|
|
|
|
|
|
|
const contentContainer = mainContent.querySelector('.max-w-4xl') || mainContent; |
|
|
contentContainer.innerHTML = homePage.content; |
|
|
|
|
|
|
|
|
if (leftSidebar) { |
|
|
leftSidebar.innerHTML = getHomePageSidebar(); |
|
|
} |
|
|
|
|
|
|
|
|
if (homePage.init) { |
|
|
homePage.init(); |
|
|
} |
|
|
|
|
|
|
|
|
this.updateNavigation('home'); |
|
|
} catch (error) { |
|
|
|
|
|
const contentContainer = mainContent.querySelector('.max-w-4xl') || mainContent; |
|
|
contentContainer.innerHTML = ` |
|
|
<div class="bg-white rounded-lg shadow-sm p-8"> |
|
|
<h1 class="text-3xl font-bold text-red-600 mb-6">Error Loading Page</h1> |
|
|
<p class="text-gray-700">Sorry, there was an error loading the home page.</p> |
|
|
</div> |
|
|
`; |
|
|
} |
|
|
} |
|
|
|
|
|
async loadAreaPage(area) { |
|
|
const mainContent = document.getElementById('main-content'); |
|
|
const leftSidebar = document.getElementById('left-sidebar'); |
|
|
|
|
|
if (!mainContent) { |
|
|
return; |
|
|
} |
|
|
|
|
|
try { |
|
|
|
|
|
const areaPage = renderAreaPage(area); |
|
|
|
|
|
|
|
|
const contentContainer = mainContent.querySelector('.max-w-4xl') || mainContent; |
|
|
contentContainer.innerHTML = areaPage.content; |
|
|
|
|
|
|
|
|
if (leftSidebar) { |
|
|
leftSidebar.innerHTML = getAreaPageSidebar(area); |
|
|
} |
|
|
|
|
|
|
|
|
if (areaPage.init) { |
|
|
areaPage.init(); |
|
|
} |
|
|
} catch (error) { |
|
|
console.error(`Error loading ${area} page:`, error); |
|
|
|
|
|
|
|
|
const contentContainer = mainContent.querySelector('.max-w-4xl') || mainContent; |
|
|
contentContainer.innerHTML = ` |
|
|
<div class="bg-white rounded-lg shadow-sm p-8"> |
|
|
<h1 class="text-3xl font-bold text-red-600 mb-6">Error Loading Page</h1> |
|
|
<p class="text-gray-700">Sorry, there was an error loading the ${area} page.</p> |
|
|
</div> |
|
|
`; |
|
|
} |
|
|
|
|
|
this.updateNavigation(area); |
|
|
} |
|
|
|
|
|
async loadResourcesPage() { |
|
|
const mainContent = document.getElementById('main-content'); |
|
|
const leftSidebar = document.getElementById('left-sidebar'); |
|
|
|
|
|
if (!mainContent) return; |
|
|
|
|
|
try { |
|
|
|
|
|
const resourcesPage = renderResourcesPage(); |
|
|
|
|
|
|
|
|
const contentContainer = mainContent.querySelector('.max-w-4xl') || mainContent; |
|
|
contentContainer.innerHTML = resourcesPage.content; |
|
|
|
|
|
|
|
|
if (leftSidebar) { |
|
|
leftSidebar.innerHTML = getResourcesPageSidebar(); |
|
|
} |
|
|
|
|
|
|
|
|
if (resourcesPage.init) { |
|
|
resourcesPage.init(); |
|
|
} |
|
|
} catch (error) { |
|
|
|
|
|
const contentContainer = mainContent.querySelector('.max-w-4xl') || mainContent; |
|
|
contentContainer.innerHTML = ` |
|
|
<div class="bg-white rounded-lg shadow-sm p-8"> |
|
|
<h1 class="text-3xl font-bold text-red-600 mb-6">Error Loading Page</h1> |
|
|
<p class="text-gray-700">Sorry, there was an error loading the resources page.</p> |
|
|
</div> |
|
|
`; |
|
|
} |
|
|
|
|
|
this.updateNavigation('resources'); |
|
|
} |
|
|
|
|
|
updateNavigation(currentPage) { |
|
|
|
|
|
const navLinks = document.querySelectorAll('header nav a'); |
|
|
navLinks.forEach(link => { |
|
|
link.classList.remove('text-blue-600', 'bg-blue-50'); |
|
|
link.classList.add('text-gray-700'); |
|
|
|
|
|
const href = link.getAttribute('href'); |
|
|
if ((currentPage === 'home' && (href === '/' || href === '/home')) || |
|
|
(currentPage === 'resources' && href === '/about') || |
|
|
(currentPage !== 'home' && currentPage !== 'resources' && href === `/${currentPage}`)) { |
|
|
link.classList.remove('text-gray-700'); |
|
|
link.classList.add('text-blue-600', 'bg-blue-50'); |
|
|
} |
|
|
}); |
|
|
} |
|
|
|
|
|
|
|
|
initializeNavigation() { |
|
|
|
|
|
document.addEventListener('click', (e) => { |
|
|
const link = e.target.closest('a'); |
|
|
if (!link) return; |
|
|
|
|
|
const href = link.getAttribute('href'); |
|
|
if (!href) return; |
|
|
|
|
|
|
|
|
if (href.startsWith('/') && !href.startsWith('/js/') && !href.startsWith('/css/') && !href.startsWith('/images/')) { |
|
|
|
|
|
const path = href.split('#')[0]; |
|
|
if (this.routes[path]) { |
|
|
e.preventDefault(); |
|
|
this.navigateToUrl(href); |
|
|
} |
|
|
} else if (href.startsWith('#')) { |
|
|
|
|
|
e.preventDefault(); |
|
|
this.scrollToSection(href.substring(1)); |
|
|
} |
|
|
|
|
|
}); |
|
|
} |
|
|
|
|
|
navigateToUrl(fullUrl) { |
|
|
|
|
|
const [path, hash] = fullUrl.split('#'); |
|
|
|
|
|
|
|
|
window.history.pushState({}, '', fullUrl); |
|
|
|
|
|
|
|
|
this.loadPage(path).then(() => { |
|
|
if (hash) { |
|
|
setTimeout(() => this.scrollToSection(hash), 100); |
|
|
} else { |
|
|
|
|
|
setTimeout(() => { |
|
|
window.scrollTo({ top: 0, behavior: 'smooth' }); |
|
|
}, 100); |
|
|
} |
|
|
}); |
|
|
} |
|
|
|
|
|
scrollToSection(sectionId) { |
|
|
const element = document.getElementById(sectionId); |
|
|
if (element) { |
|
|
|
|
|
const elementRect = element.getBoundingClientRect(); |
|
|
const absoluteElementTop = elementRect.top + window.pageYOffset; |
|
|
const offset = 120; |
|
|
|
|
|
window.scrollTo({ |
|
|
top: absoluteElementTop - offset, |
|
|
behavior: 'smooth' |
|
|
}); |
|
|
} |
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
export const router = new Router(); |
|
|
|