JFIF  x x C         C     "        } !1AQa "q2 #B R $3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz        w !1AQ aq"2 B #3R br $4 % &'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz   ?  N m? j EP // Mobile Navigation Toggle const hamburger = document.getElementById('hamburger'); const navMenu = document.getElementById('nav-menu'); if (hamburger && navMenu) { hamburger.addEventListener('click', () => { navMenu.classList.toggle('active'); hamburger.classList.toggle('active'); }); // Close menu when clicking on a link document.querySelectorAll('.nav-link').forEach(link => { link.addEventListener('click', () => { navMenu.classList.remove('active'); hamburger.classList.remove('active'); }); }); } // Smooth scrolling 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' }); } }); }); // Navbar scroll effect window.addEventListener('scroll', () => { const navbar = document.querySelector('.navbar'); if (window.scrollY > 100) { navbar.style.background = 'rgba(255, 255, 255, 0.98)'; navbar.style.boxShadow = '0 2px 30px rgba(0, 0, 0, 0.15)'; } else { navbar.style.background = 'rgba(255, 255, 255, 0.95)'; navbar.style.boxShadow = '0 2px 20px rgba(0, 0, 0, 0.1)'; } }); // Intersection Observer for animations const observerOptions = { threshold: 0.1, rootMargin: '0px 0px -50px 0px' }; const observer = new IntersectionObserver((entries) => { entries.forEach(entry => { if (entry.isIntersecting) { entry.target.style.opacity = '1'; entry.target.style.transform = 'translateY(0)'; } }); }, observerOptions); // Observe elements for animation document.addEventListener('DOMContentLoaded', () => { const animatedElements = document.querySelectorAll('.property-card, .agent-card, .feature-card, .value-card, .team-member, .faq-item'); animatedElements.forEach(el => { el.style.opacity = '0'; el.style.transform = 'translateY(30px)'; el.style.transition = 'opacity 0.6s ease, transform 0.6s ease'; observer.observe(el); }); }); // Image Carousel for Apartment Details let currentSlide = 0; const slides = document.querySelectorAll('.carousel-slide'); const indicators = document.querySelectorAll('.indicator'); const prevBtn = document.getElementById('prevBtn'); const nextBtn = document.getElementById('nextBtn'); function showSlide(index) { // Hide all slides slides.forEach(slide => slide.classList.remove('active')); indicators.forEach(indicator => indicator.classList.remove('active')); // Show current slide if (slides[index]) { slides[index].classList.add('active'); indicators[index].classList.add('active'); } } function nextSlide() { currentSlide = (currentSlide + 1) % slides.length; showSlide(currentSlide); } function prevSlide() { currentSlide = (currentSlide - 1 + slides.length) % slides.length; showSlide(currentSlide); } function currentSlideFunc(index) { currentSlide = index - 1; showSlide(currentSlide); } // Event listeners for carousel if (nextBtn) nextBtn.addEventListener('click', nextSlide); if (prevBtn) prevBtn.addEventListener('click', prevSlide); // Auto-play carousel if (slides.length > 0) { setInterval(nextSlide, 5000); } /* Form validation and submission const forms = document.querySelectorAll('form'); forms.forEach(form => { form.addEventListener('submit', (e) => { e.preventDefault(); // Basic form validation const inputs = form.querySelectorAll('input[required], select[required], textarea[required]'); let isValid = true; inputs.forEach(input => { if (!input.value.trim()) { isValid = false; input.style.borderColor = '#e74c3c'; input.style.boxShadow = '0 0 0 3px rgba(231, 76, 60, 0.1)'; } else { input.style.borderColor = '#095859'; input.style.boxShadow = '0 0 0 3px rgba(9, 88, 89, 0.1)'; } }); if (isValid) { // Show success message const submitBtn = form.querySelector('button[type="submit"], .submit-btn, .auth-btn'); const originalText = submitBtn.textContent; submitBtn.textContent = 'Success!'; submitBtn.style.background = '#27ae60'; setTimeout(() => { submitBtn.textContent = originalText; submitBtn.style.background = '#095859'; form.reset(); }, 2000); } }); });*/ // Property favorite toggle document.querySelectorAll('.property-favorite').forEach(btn => { btn.addEventListener('click', (e) => { e.preventDefault(); const heart = btn.textContent; btn.textContent = heart === '♡' ? '♥' : '♡'; btn.style.color = heart === '♡' ? '#e74c3c' : '#666'; }); }); /*Filter functionality for explore page const filterBtn = document.querySelector('.filter-btn'); const filterInputs = document.querySelectorAll('.filter-input, .filter-select'); if (filterBtn) { filterBtn.addEventListener('click', () => { // Simulate filtering const propertyCards = document.querySelectorAll('.property-card'); // Add loading state filterBtn.textContent = 'Filtering...'; filterBtn.disabled = true; setTimeout(() => { // Reset button filterBtn.textContent = 'Apply Filters'; filterBtn.disabled = false; // Animate property cards propertyCards.forEach((card, index) => { card.style.opacity = '0'; card.style.transform = 'translateY(20px)'; setTimeout(() => { card.style.opacity = '1'; card.style.transform = 'translateY(0)'; }, index * 100); }); }, 1000); }); }*/ /* Search functionality const searchInputs = document.querySelectorAll('.search-input'); const searchBtns = document.querySelectorAll('.search-btn'); searchBtns.forEach(btn => { btn.addEventListener('click', () => { // Simulate search btn.textContent = 'Searching...'; btn.disabled = true; setTimeout(() => { btn.textContent = 'Search'; btn.disabled = false; // Redirect to explore page (in a real app) if (window.location.pathname.includes('index.html') || window.location.pathname === '/') { window.location.href = 'explore.html'; } }, 1000); }); });*/ // Pagination functionality document.querySelectorAll('.page-btn').forEach(btn => { btn.addEventListener('click', () => { // Remove active class from all buttons document.querySelectorAll('.page-btn').forEach(b => b.classList.remove('active')); // Add active class to clicked button (if it's a number) if (!isNaN(btn.textContent)) { btn.classList.add('active'); } // Scroll to top of results const resultsSection = document.querySelector('.properties-listing'); if (resultsSection) { resultsSection.scrollIntoView({ behavior: 'smooth' }); } }); }); // Contact form enhancements const contactForm = document.querySelector('.contact-form'); if (contactForm) { const subjectSelect = contactForm.querySelector('#subject'); const messageTextarea = contactForm.querySelector('#message'); if (subjectSelect && messageTextarea) { subjectSelect.addEventListener('change', () => { const placeholders = { 'general': 'Tell us how we can help you...', 'viewing': 'Which property would you like to view and when?', 'application': 'Please provide your application reference number...', 'maintenance': 'Please describe the maintenance issue...', 'other': 'Please provide details about your inquiry...' }; messageTextarea.placeholder = placeholders[subjectSelect.value] || placeholders['general']; }); } } // Social auth buttons document.querySelectorAll('.social-btn').forEach(btn => { btn.addEventListener('click', (e) => { e.preventDefault(); const originalText = btn.innerHTML; btn.innerHTML = ' Connecting...'; btn.disabled = true; setTimeout(() => { btn.innerHTML = originalText; btn.disabled = false; // Show success message alert('Social authentication would be implemented here!'); }, 2000); }); }); // Property action buttons document.querySelectorAll('.action-btn').forEach(btn => { btn.addEventListener('click', () => { const action = btn.textContent.trim(); if (action.includes('Save')) { btn.textContent = btn.textContent.includes('♡') ? '♥ Saved' : '♡ Save'; btn.style.color = btn.textContent.includes('♥') ? '#e74c3c' : '#333'; } else if (action.includes('Share')) { // Simulate share functionality if (navigator.share) { navigator.share({ title: document.title, url: window.location.href }); } else { // Fallback: copy to clipboard navigator.clipboard.writeText(window.location.href).then(() => { const originalText = btn.textContent; btn.textContent = '✓ Copied!'; setTimeout(() => { btn.textContent = originalText; }, 2000); }); } } }); }); // Contact buttons in apartment details document.querySelectorAll('.contact-btn').forEach(btn => { btn.addEventListener('click', () => { const action = btn.textContent.trim(); const originalText = btn.textContent; btn.textContent = 'Processing...'; btn.disabled = true; setTimeout(() => { btn.textContent = originalText; btn.disabled = false; if (action === 'Schedule Tour') { alert('Tour scheduling would open a calendar widget here!'); } else if (action === 'Send Message') { alert('Message composer would open here!'); } else if (action === 'Apply Now') { alert('Application form would open here!'); } }, 1500); }); }); // Add loading states to navigation document.querySelectorAll('.nav-link').forEach(link => { link.addEventListener('click', (e) => { if (link.getAttribute('href').endsWith('.html')) { const originalText = link.textContent; link.textContent = 'Loading...'; // Reset after a short delay (in case navigation is cancelled) setTimeout(() => { link.textContent = originalText; }, 3000); } }); }); // Initialize tooltips and enhanced interactions document.addEventListener('DOMContentLoaded', () => { // Add hover effects to cards const cards = document.querySelectorAll('.property-card, .agent-card, .feature-card, .value-card'); cards.forEach(card => { card.addEventListener('mouseenter', () => { card.style.transform = 'translateY(-10px)'; }); card.addEventListener('mouseleave', () => { card.style.transform = 'translateY(0)'; }); }); // Add focus states for better accessibility const focusableElements = document.querySelectorAll('button, input, select, textarea, a'); focusableElements.forEach(element => { element.addEventListener('focus', () => { element.style.outline = '2px solid #095859'; element.style.outlineOffset = '2px'; }); element.addEventListener('blur', () => { element.style.outline = 'none'; }); }); }); // Performance optimization: Lazy loading for images if ('IntersectionObserver' in window) { const imageObserver = new IntersectionObserver((entries) => { entries.forEach(entry => { if (entry.isIntersecting) { const img = entry.target; if (img.dataset.src) { img.src = img.dataset.src; img.removeAttribute('data-src'); imageObserver.unobserve(img); } } }); }); document.querySelectorAll('img[data-src]').forEach(img => { imageObserver.observe(img); }); } // Global error handling window.addEventListener('error', (e) => { console.error('An error occurred:', e.error); // In a production app, you might want to send this to an error tracking service }); // Service worker registration (for future PWA features) if ('serviceWorker' in navigator) { window.addEventListener('load', () => { // Service worker would be registered here for offline functionality console.log('Service worker support detected'); }); } // Message Popup Functionality document.addEventListener('DOMContentLoaded', () => { const floatingBtn = document.getElementById('floatingMessageBtn'); const popupOverlay = document.getElementById('messagePopupOverlay'); const closePopup = document.getElementById('closePopup'); const popupForm = document.getElementById('popupContactForm'); const sendMessageBtn = document.querySelector('.contact-btn.secondary'); // Function to open popup function openMessagePopup() { popupOverlay.classList.add('active'); document.body.style.overflow = 'hidden'; // Prevent background scrolling } // Function to close popup function closeMessagePopup() { popupOverlay.classList.remove('active'); document.body.style.overflow = 'auto'; // Restore scrolling } // Event listeners for opening popup if (floatingBtn) { floatingBtn.addEventListener('click', openMessagePopup); } // Also make the "Send Message" button in sidebar open the popup if (sendMessageBtn) { sendMessageBtn.addEventListener('click', (e) => { e.preventDefault(); openMessagePopup(); }); } // Event listeners for closing popup if (closePopup) { closePopup.addEventListener('click', closeMessagePopup); } // Close popup when clicking on overlay if (popupOverlay) { popupOverlay.addEventListener('click', (e) => { if (e.target === popupOverlay) { closeMessagePopup(); } }); } // Close popup with Escape key document.addEventListener('keydown', (e) => { if (e.key === 'Escape' && popupOverlay.classList.contains('active')) { closeMessagePopup(); } }); // Handle form submission if (popupForm) { popupForm.addEventListener('submit', (e) => { e.preventDefault(); // Get form data const formData = new FormData(popupForm); const submitBtn = popupForm.querySelector('.popup-submit-btn'); const originalText = submitBtn.textContent; // Show loading state submitBtn.textContent = 'Sending...'; submitBtn.disabled = true; // Simulate form submission setTimeout(() => { // Show success state submitBtn.textContent = 'Message Sent!'; submitBtn.style.background = '#27ae60'; // Reset form and close popup after delay setTimeout(() => { popupForm.reset(); closeMessagePopup(); submitBtn.textContent = originalText; submitBtn.style.background = ''; submitBtn.disabled = false; // Show success notification showNotification('Message sent successfully! Sarah will contact you soon.'); }, 1500); }, 1000); }); } // Notification function function showNotification(message) { // Create notification element const notification = document.createElement('div'); notification.className = 'success-notification'; notification.textContent = message; notification.style.cssText = ` position: fixed; top: 20px; right: 20px; background: #27ae60; color: white; padding: 15px 20px; border-radius: 8px; box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2); z-index: 3000; font-weight: 500; max-width: 300px; opacity: 0; transform: translateX(100%); transition: all 0.3s ease; `; document.body.appendChild(notification); // Animate in setTimeout(() => { notification.style.opacity = '1'; notification.style.transform = 'translateX(0)'; }, 100); // Remove after delay setTimeout(() => { notification.style.opacity = '0'; notification.style.transform = 'translateX(100%)'; setTimeout(() => { document.body.removeChild(notification); }, 300); }, 4000); } // Auto-hide floating button when scrolling to footer const footer = document.querySelector('.footer'); if (footer && floatingBtn) { const observer = new IntersectionObserver((entries) => { entries.forEach(entry => { if (entry.isIntersecting) { floatingBtn.style.opacity = '0.5'; floatingBtn.style.transform = 'translateY(10px)'; } else { floatingBtn.style.opacity = '1'; floatingBtn.style.transform = 'translateY(0)'; } }); }, { threshold: 0.1 }); observer.observe(footer); } });