/** * js/ui.js * Handles all UI rendering and DOM manipulations. */ import {formatDate} from './utils.js'; // Import utility for date formatting const ui = { // DOM Elements carListContainer: document.getElementById('car-list'), notificationContainer: document.getElementById('notification'), loadingSpinner: document.getElementById('loading-spinner'), mobileMenuButton: document.getElementById('mobile-menu-btn'), navMenu: document.getElementById('nav-menu'), heroSection: document.getElementById('home'), // For scroll to carsSection: document.getElementById('cars'), // For scroll to howItWorksSection: document.getElementById('how-it-works'), // For scroll to contactSection: document.getElementById('contact'), // For scroll to /** * Creates and returns a DOM element for a single car card. * @param {object} car - Car data object. * @returns {HTMLElement} The car card element. */ renderCarCard(car) { const card = document.createElement('div'); card.className = 'car-card'; card.innerHTML = ` ${car.brand} ${car.model}

${car.brand} ${car.model}

${car.type} | ${car.seats} ที่นั่ง

฿${car.pricePerDay.toLocaleString()} / วัน

`; return card; }, /** * Renders a list of car cards into the car list container. * @param {Array} cars - An array of car data objects. */ renderCarList(cars) { if (!this.carListContainer) { console.warn("Car list container not found."); return; } this.carListContainer.innerHTML = ''; // Clear previous list if (cars && cars.length > 0) { cars.forEach(car => { this.carListContainer.appendChild(this.renderCarCard(car)); }); } else { this.carListContainer.innerHTML = `

ไม่พบรถยนต์ที่ตรงกับเงื่อนไขการค้นหาของคุณ

ลองเปลี่ยนเงื่อนไขหรือดูรถทั้งหมดของเรา

`; } }, /** * Displays a notification message to the user. * @param {string} message - The message to display. * @param {'info'|'success'|'error'|'warning'} type - Type of notification. */ showNotification(message, type = 'info') { if (!this.notificationContainer) { console.warn("Notification container not found."); return; } this.notificationContainer.innerHTML = `
${message}
`; this.notificationContainer.style.display = 'block'; // Automatically hide after a few seconds (CSS handles fade out) setTimeout(() => { this.notificationContainer.style.display = 'none'; this.notificationContainer.innerHTML = ''; // Clear content }, 3000); // Should match CSS animation duration }, /** * Shows or hides the global loading spinner. * @param {boolean} isLoading - True to show, false to hide. */ showLoading(isLoading) { if (this.loadingSpinner) { this.loadingSpinner.style.display = isLoading ? 'flex' : 'none'; } }, /** * Toggles the mobile navigation menu's active state. */ toggleMobileMenu() { if (this.navMenu && this.mobileMenuButton) { const expanded = this.navMenu.classList.toggle('active'); this.mobileMenuButton.classList.toggle('active'); // For rotating icon } }, /** * Closes the mobile navigation menu if it's open. */ closeMobileMenu() { if (this.navMenu && this.mobileMenuButton && this.navMenu.classList.contains('active')) { this.navMenu.classList.remove('active'); this.mobileMenuButton.classList.remove('active'); } }, /** * Updates the active state of navigation links based on the current hash. * @param {string} currentHash - The current URL hash (e.g., "#cars"). */ updateActiveNavLink(currentHash) { document.querySelectorAll('.nav-link').forEach(link => { link.classList.remove('active'); if (link.getAttribute('href') === currentHash) { link.classList.add('active'); } }); } // You might add more specific UI rendering functions here for: // - renderCarDetails(car) to show a popup or dedicated section for a single car // - renderBookingForm(car) // - renderUserDashboard() }; export default ui;