Spaces:
Running
Running
| // Global configuration and utilities | |
| const CONFIG = { | |
| apiBaseUrl: 'https://fakestoreapi.com', | |
| phoneNumber: '+33139912304', | |
| whatsappNumber: '+33139912304', | |
| companyName: 'FRANCE ÉLECTRICITÉ & PEINTURE DISTRIBUTION', | |
| address: 'Sarcelles, 95200, France' | |
| }; | |
| // Initialize the application | |
| document.addEventListener('DOMContentLoaded', function() { | |
| console.log('DOM Content Loaded - Initializing App'); | |
| initializeApp(); | |
| setupEventListeners(); | |
| loadInitialData(); | |
| // Force re-render of feather icons | |
| setTimeout(() => { | |
| if (window.feather) { | |
| feather.replace(); | |
| } | |
| }, 100); | |
| }); | |
| function initializeApp() { | |
| // Set up service worker for PWA functionality | |
| if ('serviceWorker' in navigator) { | |
| navigator.serviceWorker.register('/sw.js') | |
| .then(registration => { | |
| console.log('SW registered: ', registration); | |
| }) | |
| .catch(registrationError => { | |
| console.log('SW registration failed: ', registrationError); | |
| }); | |
| } | |
| // Initialize animations | |
| initAnimations(); | |
| } | |
| function setupEventListeners() { | |
| // Search functionality | |
| const searchInput = document.querySelector('#search-input'); | |
| if (searchInput) { | |
| searchInput.addEventListener('input', debounce(handleSearch, 300)); | |
| } | |
| // Phone click handlers | |
| const phoneLinks = document.querySelectorAll('[data-phone]'); | |
| phoneLinks.forEach(link => { | |
| link.addEventListener('click', function(e) { | |
| e.preventDefault(); | |
| window.open(`tel:${CONFIG.phoneNumber}`, '_self'); | |
| }); | |
| } | |
| // WhatsApp click handlers | |
| const whatsappLinks = document.querySelectorAll('[data-whatsapp]'); | |
| whatsappLinks.forEach(link => { | |
| link.addEventListener('click', function(e) { | |
| e.preventDefault(); | |
| window.open(`https://wa.me/${CONFIG.whatsappNumber}`, '_blank'); | |
| }); | |
| } | |
| // Mobile menu toggle | |
| const menuToggle = document.querySelector('#menu-toggle'); | |
| const mobileMenu = document.querySelector('#mobile-menu'); | |
| if (menuToggle && mobileMenu) { | |
| menuToggle.addEventListener('click', function() { | |
| mobileMenu.classList.toggle('hidden'); | |
| menuToggle.querySelector('i').setAttribute('data-feather', | |
| mobileMenu.classList.contains('hidden') ? 'menu' : 'x' | |
| ); | |
| feather.replace(); | |
| }); | |
| } | |
| } | |
| function loadInitialData() { | |
| // Load featured products for homepage | |
| fetchFeaturedProducts(); | |
| // Load categories for navigation | |
| fetchCategories(); | |
| } | |
| function fetchFeaturedProducts() { | |
| // Mock API call for featured products | |
| fetch(`${CONFIG.apiBaseUrl}/products?limit=8`) | |
| .then(response => response.json()) | |
| .then(products => { | |
| displayFeaturedProducts(products); | |
| }) | |
| .catch(error => { | |
| console.error('Error fetching featured products:', error); | |
| }); | |
| } | |
| function fetchCategories() { | |
| // Mock API call for categories | |
| const categories = [ | |
| { name: 'Électricité', slug: 'electricite', icon: 'zap' }, | |
| { name: 'Peinture', slug: 'peinture', icon: 'droplet' }, | |
| { name: 'Outillage', slug: 'outillage', icon: 'tool' }, | |
| { name: 'Préparation', slug: 'preparation', icon: 'settings' }, | |
| { name: 'Promotions', slug: 'promotions', icon: 'tag' } | |
| ]; | |
| updateNavigationCategories(categories); | |
| } | |
| function handleSearch(event) { | |
| const query = event.target.value.trim(); | |
| if (query.length > 2) { | |
| performSearch(query); | |
| } | |
| } | |
| function performSearch(query) { | |
| fetch(`${CONFIG.apiBaseUrl}/products`) | |
| .then(response => response.json()) | |
| .then(products => { | |
| const filteredProducts = products.filter(product => | |
| product.title.toLowerCase().includes(query.toLowerCase()) | |
| ); | |
| displaySearchResults(filteredProducts); | |
| }) | |
| .catch(error => { | |
| console.error('Search error:', error); | |
| }); | |
| } | |
| function displayFeaturedProducts(products) { | |
| const container = document.querySelector('#featured-products'); | |
| if (!container) return; | |
| container.innerHTML = products.map(product => ` | |
| <div class="bg-white rounded-xl shadow-lg hover:shadow-xl transition-all duration-300 card-hover"> | |
| <img src="${product.image}" alt="${product.title}" class="w-full h-48 object-cover rounded-t-xl"> | |
| <div class="p-4"> | |
| <h3 class="font-semibold text-lg mb-2 text-gray-800">${product.title}</h3> | |
| <p class="text-gray-600 text-sm mb-4">${product.description.substring(0, 80)}...</p> | |
| <div class="flex justify-between items-center"> | |
| <span class="text-primary font-bold text-lg">${product.price}€</span> | |
| <button class="bg-secondary hover:bg-secondary/90 text-white px-4 py-2 rounded-lg transition-all duration-300"> | |
| Demander un devis | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| `).join(''); | |
| } | |
| function displaySearchResults(products) { | |
| const resultsContainer = document.querySelector('#search-results'); | |
| if (!resultsContainer) return; | |
| resultsContainer.innerHTML = products.map(product => ` | |
| <div class="bg-white rounded-lg shadow-md p-4 mb-4"> | |
| <h4 class="font-semibold">${product.title}</h4> | |
| <p class="text-gray-600">${product.description.substring(0, 120)}...</p> | |
| </div> | |
| `).join(''); | |
| } | |
| function updateNavigationCategories(categories) { | |
| const navContainer = document.querySelector('#main-navigation'); | |
| if (!navContainer) return; | |
| navContainer.innerHTML = categories.map(category => ` | |
| <a href="/catalogue.html?category=${category.slug}" class="text-gray-700 hover:text-primary transition-colors duration-300"> | |
| <i data-feather="${category.icon}"></i> | |
| ${category.name} | |
| </a> | |
| `).join(''); | |
| } | |
| function initAnimations() { | |
| // Initialize intersection observer for scroll 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('fade-in-up'); | |
| } | |
| }); | |
| }, observerOptions); | |
| // Observe elements for animation | |
| document.querySelectorAll('.animate-on-scroll').forEach(element => { | |
| observer.observe(element); | |
| }); | |
| } | |
| // Utility functions | |
| function debounce(func, wait) { | |
| let timeout; | |
| return function executedFunction(...args) { | |
| const later = () => { | |
| clearTimeout(timeout); | |
| func(...args); | |
| }; | |
| clearTimeout(timeout); | |
| timeout = setTimeout(later, wait); | |
| }; | |
| } | |
| // Export for use in components if needed | |
| window.APP_CONFIG = CONFIG; |