steake's picture
Fix the broken site elements such as nav bar etc
b1f5a5d verified
// Theme toggle functionality
const themeToggle = document.getElementById('themeToggle');
const html = document.documentElement;
// Add null check for themeToggle
if (themeToggle) {
const icon = themeToggle.querySelector('i');
// Check for saved theme preference or default to dark
const currentTheme = localStorage.getItem('theme') || 'dark';
html.classList.toggle('dark', currentTheme === 'dark');
updateThemeIcon(currentTheme);
function updateThemeIcon(theme) {
if (theme === 'dark') {
icon.setAttribute('data-feather', 'sun');
} else {
icon.setAttribute('data-feather', 'moon');
}
feather.replace();
}
themeToggle.addEventListener('click', () => {
const newTheme = html.classList.contains('dark') ? 'light' : 'dark';
html.classList.toggle('dark');
localStorage.setItem('theme', newTheme);
updateThemeIcon(newTheme);
});
}
// Initialize on page load
document.addEventListener('DOMContentLoaded', () => {
feather.replace();
// Add loading animation
document.body.classList.add('animate-fade-in');
// Initialize tooltips or other interactive elements
console.log('Khmer23 Luxury Real Estate Platform Initialized');
// Ensure navbar component is loaded
const navbar = document.querySelector('custom-navbar');
const backupNav = document.getElementById('backup-nav');
if (navbar) {
console.log('Navbar component found and loaded');
// Hide backup nav if component loads
if (backupNav) {
backupNav.classList.add('hidden');
}
} else {
console.error('Navbar component not found! Using backup navigation');
// Show backup nav if component fails
if (backupNav) {
backupNav.classList.remove('hidden');
}
// Adjust body padding for backup nav
document.body.style.paddingTop = '80px';
}
});
// Live activity feed
const activities = [
{ type: 'sale', location: 'Kep', price: '$2.4M', status: 'closed' },
{ type: 'rental', location: 'Phnom Penh', price: '$8,500/mo', status: 'signed' },
{ type: 'sale', location: 'Sihanoukville', price: '$3.1M', status: 'pending' },
{ type: 'rental', location: 'Kampot', price: '$6,200/mo', status: 'closed' },
{ type: 'sale', location: 'Phnom Penh', price: '$5.2M', status: 'closed' },
{ type: 'rental', location: 'Kep', price: '$12,000/mo', status: 'signed' }
];
function addActivityItem() {
const feed = document.getElementById('activityFeed');
if (!feed) return;
const activity = activities[Math.floor(Math.random() * activities.length)];
const item = document.createElement('div');
item.className = 'activity-item flex items-center justify-between py-2 border-b border-slate-800 last:border-0';
const icon = activity.type === 'sale' ? '🏠' : '🔑';
const color = activity.status === 'closed' ? 'text-emerald-400' : activity.status === 'signed' ? 'text-amber-400' : 'text-slate-500';
item.innerHTML = `
<div class="flex items-center gap-2">
<span class="text-lg">${icon}</span>
<div>
<div class="${color} font-light capitalize">${activity.type}${activity.location}</div>
<div class="text-slate-500">${activity.price}</div>
</div>
</div>
<div class="text-xs text-slate-600">${formatTime(Date.now())}</div>
`;
feed.insertBefore(item, feed.firstChild);
// Keep only last 4 activities
while (feed.children.length > 4) {
feed.removeChild(feed.lastChild);
}
}
function formatTime(timestamp) {
const now = new Date();
const time = new Date(timestamp);
const diff = Math.floor((now - time) / 1000);
if (diff < 60) return 'Just now';
if (diff < 3600) return `${Math.floor(diff / 60)}m ago`;
if (diff < 86400) return `${Math.floor(diff / 3600)}h ago`;
return `${Math.floor(diff / 86400)}d ago`;
}
// Initialize activity feed
if (document.getElementById('activityFeed')) {
// Add initial activities
for (let i = 0; i < 3; i++) {
addActivityItem();
}
// Add new activity every 10 seconds
setInterval(addActivityItem, 10000);
}
// Contact form handling
const contactForm = document.getElementById('contactForm');
if (contactForm) {
contactForm.addEventListener('submit', (e) => {
e.preventDefault();
// Show success message
const formContainer = contactForm.parentElement;
formContainer.innerHTML = `
<div class="text-center py-12">
<div class="w-20 h-20 mx-auto mb-6 bg-emerald-500/20 rounded-full flex items-center justify-center">
<i data-feather="check-circle" class="w-10 h-10 text-emerald-400"></i>
</div>
<h3 class="text-2xl font-light mb-4">Request Received</h3>
<p class="text-slate-400 mb-8">
Your inquiry has been submitted for review. Our membership committee will contact qualified candidates within 72 hours.
</p>
<div class="bg-slate-800 rounded-2xl p-6 text-left">
<h4 class="text-lg font-light mb-3 text-emerald-400">Next Steps:</h4>
<ul class="space-y-2 text-slate-300 text-sm font-light">
<li>• Preliminary qualification review (24-48 hours)</li>
<li>• Background verification (additional 24 hours)</li>
<li>• Personal consultation by invitation only</li>
<li>• Access to exclusive property portfolio</li>
</ul>
</div>
<a href="index.html" class="inline-block mt-8 px-8 py-3 bg-slate-800 hover:bg-slate-700 text-alabaster rounded-full transition-all duration-300">
Return to Home
</a>
</div>
`;
feather.replace();
});
}
// Smooth scroll for anchor links
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
anchor.addEventListener('click', function (e) {
e.preventDefault();
const target = document.querySelector(this.getAttribute('href'));
if (target) {
target.scrollIntoView({
behavior: 'smooth',
block: 'start'
});
}
});
});
// Intersection Observer for fade-in animations
const observerOptions = {
threshold: 0.1,
rootMargin: '0px 0px -50px 0px'
};
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
entry.target.classList.add('animate-fade-in');
observer.unobserve(entry.target);
}
});
}, observerOptions);
// Observe elements for animation
document.querySelectorAll('section').forEach(section => {
observer.observe(section);
});
// Property filter functionality
const filterSelects = document.querySelectorAll('select');
filterSelects.forEach(select => {
select.addEventListener('change', () => {
// Add filter animation
const cards = document.querySelectorAll('.group.cursor-pointer');
cards.forEach((card, index) => {
setTimeout(() => {
card.classList.add('animate-fade-in');
}, index * 100);
});
});
});
// Load more functionality
const loadMoreBtn = document.querySelector('button:has([text="Load More"])');
if (loadMoreBtn) {
loadMoreBtn.addEventListener('click', () => {
loadMoreBtn.innerHTML = '<span class="flex items-center gap-2"><svg class="animate-spin h-4 w-4" viewBox="0 0 24 24"><circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4" fill="none"></circle><path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path></svg>Loading...</span>';
setTimeout(() => {
loadMoreBtn.innerHTML = 'No More Properties';
loadMoreBtn.disabled = true;
loadMoreBtn.classList.add('opacity-50', 'cursor-not-allowed');
}, 1500);
});
}
// Parallax effect for hero images
window.addEventListener('scroll', () => {
const scrolled = window.pageYOffset;
const parallaxElements = document.querySelectorAll('.parallax');
parallaxElements.forEach(element => {
const speed = element.dataset.speed || 0.5;
element.style.transform = `translateY(${scrolled * speed}px)`;
});
});
// Initialize on page load
document.addEventListener('DOMContentLoaded', () => {
feather.replace();
// Add loading animation
document.body.classList.add('animate-fade-in');
// Initialize tooltips or other interactive elements
console.log('Khmer23 Luxury Real Estate Platform Initialized');
});
// Performance optimization - lazy loading images
if ('IntersectionObserver' in window) {
const imageObserver = new IntersectionObserver((entries, observer) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const img = entry.target;
img.src = img.dataset.src;
img.classList.remove('lazy');
imageObserver.unobserve(img);
}
});
});
document.querySelectorAll('img[data-src]').forEach(img => {
imageObserver.observe(img);
});
}