/**
* 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 = `
<img src="${car.imageUrl}" alt="${car.brand} ${car.model}" loading="lazy" width="400" height="250">
<div class="car-card-content">
<h3>${car.brand} ${car.model}</h3>
<p><i class="fas fa-car"></i> ${car.type} | <i class="fas fa-users"></i> ${car.seats} ที่นั่ง</p>
<p class="price">฿${car.pricePerDay.toLocaleString()} / วัน</p>
<button class="btn btn-primary" data-car-id="${car.id}">ดูรายละเอียด</button>
</div>
`;
return card;
},
/**
* Renders a list of car cards into the car list container.
* @param {Array<object>} 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 = `
<div class="no-results">
<i class="fas fa-exclamation-circle"></i>
<p>ไม่พบรถยนต์ที่ตรงกับเงื่อนไขการค้นหาของคุณ</p>
<p>ลองเปลี่ยนเงื่อนไขหรือดูรถทั้งหมดของเรา</p>
</div>
`;
}
},
/**
* 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 = `<div class="alert alert-${type}">${message}</div>`;
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;