// PalletPal Pro - Main JavaScript // Product data const products = [ { id: 1, name: "Standard 48x40\" New", category: "new", price: 12.99, image: "http://static.photos/industry/640x480/1", description: "Industry standard GMA pallet, heat-treated hardwood construction.", specs: ["48\" x 40\" x 6\"", "2,500 lbs capacity", "ISPM-15 certified"] }, { id: 2, name: "Heavy Duty Block Pallet", category: "new", price: 24.99, image: "http://static.photos/industry/640x480/2", description: "Four-way entry block pallet for heavy loads and rack storage.", specs: ["48\" x 40\" x 6.5\"", "5,000 lbs capacity", "4-way entry"] }, { id: 3, name: "Premium Used Grade A", category: "used", price: 6.99, image: "http://static.photos/industry/640x480/3", description: "Top-quality refurbished pallets, repaired to like-new condition.", specs: ["48\" x 40\" x 6\"", "2,200 lbs capacity", "Heat treated"] }, { id: 4, name: "Export/Heat Treated", category: "export", price: 15.99, image: "http://static.photos/industry/640x480/4", description: "ISPM-15 compliant pallets for international shipping.", specs: ["48\" x 40\" x 6\"", "IPPC marked", "Global compliant"] }, { id: 5, name: "Custom Size Pallet", category: "custom", price: 35.00, image: "http://static.photos/craft/640x480/5", description: "Built to your exact specifications and requirements.", specs: ["Any size up to 96\"", "Custom capacity", "Your choice of wood"] }, { id: 6, name: "Lightweight Economy", category: "new", price: 8.99, image: "http://static.photos/industry/640x480/6", description: "Cost-effective solution for light to medium loads.", specs: ["48\" x 40\" x 5.5\"", "1,500 lbs capacity", "Softwood construction"] } ]; // Testimonials data const testimonials = [ { id: 1, name: "Robert Martinez", company: "FastTrack Logistics", role: "Operations Director", image: "http://static.photos/people/200x200/101", content: "PalletPal Pro has been our go-to supplier for 5 years. Their quality is consistent, delivery is always on time, and their team genuinely cares about our success.", rating: 5 }, { id: 2, name: "Jennifer Walsh", company: "Midwest Manufacturing", role: "Supply Chain Manager", image: "http://static.photos/people/200x200/102", content: "The B2B program saved us 30% on pallet costs while eliminating stockouts. Their just-in-time delivery model transformed our warehouse operations.", rating: 5 }, { id: 3, name: "David Kim", company: "GreenGrocer Distributors", role: "CEO", image: "http://static.photos/people/200x200/103", content: "As a company focused on sustainability, we love that PalletPal Pro shares our values. Their recycled pallet program aligns perfectly with our mission.", rating: 5 } ]; // Pricing configuration const pricing = { standard: { base: 12.99, multiplier: 1 }, heavy: { base: 24.99, multiplier: 1 }, custom: { base: 35.00, multiplier: 1.2 }, used: { base: 6.99, multiplier: 1 }, export: { base: 15.99, multiplier: 1 } }; const locationMultipliers = { local: 1, regional: 1.15, national: 1.35 }; // DOM Ready document.addEventListener('DOMContentLoaded', function() { // Initialize Feather icons if (typeof feather !== 'undefined') { feather.replace(); } // Load products on index page loadFeaturedProducts(); // Load all products on products page loadAllProducts(); // Load testimonials loadTestimonials(); // Setup quote calculator setupQuoteCalculator(); // Setup product filters setupProductFilters(); // Setup forms setupForms(); // Setup scroll animations setupScrollAnimations(); }); // Load featured products (homepage) function loadFeaturedProducts() { const grid = document.getElementById('product-grid'); if (!grid) return; const featuredProducts = products.slice(0, 3); grid.innerHTML = featuredProducts.map(product => createProductCard(product)).join(''); if (typeof feather !== 'undefined') { feather.replace(); } } // Load all products (products page) function loadAllProducts() { const grid = document.getElementById('all-products-grid'); if (!grid) return; grid.innerHTML = products.map(product => createProductCard(product)).join(''); if (typeof feather !== 'undefined') { feather.replace(); } } // Create product card HTML function createProductCard(product) { return `
${product.name}
${product.category}

${product.name}

${product.price.toFixed(2)}

${product.description}

Request Quote
`; } // Load testimonials function loadTestimonials() { const grid = document.getElementById('testimonials-grid'); if (!grid) return; grid.innerHTML = testimonials.map(t => `
${Array(t.rating).fill('').join('')}

"${t.content}"

