New Initial Commit
This commit is contained in:
@@ -0,0 +1,223 @@
|
||||
// ===== MOBILE MENU TOGGLE =====
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
const hamburger = document.querySelector('.hamburger');
|
||||
const nav = document.querySelector('nav');
|
||||
|
||||
if (hamburger) {
|
||||
hamburger.addEventListener('click', function () {
|
||||
nav.classList.toggle('active');
|
||||
});
|
||||
|
||||
// Close menu when a link is clicked
|
||||
document.querySelectorAll('nav a').forEach(link => {
|
||||
link.addEventListener('click', function () {
|
||||
nav.classList.remove('active');
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// ===== SMOOTH SCROLL 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'
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// ===== LAZY LOAD IMAGES =====
|
||||
if ('IntersectionObserver' in window) {
|
||||
const imageObserver = new IntersectionObserver((entries, observer) => {
|
||||
entries.forEach(entry => {
|
||||
if (entry.isIntersecting) {
|
||||
const img = entry.target;
|
||||
img.src = img.dataset.src;
|
||||
img.classList.add('loaded');
|
||||
observer.unobserve(img);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
document.querySelectorAll('img[data-src]').forEach(img => imageObserver.observe(img));
|
||||
}
|
||||
|
||||
// ===== SCROLL ANIMATIONS =====
|
||||
function observeElements() {
|
||||
const observer = new IntersectionObserver((entries) => {
|
||||
entries.forEach(entry => {
|
||||
if (entry.isIntersecting) {
|
||||
entry.target.style.opacity = '1';
|
||||
entry.target.style.transform = 'translateY(0)';
|
||||
}
|
||||
});
|
||||
}, {
|
||||
threshold: 0.1
|
||||
});
|
||||
|
||||
document.querySelectorAll('.card, .section').forEach(el => {
|
||||
el.style.opacity = '0';
|
||||
el.style.transform = 'translateY(20px)';
|
||||
el.style.transition = 'opacity 0.6s ease, transform 0.6s ease';
|
||||
observer.observe(el);
|
||||
});
|
||||
}
|
||||
|
||||
observeElements();
|
||||
|
||||
// ===== CART FUNCTIONALITY (SESSION-BASED) =====
|
||||
class Cart {
|
||||
constructor() {
|
||||
this.items = JSON.parse(localStorage.getItem('cart')) || [];
|
||||
this.updateCartCount();
|
||||
}
|
||||
|
||||
addItem(productId, productName, price, quantity = 1) {
|
||||
const existingItem = this.items.find(item => item.productId === productId);
|
||||
|
||||
if (existingItem) {
|
||||
existingItem.quantity += quantity;
|
||||
} else {
|
||||
this.items.push({
|
||||
productId,
|
||||
productName,
|
||||
price,
|
||||
quantity
|
||||
});
|
||||
}
|
||||
|
||||
this.save();
|
||||
this.updateCartCount();
|
||||
this.showNotification(`${productName} added to cart`);
|
||||
}
|
||||
|
||||
removeItem(productId) {
|
||||
this.items = this.items.filter(item => item.productId !== productId);
|
||||
this.save();
|
||||
this.updateCartCount();
|
||||
}
|
||||
|
||||
updateQuantity(productId, quantity) {
|
||||
const item = this.items.find(item => item.productId === productId);
|
||||
if (item) {
|
||||
item.quantity = Math.max(1, quantity);
|
||||
this.save();
|
||||
this.updateCartCount();
|
||||
}
|
||||
}
|
||||
|
||||
clear() {
|
||||
this.items = [];
|
||||
this.save();
|
||||
this.updateCartCount();
|
||||
}
|
||||
|
||||
getTotal() {
|
||||
return this.items.reduce((total, item) => total + (item.price * item.quantity), 0);
|
||||
}
|
||||
|
||||
save() {
|
||||
localStorage.setItem('cart', JSON.stringify(this.items));
|
||||
}
|
||||
|
||||
updateCartCount() {
|
||||
const count = this.items.reduce((sum, item) => sum + item.quantity, 0);
|
||||
const badge = document.querySelector('.cart-count');
|
||||
if (badge) {
|
||||
badge.textContent = count;
|
||||
badge.style.display = count > 0 ? 'block' : 'none';
|
||||
}
|
||||
}
|
||||
|
||||
showNotification(message) {
|
||||
const notification = document.createElement('div');
|
||||
notification.textContent = message;
|
||||
notification.style.cssText = `
|
||||
position: fixed;
|
||||
bottom: 20px;
|
||||
right: 20px;
|
||||
background-color: var(--accent-dark);
|
||||
color: white;
|
||||
padding: 12px 20px;
|
||||
border-radius: 4px;
|
||||
font-size: 14px;
|
||||
z-index: 1000;
|
||||
animation: slideIn 0.3s ease;
|
||||
`;
|
||||
|
||||
document.body.appendChild(notification);
|
||||
|
||||
setTimeout(() => {
|
||||
notification.style.animation = 'slideOut 0.3s ease';
|
||||
setTimeout(() => notification.remove(), 300);
|
||||
}, 2000);
|
||||
}
|
||||
}
|
||||
|
||||
const cart = new Cart();
|
||||
|
||||
// Add CSS animations
|
||||
const style = document.createElement('style');
|
||||
style.textContent = `
|
||||
@keyframes slideIn {
|
||||
from {
|
||||
transform: translateX(100%);
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
transform: translateX(0);
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes slideOut {
|
||||
from {
|
||||
transform: translateX(0);
|
||||
opacity: 1;
|
||||
}
|
||||
to {
|
||||
transform: translateX(100%);
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
`;
|
||||
document.head.appendChild(style);
|
||||
|
||||
// ===== FORM HANDLING =====
|
||||
document.querySelectorAll('form').forEach(form => {
|
||||
// Skip cart-related forms (add to cart, update quantity, remove, etc)
|
||||
if (form.action.includes('/cart/') || form.action.includes('/orders/')) {
|
||||
return;
|
||||
}
|
||||
|
||||
form.addEventListener('submit', function(e) {
|
||||
e.preventDefault();
|
||||
|
||||
const formData = new FormData(this);
|
||||
const data = Object.fromEntries(formData);
|
||||
|
||||
// Here you would typically send to backend
|
||||
console.log('Form submitted:', data);
|
||||
|
||||
// Show success message
|
||||
const message = document.createElement('div');
|
||||
message.textContent = 'Thank you! We\'ll be in touch soon.';
|
||||
message.style.cssText = `
|
||||
padding: 12px 20px;
|
||||
background-color: #4caf50;
|
||||
color: white;
|
||||
border-radius: 4px;
|
||||
margin-top: 10px;
|
||||
`;
|
||||
|
||||
this.appendChild(message);
|
||||
this.reset();
|
||||
|
||||
setTimeout(() => message.remove(), 3000);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user