PHƯƠNG TRÁNG GLOBAL
Móc Khóa Handmade
Móc Khóa Handmade
Móc Khóa Handmade
Móc Khóa Handmade
Móc Khóa Handmade
Móc Khóa Handmade
Móc Khóa Handmade
Móc Khóa Handmade
Móc Khóa Handmade
Móc Khóa Handmade
<a>" alt="Móc Khóa Handmade" class="w-full h-full object-cover object-top grayscale-[10%]"> </div> </div> <div class="swiper-pagination !-bottom-8"></div> </div> </div> <!-- Desktop: Grid Stack (hidden on mobile) --> <div class="hidden lg:grid grid-cols-2 gap-4"> <div class="col-span-2 bg-surface cursor-crosshair group relative overflow-hidden"> <img src="https://sgsouveni.com/assets/images/products/1778836385_6a06e3a1aebd1.jpg" alt="Móc Khóa Handmade" class="w-full h-full object-cover object-top filter grayscale-[5%] group-hover:grayscale-0 transition-all duration-700"> </div> <div class="col-span-1 bg-surface cursor-crosshair group relative overflow-hidden"> <img src="https://sgsouveni.com/assets/images/products/1778836385_6a06e3a1bd178.jpg" alt="Móc Khóa Handmade" class="w-full h-full object-cover object-top filter grayscale-[10%] group-hover:grayscale-0 transition-all duration-700"> </div> <div class="col-span-1 bg-surface cursor-crosshair group relative overflow-hidden"> <img src="https://sgsouveni.com/assets/images/products/1778836385_6a06e3a1df4cd.jpg" alt="Móc Khóa Handmade" class="w-full h-full object-cover object-top filter grayscale-[10%] group-hover:grayscale-0 transition-all duration-700"> </div> <div class="col-span-1 bg-surface cursor-crosshair group relative overflow-hidden"> <img src="https://sgsouveni.com/assets/images/products/1778836385_6a06e3a1e51b2.jpg" alt="Móc Khóa Handmade" class="w-full h-full object-cover object-top filter grayscale-[10%] group-hover:grayscale-0 transition-all duration-700"> </div> <div class="col-span-1 bg-surface cursor-crosshair group relative overflow-hidden"> <img src="https://sgsouveni.com/assets/images/products/1778836385_6a06e3a1e8d69.jpg" alt="Móc Khóa Handmade" class="w-full h-full object-cover object-top filter grayscale-[10%] group-hover:grayscale-0 transition-all duration-700"> </div> <div class="col-span-1 bg-surface cursor-crosshair group relative overflow-hidden"> <img src="https://sgsouveni.com/assets/images/products/1778836386_6a06e3a205d16.jpg" alt="Móc Khóa Handmade" class="w-full h-full object-cover object-top filter grayscale-[10%] group-hover:grayscale-0 transition-all duration-700"> </div> <div class="col-span-1 bg-surface cursor-crosshair group relative overflow-hidden"> <img src="https://sgsouveni.com/assets/images/products/1778836386_6a06e3a20caae.jpg" alt="Móc Khóa Handmade" class="w-full h-full object-cover object-top filter grayscale-[10%] group-hover:grayscale-0 transition-all duration-700"> </div> <div class="col-span-1 bg-surface cursor-crosshair group relative overflow-hidden"> <img src="https://sgsouveni.com/assets/images/products/1778836386_6a06e3a21671a.jpg" alt="Móc Khóa Handmade" class="w-full h-full object-cover object-top filter grayscale-[10%] group-hover:grayscale-0 transition-all duration-700"> </div> <div class="col-span-1 bg-surface cursor-crosshair group relative overflow-hidden"> <img src="https://sgsouveni.com/assets/images/products/1778836386_6a06e3a218b8d.jpg" alt="Móc Khóa Handmade" class="w-full h-full object-cover object-top filter grayscale-[10%] group-hover:grayscale-0 transition-all duration-700"> </div> <div class="col-span-1 bg-surface cursor-crosshair group relative overflow-hidden"> <img src="https://sgsouveni.com/assets/images/products/1778836386_6a06e3a21b27d.jpg" alt="Móc Khóa Handmade" class="w-full h-full object-cover object-top filter grayscale-[10%] group-hover:grayscale-0 transition-all duration-700"> </div> <div class="col-span-1 bg-surface cursor-crosshair group relative overflow-hidden"> <img src="https://sgsouveni.com/assets/images/products/1778836386_6a06e3a21da0f.jpg'"><a>" alt="Móc Khóa Handmade" class="w-full h-full object-cover object-top filter grayscale-[10%] group-hover:grayscale-0 transition-all duration-700"> </div> </div> </div> <!-- Content --> <div class="w-full lg:w-[45%] space-y-16"> <!-- Header --> <div class="space-y-6"> <p class="text-[12px] font-black uppercase tracking-[0.5em] text-accent"> PHƯƠNG TRÁNG GLOBAL </p> <h1 class="text-5xl md:text-8xl font-serif italic text-primary leading-[1.1]"> Móc Khóa Handmade </h1> <div class="flex items-center space-x-6"> <span class="text-4xl font-bold text-primary">236.000₫</span> <span class="text-2xl text-neutral-400 line-through decoration-1 decoration-neutral-200">323.000₫</span> <span class="text-[12px] font-black bg-rose-50 text-rose-600 px-4 py-1.5 uppercase tracking-widest">Ưu đãi giới hạn</span> </div> </div> <!-- Abstract --> <div class="text-[16px] text-neutral-700 leading-relaxed font-medium max-w-xl"> <p>Mỗi chiếc móc khóa không chỉ là một phụ kiện, mà là một mảnh ghép nhỏ mang theo nét đẹp văn hóa và sự sáng tạo của Việt Nam. </p><p>Được làm thủ công tỉ mỉ, từng chi tiết đều thể hiện sự khéo léo và tâm huyết của người nghệ nhân.</p><p> </p>'"><a> </div> <!-- Product Form --> <form id="atc-form" class="space-y-12"> <input type="hidden" name="id" value="129"> <!-- Color --> <!-- Size --> <!-- CTA --> <div class="flex flex-col sm:flex-row gap-4 pt-6"> <div class="flex items-center border border-neutral-100 h-16 px-6 bg-surface"> <button type="button" onclick="this.nextElementSibling.value = Math.max(1, parseInt(this.nextElementSibling.value)-1)" class="p-2 text-neutral-500 hover:text-primary transition-colors"><i data-lucide="minus" class="w-4 h-4"></i></button> <input type="number" name="quantity" value="1" min="1" class="w-12 bg-transparent text-center font-black text-[13px] outline-none text-primary"> <button type="button" onclick="this.previousElementSibling.value = parseInt(this.previousElementSibling.value)+1" class="p-2 text-neutral-500 hover:text-primary transition-colors"><i data-lucide="plus" class="w-4 h-4"></i></button> </div> <button type="submit" class="flex-grow h-16 bg-primary text-white text-[13px] font-black uppercase tracking-[0.4em] hover:bg-black transition-all shadow-xl"> Thêm vào giỏ hàng </button> <button type="button" onclick="buyNow()" class="flex-grow h-16 bg-accent text-white text-[13px] font-black uppercase tracking-[0.4em] hover:bg-primary transition-all shadow-xl"> MUA NGAY </button> </div> </form> <!-- Information --> <div class="border-t border-neutral-100 pt-12 space-y-10"> <div class="acc-item group active"> <button class="w-full flex justify-between items-center text-[12px] font-black uppercase tracking-[0.4em] text-primary border-b border-neutral-50 pb-4"> Chi tiết & Thành phần <i data-lucide="plus" class="w-3 h-3 group-[.active]:hidden"></i> <i data-lucide="minus" class="w-3 h-3 hidden group-[.active]:block"></i> </button> <div class="hidden group-[.active]:block py-8 text-[14px] text-neutral-900 leading-loose animate-fade-in"> <p>Móc Khóa Handmade Việt Nam – Nhỏ Xinh, Đậm Chất Riêng</p><p><br></p><p>Mỗi chiếc móc khóa không chỉ là một phụ kiện, mà là một mảnh ghép nhỏ mang theo nét đẹp văn hóa và sự sáng tạo của Việt Nam.</p><p>Được làm thủ công tỉ mỉ, từng chi tiết đều thể hiện sự khéo léo và tâm huyết của người nghệ nhân.</p><p><br></p><p>Từ những hình ảnh dễ thương, họa tiết truyền thống đến các biểu tượng đặc trưng của Việt Nam – tất cả tạo nên những chiếc móc khóa độc đáo, đầy màu sắc và cá tính.</p><p><br></p><p>✨ Điểm nổi bật:</p><p>100% handmade – mỗi sản phẩm là duy nhất</p><p>Thiết kế đa dạng: dễ thương, truyền thống, hiện đại</p><p>Nhẹ, bền, tiện lợi mang theo mọi lúc</p><p>Màu sắc nổi bật, phù hợp nhiều phong cách</p><p>🎁 Món quà hoàn hảo:</p><p>Quà lưu niệm Việt Nam ý nghĩa</p><p>Quà tặng cho bạn bè, khách quốc tế</p><p>Phụ kiện trang trí túi xách, chìa khóa</p><p>🌟 Giá trị đặc biệt:</p><p>Mang dấu ấn thủ công Việt Nam</p><p>Thể hiện cá tính và phong cách riêng</p><p>Lưu giữ kỷ niệm nhỏ nhưng đáng nhớ</p><p><br></p><p>👉 Một chiếc móc khóa nhỏ – thể hiện cả sự tinh tế và sáng tạo.</p><p><br></p><p>Chọn ngay cho mình một mẫu thật xinh để mang theo phong cách Việt mỗi ngày!</p><p><br></p><p>🇻🇳 Phiên bản ngắn (banner)</p><p><br></p><p>Móc Khóa Handmade – Nhỏ Xinh & Độc Đáo</p><p>Thủ công • Dễ thương • Ý nghĩa</p><p>👉 Mua ngay</p>'"><a> </div> </div> <div class="acc-item group"> <button class="w-full flex justify-between items-center text-[12px] font-black uppercase tracking-[0.4em] text-primary border-b border-neutral-50 pb-4"> Giao hàng & Di sản <i data-lucide="plus" class="w-3 h-3 group-[.active]:hidden"></i> <i data-lucide="minus" class="w-3 h-3 hidden group-[.active]:block"></i> </button> <div class="hidden group-[.active]:block py-8 text-[13px] text-neutral-500 leading-loose font-medium opacity-80 animate-fade-in"> Sản phẩm được lựa chọn và kiểm tra thủ công. Giao hàng hỏa tốc trong 24-48 giờ. Hàng đi kèm hộp đựng đặc thù của thương hiệu. </div> </div> </div> </div> </div> <!-- Section: You May Like --> <div class="mt-48 pt-32 border-t border-neutral-100"> <div class="flex justify-between items-end mb-16"> <div class="space-y-4"> <p class="text-[12px] font-black uppercase tracking-[0.5em] text-accent">Sản phẩm liên quan</p> <h2 class="text-4xl md:text-5xl font-serif italic text-primary">Khám phá thêm</h2> </div> <a href="/products/all" class="text-[9px] font-black uppercase tracking-[0.4em] text-primary hover:text-accent border-b border-primary hover:border-accent transition-all pb-1">Xem tất cả</a> </div> <div class="grid grid-cols-2 lg:grid-cols-4 gap-x-10 gap-y-16"> <div class="group"> <div class="relative aspect-[3/4] overflow-hidden bg-surface mb-6"> <a href="/products/view?id=128"> <img src="https://sgsouveni.com/assets/images/products/1778835839.jpg" alt="Magnet Lưu Niệm" class="w-full h-full object-cover grayscale-[20%] group-hover:grayscale-0 group-hover:scale-110 transition-all duration-[2000ms]"> </a> </div> <div class="text-center space-y-2"> <p class="text-[13px] font-black uppercase tracking-[0.4em] text-neutral-500"> PHƯƠNG TRÁNG GLOBAL </p> <h3 class="font-serif italic text-xl text-primary truncate hover:text-accent transition-colors"> <a href="/products/view?id=128">Magnet Lưu Niệm</a> </h3> <p class="text-[14px] font-bold text-primary">268.000₫</p> </div> </div> </div> </div> </div> </div> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/swiper@11/swiper-bundle.min.css" /> <script src="https://cdn.jsdelivr.net/npm/swiper@11/swiper-bundle.min.js"></script> <script> const mainSwiper = new Swiper('.main-swiper', { spaceBetween: 10, pagination: { el: '.swiper-pagination', clickable: true, }, }); document.querySelectorAll('.acc-item button').forEach(btn => { btn.addEventListener('click', () => { const item = btn.closest('.acc-item'); const isActive = item.classList.contains('active'); if (!isActive) item.classList.add('active'); else item.classList.remove('active'); }); }); // Trigger Global Add To Cart Logic const form = document.querySelector('#atc-form'); if (form) { form.addEventListener('submit', (e) => { e.preventDefault(); const formData = new FormData(form); if (typeof addToCart === 'function') addToCart(formData); }); } window.buyNow = async function () { const formData = new FormData(document.querySelector('#atc-form')); const data = Object.fromEntries(formData); if (typeof syncCart === 'function') { const res = await syncCart('add', data); if (res && res.success) { // Sync to persistent local storage before redirect const storageCart = {}; res.cart.forEach(item => { storageCart[item.key] = item; }); localStorage.setItem("my_cart", JSON.stringify(storageCart)); window.location.href = '/products/cart'; } } }; </script> </main> <!-- Master Footer --> <!-- Chatbot Section Integration --> <aside id="chat-widget" class="fixed bottom-10 right-10 z-[80] group"> <button id="chatToggle" class="w-16 h-16 bg-primary text-white rounded-full flex items-center justify-center shadow-2xl hover:scale-110 transition-transform active:scale-95 group-hover:bg-black"> <i data-lucide="message-square" class="w-6 h-6"></i> </button> <div id="chatBox" class="absolute bottom-20 right-0 w-[400px] h-[600px] bg-white shadow-2xl rounded-sm flex flex-col opacity-0 pointer-events-none translate-y-4 transition-all duration-300 border border-neutral-50"> <div class="h-20 bg-primary flex items-center justify-between px-8 text-white"> <div class="flex items-center gap-4"> <div class="w-8 h-8 rounded-full bg-accent/20 flex items-center justify-center"> <i data-lucide="sparkles" class="w-4 h-4 text-accent"></i> </div> <span class="text-[13px] font-black uppercase tracking-[0.3em]">Signature Concierge</span> </div> <button id="chatClose" class="text-white/50 hover:text-white"><i data-lucide="x" class="w-5 h-5"></i></button> </div> <div id="chatMessages" class="flex-grow overflow-y-auto p-10 space-y-6 custom-scrollbar text-[12px] font-medium leading-relaxed"> <!-- Dynamic Messages --> </div> <div class="p-8 border-t border-neutral-100 flex gap-4"> <input type="text" id="chatInput" placeholder="Quý khách cần hỗ trợ gì ạ?" class="flex-grow text-[12px] border-none focus:ring-0 placeholder:text-neutral-300"> <button id="chatSend" class="text-primary hover:text-accent transition-colors"><i data-lucide="send" class="w-5 h-5"></i></button> </div> </div> </aside> <script> document.addEventListener("DOMContentLoaded", function () { const chatBox = document.getElementById('chatBox'); const chatToggle = document.getElementById('chatToggle'); const chatClose = document.getElementById('chatClose'); const chatMessages = document.getElementById('chatMessages'); const chatInput = document.getElementById('chatInput'); const chatSend = document.getElementById('chatSend'); const backendUrl = "https://globalshop.it.com/server/chatbot-vnua"; const language = ""; let userId = localStorage.getItem("userId") || Math.floor(Math.random() * 9000000) + 1000000; localStorage.setItem("userId", userId); function append(role, text) { const div = document.createElement("div"); div.className = `flex ${role === 'user' ? 'justify-end' : 'justify-start'}`; div.innerHTML = ` <div class="max-w-[80%] px-6 py-4 rounded-sm ${role === 'user' ? 'bg-primary text-white' : 'bg-surface text-primary border border-neutral-50'}"> ${text} </div> `; chatMessages.appendChild(div); chatMessages.scrollTop = chatMessages.scrollHeight; } async function send(text) { append("user", text); try { const res = await fetch(backendUrl, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ message: text, userId, language }) }); const data = await res.json(); append("bot", data.reply || "Không thể kết nối với hỗ trợ khách hàng."); } catch { append("bot", "Phát hiện lỗi kết nối mạng."); } } chatToggle.onclick = () => { const isOpen = !chatBox.classList.contains('opacity-0'); chatBox.classList.toggle('opacity-0', isOpen); chatBox.classList.toggle('pointer-events-none', isOpen); chatBox.classList.toggle('translate-y-4', isOpen); }; chatClose.onclick = chatToggle.onclick; chatSend.onclick = () => { const text = chatInput.value.trim(); if (text) { send(text); chatInput.value = ""; } }; chatInput.onkeydown = (e) => { if (e.key === 'Enter') chatSend.onclick(); }; // Initial Greeting setTimeout(() => { append("bot", "Chào mừng quý khách trở lại. Quý khách có hài lòng với lựa chọn của mình không?"); // Auto open the chat widget only on the Thank You / Order Success page if (window.location.pathname.includes('/thankyou')) { chatBox.classList.remove('opacity-0', 'pointer-events-none', 'translate-y-4'); } }, 1500); lucide.createIcons(); }); </script> <footer class="bg-primary text-white pt-24 pb-12 overflow-hidden"> <div class="container mx-auto px-4 md:px-8"> <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-5 gap-16 lg:gap-8"> <!-- Column 1: Brand --> <div class="space-y-8 animate-fade-in lg:col-span-2"> <a href="/home" class="inline-block"> <h2 class="text-3xl font-black tracking-tighter uppercase text-white"> PHƯƠNG TRÁNG GLOBAL </h2> </a> <p class="text-neutral-300 text-[13px] leading-relaxed max-w-sm font-medium uppercase tracking-[0.1em]"> Định nghĩa sự giao thoa giữa thiết kế tiên phong và tay nghề vượt thời gian. Một sự lựa chọn biên tập dành cho những người sành sỏi hiện đại. </p> <div class="pt-8"> <h4 class="text-[13px] font-black uppercase tracking-[0.4em] mb-6 text-white"> Thông tin doanh nghiệp </h4> <div class="text-[13px] text-neutral-400 font-medium tracking-[0.1em] leading-loose space-y-3"> <p class="font-bold text-white uppercase tracking-[0.2em] leading-relaxed">CÔNG TY TNHH THƯƠNG MẠI DỊCH VỤ PHƯƠNG TRÁNG GLOBAL</p> <p>Địa chỉ: T4-51 Đường T4, Phố Manhattan, Vinhomes Grand Park, Phường Long Bình, Thành Phố Hồ Chí Minh, Việt Nam</p> <p>Mã số thuế: 0319648204 - Ngày cấp: 21/07/2026<br> Nơi cấp: Sở Kế hoạch và Đầu tư Thành phố Hồ Chí Minh</p> <p>Số điện thoại: 0974204512<br> Email: phuongtrangglobal@gmail.com</p> </div> </div> <!-- Khối tích hợp Logo Bộ Công Thương tuân thủ chuẩn UX/UI của hệ thống --> <div class="pt-6"> <a href="http://online.gov.vn/nen-tang/492c32ef-b2a1-488e-af0c-bc7ee0de4d14" target="_blank" rel="noopener noreferrer" class="inline-block hover:opacity-80 transition-opacity duration-300"> <img src="/assets/images/bocongthuong.png" alt="Bộ Công Thương Đã Thông Báo" class="h-12 w-auto object-contain"> </a> </div> </div> <!-- Column 2: Navigation --> <div class="animate-fade-in" style="animation-delay: 0.1s"> <h4 class="text-[13px] font-black uppercase tracking-[0.4em] mb-10 text-white"> Sản phẩm </h4> <ul class="space-y-5 text-[12px] font-bold uppercase tracking-[0.2em] text-neutral-400"> <li><a href="/" class="hover:text-white transition-colors">Trang chủ</a></li> <li><a href="/products/all" class="hover:text-white transition-colors">Sản phẩm</a> </li> <li><a href="/news" class="hover:text-white transition-colors">Tin tức</a></li> <li><a href="/gioithieu" class="hover:text-white transition-colors">Giới thiệu</a> </li> <li><a href="/pages/contact" class="hover:text-white transition-colors">Liên hệ</a> </li> </ul> </div> <!-- Column 3: Policies --> <div class="animate-fade-in" style="animation-delay: 0.2s"> <h4 class="text-[13px] font-black uppercase tracking-[0.4em] mb-10 text-white">Chính sách </h4> <ul class="space-y-5 text-[12px] font-bold uppercase tracking-[0.2em] text-neutral-400"> <li><a href="/chinhsach/baomat" class="hover:text-white transition-colors">Bảo mật & Dữ liệu</a> </li> <li><a href="/chinhsach/giaohang" class="hover:text-white transition-colors">Giao hàng & Vận chuyển</a></li> <li><a href="/chinhsach/doisanpham" class="hover:text-white transition-colors">Đổi trả & Bảo hành</a></li> <li><a href="/chinhsach/thanhtoan" class="hover:text-white transition-colors">Chính sách thanh toán</a></li> <li><a href="/chinhsach/tiepnhankhieunai" class="hover:text-white transition-colors">Giải quyết khiếu nại</a></li> <li><a href="/chinhsach/chinhsachgia" class="hover:text-white transition-colors">Chính sách về giá</a></li> <li><a href="/chinhsach/dieukienhanghoa" class="hover:text-white transition-colors">Điều kiện & Hạn chế cung cấp</a></li> </ul> </div> <!-- Column 4: Guides --> <div class="animate-fade-in" style="animation-delay: 0.3s"> <h4 class="text-[13px] font-black uppercase tracking-[0.4em] mb-10 text-white">Hướng dẫn </h4> <ul class="space-y-5 text-[12px] font-bold uppercase tracking-[0.2em] text-neutral-400"> <li><a href="/huongdan/muahang" class="hover:text-white transition-colors">Hướng dẫn mua hàng</a> </li> <li><a href="/huongdan/thanhtoan" class="hover:text-white transition-colors">Hướng dẫn thanh toán</a> </li> <li><a href="/pages/contact" class="hover:text-white transition-colors">Hỗ trợ trực tiếp</a></li> </ul> </div> <!-- Column 5: Newsletter --> <div class="animate-fade-in space-y-12" style="animation-delay: 0.4s"> <div> <h4 class="text-[13px] font-black uppercase tracking-[0.4em] mb-8 text-white"> Bản tin </h4> <form class="relative group"> <input type="email" placeholder="ĐỊA CHỈ EMAIL CỦA BẠN" class="w-full bg-transparent border-b border-neutral-600 focus:border-white py-4 text-[12px] font-bold outline-none transition-all placeholder:text-neutral-500 uppercase tracking-widest text-white"> <button type="submit" class="absolute right-0 top-1/2 -translate-y-1/2 text-neutral-400 hover:text-white transition-colors"> <i data-lucide="arrow-right" class="w-4 h-4"></i> </button> </form> </div> </div> </div> <!-- Bottom Bar --> <div class="mt-24 pt-12 border-t border-neutral-800 flex flex-col md:flex-row justify-between items-center gap-8"> <p class="text-[12px] text-neutral-500 uppercase tracking-[0.2em] font-medium text-center md:text-left"> © 2026 PHUONG TRANG GLOBAL CO.,LTD. Bảo lưu mọi quyền. </p> <div class="flex items-center space-x-6 grayscale opacity-30 hover:grayscale-0 hover:opacity-100 transition-all duration-500"> <img src="https://upload.wikimedia.org/wikipedia/commons/5/5e/Visa_Inc._logo.svg" alt="Visa" class="h-3"> <img src="https://upload.wikimedia.org/wikipedia/commons/2/2a/Mastercard-logo.svg" alt="Mastercard" class="h-6"> <img src="https://upload.wikimedia.org/wikipedia/commons/b/b5/PayPal.svg" alt="PayPal" class="h-4"> </div> </div> </div> </footer> <!-- Initialize Icons --> <script> lucide.createIcons(); </script> <!-- Global Cart & Menu Logic --> <script> // Global State const LANG = 'vi'; const USD_RATE = Number('26000'); function formatCurrency(val) { if (LANG === 'en') return '$' + (val / USD_RATE).toFixed(2); return new Intl.NumberFormat('vi-VN').format(val) + '₫'; } async function syncCart(action, data = {}) { const formData = new FormData(); formData.append('action', action); formData.append('_STATUS', '1'); // Security check for routing for (let k in data) formData.append(k, data[k]); try { const res = await fetch('/products/cart_sync', { method: 'POST', body: formData }); return await res.json(); } catch (e) { console.error('Sync fail', e); return null; } } window.openCartModal = () => document.getElementById('cart-modal').classList.add('open'); window.closeCartModal = () => document.getElementById('cart-modal').classList.remove('open'); window.updateCartUI = async function (cartData = null) { if (!cartData) { const res = await syncCart('get'); if (res) cartData = res.cart; else return; } // Sync to Persistent LocalStorage for Checkout & Persistence const storageCart = {}; cartData.forEach(item => { storageCart[item.key] = item; }); localStorage.setItem("my_cart", JSON.stringify(storageCart)); const container = document.getElementById('cart-modal-items'); const counter = document.getElementById('cart-counter'); const totalEl = document.getElementById('cart-modal-total'); if (!container) return; container.innerHTML = ''; let total = 0; let count = 0; cartData.forEach(item => { total += item.price * item.quantity; count += Number(item.quantity); const imgPath = item.img.startsWith('http') || item.img.startsWith('/') ? item.img : '/' + item.img; const div = document.createElement('div'); div.className = "flex gap-6 group/item animate-fade-in"; div.innerHTML = ` <div class="w-20 md:w-24 aspect-[3/4] bg-surface flex-shrink-0 overflow-hidden relative"> <img src="${imgPath}" class="w-full h-full object-cover group-hover/item:scale-110 transition-transform duration-700"> </div> <div class="flex-grow flex flex-col justify-between py-1"> <div class="space-y-1"> <p class="text-[8px] font-black uppercase tracking-[0.3em] text-neutral-300">${item.brand}</p> <h4 class="text-xs font-black text-primary uppercase tracking-widest truncate max-w-[150px] md:max-w-xs">${item.name}</h4> <p class="text-[9px] text-neutral-400 font-bold uppercase tracking-widest">${item.size} / ${item.color}</p> </div> <div class="flex items-center justify-between"> <div class="flex items-center border border-neutral-100 h-9 px-1 bg-surface"> <button onclick="changeQty('${item.key}', ${item.quantity - 1})" class="p-1 text-neutral-400 hover:text-primary"><i data-lucide="minus" class="w-3 h-3"></i></button> <span class="w-7 text-center text-[12px] font-black">${item.quantity}</span> <button onclick="changeQty('${item.key}', ${item.quantity + 1})" class="p-1 text-neutral-400 hover:text-primary"><i data-lucide="plus" class="w-3 h-3"></i></button> </div> <div class="text-right"> <p class="text-xs font-black text-primary">${formatCurrency(item.price * item.quantity)}</p> <button onclick="removeItem('${item.key}')" class="text-[8px] font-black uppercase tracking-widest text-rose-500 hover:text-rose-700 mt-1 transition-colors">Discard</button> </div> </div> </div> `; container.appendChild(div); }); if (cartData.length === 0) { container.innerHTML = `<div class="py-12 text-center space-y-4"> <i data-lucide="shopping-bag" class="w-10 h-10 mx-auto text-neutral-100"></i> <p class="text-[12px] font-bold uppercase tracking-[0.2em] text-neutral-300">Bag is currently empty.</p> </div>`; } totalEl.textContent = formatCurrency(total); if (counter) counter.textContent = count; lucide.createIcons(); } window.addToCart = async function (formData) { const data = Object.fromEntries(formData); const res = await syncCart('add', data); if (res && res.success) { await updateCartUI(res.cart); openCartModal(); } } window.changeQty = async function (key, newQty) { if (newQty < 1) return removeItem(key); const res = await syncCart('update', { key, quantity: newQty }); if (res && res.success) updateCartUI(res.cart); } window.removeItem = async function (key) { const res = await syncCart('remove', { key }); if (res && res.success) updateCartUI(res.cart); } document.addEventListener('DOMContentLoaded', () => { // Mobile Menu const toggle = document.querySelector('#mobile-menu-toggle'); const menu = document.querySelector('#mobile-menu'); const mClose = document.querySelector('#mobile-menu-close'); if (toggle && menu) { toggle.onclick = () => menu.classList.remove('translate-x-full'); if (mClose) mClose.onclick = () => menu.classList.add('translate-x-full'); } // Cart Init updateCartUI(); // Modal Close const cClose = document.getElementById('cart-modal-close'); const cCont = document.getElementById('cart-modal-continue'); const cBack = document.getElementById('cart-modal-backdrop'); [cClose, cCont, cBack].forEach(el => { if (el) el.onclick = closeCartModal; }); }); </script> </body> </html>