${t.name}
${t.name}
${t.role}, ${t.company}
`).join(''); if (typeof feather !== 'undefined') { feather.replace(); } } // Setup quote calculator function setupQuoteCalculator() { const form = document.getElementById('quote-form'); const result = document.getElementById('quote-result'); const priceEl = document.getElementById('quote-price'); if (!form) return; form.addEventListener('submit', function(e) { e.preventDefault(); const type = document.getElementById('pallet-type').value; const quantity = parseInt(document.getElementById('quantity').value) || 1; const location = document.getElementById('location').value; const basePrice = pricing[type].base; const locationMult = locationMultipliers[location]; const volumeDiscount = quantity >= 500 ? 0.85 : quantity >= 100 ? 0.9 : 1; const total = basePrice * quantity * locationMult * volumeDiscount; priceEl.textContent = ' + total.toLocaleString('en-US', { minimumFractionDigits: 2, maximumFractionDigits: 2 }); result.classList.remove('hidden'); // Animate the price animateValue(priceEl, 0, total, 500); }); } // Animate number value function animateValue(element, start, end, duration) { const range = end - start; const increment = end > start ? 1 : -1; const stepTime = Math.abs(Math.floor(duration / (range / 100))); let current = start; const timer = setInterval(() => { current += range / 20; if ((increment > 0 && current >= end) || (increment < 0 && current <= end)) { current = end; clearInterval(timer); } element.textContent = ' + current.toLocaleString('en-US', { minimumFractionDigits: 2, maximumFractionDigits: 2 }); }, stepTime); } // Submit quote request function submitQuote() { const type = document.getElementById('pallet-type').value; const quantity = document.getElementById('quantity').value; // Store in sessionStorage for contact form sessionStorage.setItem('quoteType', type); sessionStorage.setItem('quoteQuantity', quantity); window.location.href = 'contact.html?subject=quote'; } // Setup product filters function setupProductFilters() { const buttons = document.querySelectorAll('.filter-btn'); const cards = document.querySelectorAll('[data-category]'); if (!buttons.length) return; buttons.forEach(btn => { btn.addEventListener('click', () => { // Update active state buttons.forEach(b => { b.classList.remove('active', 'bg-primary-600', 'text-white'); b.classList.add('bg-white', 'dark:bg-wood-800'); }); btn.classList.add('active', 'bg-primary-600', 'text-white'); btn.classList.remove('bg-white', 'dark:bg-wood-800'); // Filter cards const filter = btn.dataset.filter; cards.forEach(card => { if (filter === 'all' || card.dataset.category === filter) { card.style.display = 'block'; card.classList.add('animate-scale-in'); } else { card.style.display = 'none'; } }); }); }); } // Setup forms function setupForms() { // Contact form const contactForm = document.getElementById('contact-form'); if (contactForm) { // Pre-fill if coming from quote const urlParams = new URLSearchParams(window.location.search); const subject = urlParams.get('subject'); if (subject === 'quote') { const subjectSelect = contactForm.querySelector('select'); if (subjectSelect) subjectSelect.value = 'Request Quote'; } contactForm.addEventListener('submit', function(e) { e.preventDefault(); showToast('Message sent successfully! We\'ll get back to you within 2 hours.'); this.reset(); }); } // B2B form const b2bForm = document.getElementById('b2b-form'); if (b2bForm) { b2bForm.addEventListener('submit', function(e) { e.preventDefault(); showToast('Consultation request submitted! Our B2B team will contact you shortly.'); this.reset(); }); } } // Show toast notification function showToast(message) { // Remove existing toast const existing = document.querySelector('.toast'); if (existing) existing.remove(); const toast = document.createElement('div'); toast.className = 'toast'; toast.innerHTML = `
${message}
`; document.body.appendChild(toast); if (typeof feather !== 'undefined') { feather.replace(); } setTimeout(() => toast.classList.add('show'), 10); setTimeout(() => { toast.classList.remove('show'); setTimeout(() => toast.remove(), 300); }, 4000); } // Setup scroll animations function setupScrollAnimations() { 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-slide-up'); observer.unobserve(entry.target); } }); }, observerOptions); // Observe sections for animation document.querySelectorAll('section > div').forEach(el => { el.style.opacity = '0'; el.style.transform = 'translateY(30px)'; observer.observe(el); }); } // Add CSS animation classes dynamically const style = document.createElement('style'); style.textContent = ` .animate-slide-up { animation: slideUp 0.6s ease-out forwards; } @keyframes slideUp { from { opacity: 0; transform: translateY(30px); } to { opacity: 1; transform: translateY(0); } } `; document.head.appendChild(style);