<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title id="page-title">Loading Store...</title>
<!-- Tailwind CSS CDN -->
<script src="https://cdn.tailwindcss.com"></script>
<!-- FontAwesome 6 -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<!-- Google Fonts -->
<link href="https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;500;600;700;800&display=swap" rel="stylesheet">
<style>
body { font-family: 'Plus Jakarta Sans', sans-serif; scroll-behavior: smooth; }
.slider-wrapper { transition: transform 0.5s cubic-bezier(0.4, 0, 0.2, 1); }
.tab-btn.active { background-color: #4f46e5; color: #ffffff; font-weight: 700; box-shadow: 0 4px 10px rgba(79, 70, 229, 0.3); }
.category-item:hover { background-color: #f3f4f6; color: #4f46e5; }
.category-item.active { background-color: #eef2ff; color: #4f46e5; font-weight: 700; border-right: 4px solid #4f46e5; }
.variant-btn.active-variant { background-color: #eef2ff; border-color: #4f46e5; color: #4f46e5; font-weight: 700; }
::-webkit-scrollbar { height: 4px; width: 4px; }
::-webkit-scrollbar-thumb { background: #cbd5e1; border-radius: 10px; }
</style>
</head>
<body class="bg-gray-50 text-gray-800 antialiased selection:bg-indigo-500 selection:text-white pb-16 sm:pb-0">
<!-- FLOATING ADMIN / CUSTOMIZER BUTTON -->
<div class="fixed bottom-4 right-4 z-50">
<button onclick="openAdminModal()" class="bg-indigo-900 hover:bg-black text-amber-300 font-extrabold px-4 py-2.5 rounded-full shadow-2xl border-2 border-amber-400 flex items-center space-x-2 text-xs sm:text-sm transform hover:scale-105 transition active:scale-95">
<i class="fa-solid fa-sliders text-base animate-spin" style="animation-duration: 8s;"></i>
<span>⚙️ Edit Logo & Toko</span>
</button>
</div>
<!-- 1. TOP MENU BAR (RESPONSIVE) -->
<div class="bg-indigo-950 text-indigo-200 text-[10px] sm:text-[11px] py-1.5 border-b border-indigo-900/50">
<div class="max-w-7xl mx-auto px-3 sm:px-6 lg:px-8 flex flex-row items-center justify-between gap-2">
<nav class="flex items-center space-x-3 sm:space-x-5 overflow-x-auto whitespace-nowrap scrollbar-none">
<a href="#" class="hover:text-white transition flex items-center space-x-1">
<i class="fa-solid fa-house text-[9px]"></i>
<span>Beranda</span>
</a>
<a href="#tentang" onclick="alert(appConfig.storeName + ' - ' + appConfig.storeSlogan)" class="hover:text-white transition">Tentang Kami</a>
<a href="#panduan" onclick="toggleGuideModal()" class="hover:text-white transition flex items-center space-x-1">
<i class="fa-circle-question fa-regular text-[9px]"></i>
<span>Cara Order</span>
</a>
<a href="#hubungi" onclick="openCSWhatsApp()" class="hover:text-white transition">Kontak</a>
</nav>
<div class="flex items-center space-x-3 flex-shrink-0">
<span id="top-announcement" class="bg-indigo-900/80 text-amber-300 px-2 py-0.5 rounded-full text-[9px] font-semibold hidden md:inline border border-indigo-700/50">
<i class="fa-solid fa-truck-fast mr-1"></i> Gratis Ongkir Seluruh Indonesia
</span>
<div class="flex items-center space-x-1 text-indigo-300">
<i class="fa-brands fa-whatsapp text-emerald-400"></i>
<span id="top-cs-phone" class="font-bold text-white text-[10px] sm:text-[11px]">CS: 081234567890</span>
</div>
</div>
</div>
</div>
<!-- 2. NAVBAR UTAMA (DENGAN LOGO DYNAMIS) -->
<header class="sticky top-0 z-40 bg-white/95 backdrop-blur-md shadow-sm border-b border-gray-100">
<div class="max-w-7xl mx-auto px-3 sm:px-6 lg:px-8 h-16 flex items-center justify-between gap-2 sm:gap-3">
<!-- LOGO & BRANDING TOKO -->
<div class="flex items-center space-x-2.5 flex-shrink-0 cursor-pointer" onclick="window.scrollTo(0,0)">
<div id="brand-logo-icon" class="w-10 h-10 rounded-xl flex items-center justify-center flex-shrink-0 transition">
<!-- Dynamic Logo Image/Icon via JS -->
</div>
<div class="truncate max-w-[130px] sm:max-w-none">
<h1 id="brand-name" class="font-black text-base sm:text-lg tracking-tight text-gray-900 leading-none truncate">Zulaikha Store</h1>
<p id="brand-slogan" class="text-[9px] sm:text-[10px] text-gray-500 font-medium mt-0.5 truncate">Premium Shopping</p>
</div>
</div>
<!-- SEARCH BAR -->
<div class="flex flex-1 max-w-md mx-1 sm:mx-4">
<div class="relative w-full">
<input type="text" id="search-input" onkeyup="searchProduct()" placeholder="Cari barang..." class="w-full pl-8 sm:pl-9 pr-3 py-1.5 sm:py-2 bg-gray-100 border-0 rounded-xl text-xs focus:ring-2 focus:ring-indigo-600 focus:bg-white transition">
<i class="fa-solid fa-magnifying-glass absolute left-2.5 sm:left-3 top-1/2 -translate-y-1/2 text-gray-400 text-xs"></i>
</div>
</div>
<!-- KERANJANG -->
<div class="flex items-center space-x-2 flex-shrink-0">
<button onclick="toggleCart()" class="relative bg-indigo-50 hover:bg-indigo-100 text-indigo-700 px-3 sm:px-4 py-2 rounded-xl font-bold transition flex items-center space-x-1.5 text-xs shadow-sm">
<i class="fa-solid fa-cart-shopping text-sm"></i>
<span class="hidden sm:inline">Keranjang</span>
<span id="cart-count" class="bg-rose-500 text-white text-[10px] font-bold w-5 h-5 rounded-full flex items-center justify-center border-2 border-white">0</span>
</button>
</div>
</div>
</header>
<!-- 3. HERO: SIDEBAR KATEGORI & SLIDER HALF-HEIGHT -->
<section class="max-w-7xl mx-auto px-3 sm:px-6 lg:px-8 py-3">
<div class="flex flex-col md:flex-row items-stretch gap-3">
<aside class="w-full md:w-1/4 lg:w-1/5 flex-shrink-0">
<div class="bg-white rounded-2xl shadow-sm border border-gray-100 overflow-hidden h-full flex flex-col justify-between">
<div class="p-2 sm:p-2.5 bg-gray-50 border-b border-gray-100 flex items-center justify-between">
<div class="flex items-center space-x-1.5">
<i class="fa-solid fa-list-ul text-indigo-600 text-xs"></i>
<h3 class="font-bold text-xs text-gray-900 tracking-tight">Kategori Produk</h3>
</div>
</div>
<nav id="category-sidebar-list" class="flex md:flex-col py-1 overflow-x-auto md:overflow-y-auto max-h-[160px] md:max-h-[190px] scrollbar-none">
<!-- JS Dynamic Render -->
</nav>
</div>
</aside>
<div class="w-full md:w-3/4 lg:w-4/5 flex-1 h-[140px] sm:h-[160px] md:h-[190px]">
<div class="relative rounded-2xl overflow-hidden shadow-md bg-gray-900 h-full group">
<div id="slider-track" class="flex h-full slider-wrapper w-full">
<!-- Slide diisi JS -->
</div>
<div class="absolute inset-x-0 top-0 p-2 flex justify-between items-start z-20 pointer-events-none">
<div class="bg-black/50 backdrop-blur-md text-white text-[8px] sm:text-[9px] font-bold px-2 py-0.5 rounded-full border border-white/20 pointer-events-auto shadow-sm">
<i class="fa-solid fa-circle text-emerald-400 text-[4px] mr-1 animate-pulse"></i>
<span id="slide-counter-badge">Slide 1</span>
</div>
</div>
<div class="absolute inset-y-0 flex items-center justify-between px-2 w-full pointer-events-none">
<button onclick="prevSlide()" class="pointer-events-auto bg-white/20 hover:bg-white/40 backdrop-blur-md text-white w-6 h-6 sm:w-7 sm:h-7 rounded-full flex items-center justify-center transition-all opacity-0 group-hover:opacity-100 shadow-md">
<i class="fa-solid fa-chevron-left text-[10px]"></i>
</button>
<button onclick="nextSlide()" class="pointer-events-auto bg-white/20 hover:bg-white/40 backdrop-blur-md text-white w-6 h-6 sm:w-7 sm:h-7 rounded-full flex items-center justify-center transition-all opacity-0 group-hover:opacity-100 shadow-md">
<i class="fa-solid fa-chevron-right text-[10px]"></i>
</button>
</div>
<div id="slider-dots" class="absolute bottom-1.5 left-1/2 -translate-x-1/2 flex space-x-1.5 z-20 bg-black/20 backdrop-blur-md px-2 py-0.5 rounded-full">
<!-- Dots JS -->
</div>
</div>
</div>
</div>
</section>
<!-- 4. TAB KATEGORI & GRID PRODUK (5 BARIS = 20 PRODUK DEFAULTS) -->
<main class="max-w-7xl mx-auto px-3 sm:px-6 lg:px-8 py-2">
<div class="bg-white p-2.5 sm:p-3 rounded-2xl shadow-sm border border-gray-100 mb-3 flex items-center justify-between flex-wrap gap-2">
<div id="category-tab-list" class="flex items-center space-x-2 overflow-x-auto pb-0.5 scrollbar-none w-full sm:w-auto">
<!-- JS Dynamic Tabs -->
</div>
<div class="text-[10px] sm:text-[11px] font-bold text-gray-400">
Menampilkan <span id="rendered-count" class="text-indigo-600 font-extrabold">20</span> dari <span id="total-count" class="text-gray-700">0</span> Produk
</div>
</div>
<div id="product-grid" class="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-4 gap-2 sm:gap-3.5">
<!-- Rendered by JS -->
</div>
<div id="load-more-container" class="mt-6 text-center">
<button onclick="loadMoreProducts()" id="load-more-btn" class="bg-indigo-600 hover:bg-indigo-700 text-white font-bold px-6 py-2.5 rounded-xl text-xs shadow-md transition-all flex items-center mx-auto space-x-2">
<i class="fa-solid fa-rotate"></i>
<span>Muat Lebih Banyak Produk</span>
</button>
</div>
<!-- 5. LAYER BANNER IKLAN KECIL -->
<div id="small-ad-banner" class="mt-8 rounded-2xl bg-gradient-to-r from-amber-500 via-rose-500 to-indigo-600 text-white p-3.5 sm:p-5 shadow-md relative overflow-hidden flex flex-col sm:flex-row items-center justify-between gap-3 group">
<div id="ad-banner-bg" class="absolute inset-0 bg-cover bg-center hidden opacity-30 transition-all duration-300"></div>
<div class="absolute inset-0 bg-black/20 group-hover:bg-black/10 transition"></div>
<div class="flex items-center space-x-3 z-10">
<div class="w-10 h-10 bg-white/20 backdrop-blur-md rounded-xl flex items-center justify-center text-white text-xl flex-shrink-0 shadow-inner">
<i class="fa-solid fa-bolt text-amber-300"></i>
</div>
<div>
<div class="flex items-center space-x-2">
<span id="ad-banner-badge" class="bg-white/20 text-white text-[9px] font-extrabold px-2 py-0.5 rounded-full uppercase tracking-wider border border-white/20">FLASH SALE</span>
<span id="ad-banner-subtitle" class="text-[10px] text-amber-200 font-semibold">Penawaran Spesial Terbatas</span>
</div>
<h4 id="ad-banner-title" class="font-extrabold text-xs sm:text-sm leading-tight mt-1 drop-shadow">Diskon Spesial Hingga 50% + Gratis Ongkir!</h4>
</div>
</div>
<a id="ad-banner-btn" href="#" onclick="openCSWhatsApp('Halo Admin, saya ingin menanyakan Promo Flash Sale!')" class="z-10 bg-white hover:bg-amber-50 text-indigo-900 font-extrabold text-xs px-4 py-2 rounded-xl shadow transition whitespace-nowrap flex items-center space-x-1.5 transform hover:scale-105">
<i class="fa-brands fa-whatsapp text-emerald-500 text-sm"></i>
<span>Klaim Promo WhatsApp</span>
</a>
</div>
<!-- 6. 3 PRODUK UNGGULAN -->
<section class="mt-8">
<div class="flex items-center justify-between mb-4">
<div class="flex items-center space-x-2">
<div class="w-7 h-7 bg-amber-500 text-white rounded-xl flex items-center justify-center shadow-sm">
<i class="fa-solid fa-fire text-sm"></i>
</div>
<div>
<h3 class="font-extrabold text-base sm:text-lg text-gray-900 tracking-tight flex items-center gap-2">
<span>3 Produk Unggulan</span>
<span class="bg-amber-100 text-amber-700 text-[10px] font-bold px-2 py-0.5 rounded-full border border-amber-300">Terlaris</span>
</h3>
<p class="text-[10px] sm:text-xs text-gray-400">Rekomendasi terbaik dengan tingkat kepuasan pelanggan tertinggi</p>
</div>
</div>
</div>
<div id="featured-products-grid" class="grid grid-cols-1 sm:grid-cols-3 gap-3.5">
<!-- JS Render -->
</div>
</section>
</main>
<!-- 7. TRUST BADGES -->
<section class="max-w-7xl mx-auto px-3 sm:px-6 lg:px-8 mt-8 mb-6">
<div class="grid grid-cols-2 lg:grid-cols-4 gap-3">
<div class="bg-white p-3.5 rounded-2xl border border-gray-100 shadow-sm flex items-center space-x-3">
<div class="w-9 h-9 rounded-xl bg-indigo-50 text-indigo-600 flex items-center justify-center flex-shrink-0"><i class="fa-solid fa-shield-check"></i></div>
<div><h4 class="font-bold text-xs text-gray-900">100% Original</h4><p class="text-[9px] text-gray-400">Jaminan kualitas produk</p></div>
</div>
<div class="bg-white p-3.5 rounded-2xl border border-gray-100 shadow-sm flex items-center space-x-3">
<div class="w-9 h-9 rounded-xl bg-emerald-50 text-emerald-600 flex items-center justify-center flex-shrink-0"><i class="fa-solid fa-truck-fast"></i></div>
<div><h4 class="font-bold text-xs text-gray-900">Pengiriman Cepat</h4><p class="text-[9px] text-gray-400">Pesanan langsung diproses</p></div>
</div>
<div class="bg-white p-3.5 rounded-2xl border border-gray-100 shadow-sm flex items-center space-x-3">
<div class="w-9 h-9 rounded-xl bg-amber-50 text-amber-600 flex items-center justify-center flex-shrink-0"><i class="fa-solid fa-rotate-left"></i></div>
<div><h4 class="font-bold text-xs text-gray-900">Garansi Retur</h4><p class="text-[9px] text-gray-400">Garansi tukar jika cacat</p></div>
</div>
<div class="bg-white p-3.5 rounded-2xl border border-gray-100 shadow-sm flex items-center space-x-3">
<div class="w-9 h-9 rounded-xl bg-purple-50 text-purple-600 flex items-center justify-center flex-shrink-0"><i class="fa-brands fa-whatsapp text-base"></i></div>
<div><h4 class="font-bold text-xs text-gray-900">Respon CS Cepat</h4><p class="text-[9px] text-gray-400">Siap melayani 24/7</p></div>
</div>
</div>
</section>
<!-- 8. FOOTER UTAMA (CUSTOMIZABLE) -->
<footer class="bg-indigo-950 text-indigo-200 mt-8 border-t border-indigo-900">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8 sm:py-10">
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6 sm:gap-8 mb-8">
<div class="space-y-3">
<div class="flex items-center space-x-2.5">
<div id="footer-logo-icon" class="w-9 h-9 rounded-xl flex items-center justify-center flex-shrink-0">
<!-- JS Footer Logo -->
</div>
<h3 id="footer-store-name" class="font-bold text-lg text-white tracking-tight">Zulaikha Store</h3>
</div>
<p id="footer-desc" class="text-xs text-indigo-300 leading-relaxed">Pusat fashion, tas, sepatu, dan aksesoris berkualitas premium dengan sistem pesan cepat WhatsApp.</p>
</div>
<div>
<h4 class="font-bold text-white text-xs uppercase tracking-wider mb-3 pb-1 border-b border-indigo-900">Navigasi Cepat</h4>
<ul class="space-y-2 text-xs">
<li><a href="#" class="hover:text-white transition">Beranda Utama</a></li>
<li><a href="#panduan" onclick="toggleGuideModal()" class="hover:text-white transition">Panduan Cara Order</a></li>
<li><a href="#" onclick="openCSWhatsApp('Halo Admin, mau tanya status pesanan')" class="hover:text-white transition">Status Pesanan</a></li>
</ul>
</div>
<div>
<h4 class="font-bold text-white text-xs uppercase tracking-wider mb-3 pb-1 border-b border-indigo-900">Pembayaran & Pengiriman</h4>
<p class="text-[11px] text-indigo-300 mb-2">BCA, Mandiri, BRI, QRIS, J&T, JNE, SiCepat</p>
</div>
<div>
<h4 class="font-bold text-white text-xs uppercase tracking-wider mb-3 pb-1 border-b border-indigo-900">Hubungi Kami</h4>
<p id="footer-address" class="text-xs text-indigo-300 mb-3">Jakarta & Bandung, Indonesia</p>
<a href="#" onclick="openCSWhatsApp()" class="inline-flex bg-emerald-500 hover:bg-emerald-600 text-white font-bold py-2 px-3 rounded-xl shadow text-xs items-center space-x-2">
<i class="fa-brands fa-whatsapp text-sm"></i><span>Chat WhatsApp Admin</span>
</a>
</div>
</div>
<div class="pt-6 border-t border-indigo-900/80 text-center text-xs text-indigo-400">
<p>© 2026 <span id="copyright-store-name">Zulaikha Store</span>. Hak Cipta Dilindungi.</p>
</div>
</div>
</footer>
<!-- ================= MODAL ADMIN CUSTOMIZER DENGAN FITUR UPLOAD LOGO ================= -->
<div id="admin-modal" class="fixed inset-0 z-50 bg-black/80 backdrop-blur-md hidden flex items-center justify-center p-3 sm:p-4">
<div class="bg-white w-full max-w-3xl rounded-3xl shadow-2xl overflow-hidden flex flex-col max-h-[90vh]">
<div class="p-4 bg-indigo-900 text-white flex justify-between items-center">
<div class="flex items-center space-x-2">
<i class="fa-solid fa-sliders text-amber-400 text-lg"></i>
<h3 class="font-bold text-sm sm:text-base">Panel Kustomisasi & Edit Toko</h3>
</div>
<button onclick="closeAdminModal()" class="text-white/80 hover:text-white p-1"><i class="fa-solid fa-xmark text-xl"></i></button>
</div>
<div class="bg-gray-100 border-b flex overflow-x-auto text-xs font-bold scrollbar-none">
<button onclick="switchAdminTab('tab-general')" class="admin-tab-btn active px-4 py-3 border-b-2 border-indigo-600 text-indigo-600 whitespace-nowrap">1. Logo & Info Toko</button>
<button onclick="switchAdminTab('tab-categories')" class="admin-tab-btn px-4 py-3 border-b-2 border-transparent text-gray-500 hover:text-gray-800 whitespace-nowrap">2. Kategori</button>
<button onclick="switchAdminTab('tab-products')" class="admin-tab-btn px-4 py-3 border-b-2 border-transparent text-gray-500 hover:text-gray-800 whitespace-nowrap">3. Tambah/Edit Produk</button>
<button onclick="switchAdminTab('tab-banners')" class="admin-tab-btn px-4 py-3 border-b-2 border-transparent text-gray-500 hover:text-gray-800 whitespace-nowrap">4. Banner Header</button>
</div>
<div class="p-4 sm:p-6 overflow-y-auto space-y-4 flex-1 text-xs">
<!-- TAB 1: GENERAL INFO & UPLOAD LOGO -->
<div id="tab-general" class="admin-tab-content space-y-4">
<h4 class="font-bold text-sm text-gray-900">Upload Logo Toko & Identitas</h4>
<!-- UPLOAD LOGO SECTION -->
<div class="bg-indigo-50/70 border border-indigo-100 p-4 rounded-2xl space-y-3">
<label class="block font-bold text-indigo-950">Upload Logo Toko</label>
<div class="flex flex-col sm:flex-row items-center gap-3">
<div id="logo-preview-box" class="w-16 h-16 rounded-2xl border-2 border-dashed border-indigo-300 bg-white flex items-center justify-center overflow-hidden flex-shrink-0">
<i class="fa-solid fa-image text-gray-300 text-2xl"></i>
</div>
<div class="flex-1 space-y-2 w-full">
<input type="file" id="cfg-logo-file" accept="image/*" onchange="handleLogoFileSelect(event)" class="w-full text-xs text-gray-500 file:mr-2 file:py-1.5 file:px-3 file:rounded-xl file:bg-indigo-600 file:text-white file:border-0 hover:file:bg-indigo-700 cursor-pointer border rounded-xl bg-white p-1">
<p class="text-[10px] text-gray-400">Atau tempel URL Link Gambar Logo di bawah:</p>
<input type="text" id="cfg-logo-url" placeholder="https://domain.com/logo.png" oninput="handleLogoUrlInput(this.value)" class="w-full p-2 bg-white border rounded-xl outline-none focus:ring-2 focus:ring-indigo-600">
</div>
<button onclick="clearLogo()" class="text-rose-500 font-bold text-xs hover:underline flex-shrink-0">Hapus Logo</button>
</div>
</div>
<div class="grid grid-cols-1 sm:grid-cols-2 gap-3">
<div>
<label class="block font-semibold text-gray-600 mb-1">Nama Toko</label>
<input type="text" id="cfg-store-name" class="w-full p-2.5 bg-gray-50 border rounded-xl outline-none focus:ring-2 focus:ring-indigo-600">
</div>
<div>
<label class="block font-semibold text-gray-600 mb-1">Slogan Toko</label>
<input type="text" id="cfg-store-slogan" class="w-full p-2.5 bg-gray-50 border rounded-xl outline-none focus:ring-2 focus:ring-indigo-600">
</div>
<div>
<label class="block font-semibold text-gray-600 mb-1">Nomor WhatsApp Admin (Format 628xxx)</label>
<input type="text" id="cfg-wa-number" class="w-full p-2.5 bg-gray-50 border rounded-xl outline-none focus:ring-2 focus:ring-indigo-600">
</div>
<div>
<label class="block font-semibold text-gray-600 mb-1">Pengumuman Bar Atas</label>
<input type="text" id="cfg-announcement" class="w-full p-2.5 bg-gray-50 border rounded-xl outline-none focus:ring-2 focus:ring-indigo-600">
</div>
</div>
</div>
<!-- TAB 2: CATEGORIES -->
<div id="tab-categories" class="admin-tab-content hidden space-y-3">
<h4 class="font-bold text-sm text-gray-900">Kelola Kategori Produk</h4>
<div class="flex space-x-2">
<input type="text" id="new-cat-id" placeholder="ID (cth: elektronik)" class="w-1/3 p-2 border rounded-xl">
<input type="text" id="new-cat-name" placeholder="Nama Kategori (cth: Elektronik)" class="w-2/3 p-2 border rounded-xl">
<button onclick="addNewCategory()" class="bg-indigo-600 text-white px-4 rounded-xl font-bold">Tambah</button>
</div>
<div id="admin-category-list" class="space-y-1.5 pt-2"></div>
</div>
<!-- TAB 3: PRODUCTS -->
<div id="tab-products" class="admin-tab-content hidden space-y-3">
<h4 class="font-bold text-sm text-gray-900">Tambah / Edit Produk Baru</h4>
<div class="bg-gray-50 p-3 rounded-2xl border space-y-2">
<div class="grid grid-cols-1 sm:grid-cols-2 gap-2">
<input type="text" id="p-name" placeholder="Nama Produk" class="p-2 border rounded-xl">
<input type="number" id="p-price" placeholder="Harga (cth: 150000)" class="p-2 border rounded-xl">
<select id="p-category" class="p-2 border rounded-xl bg-white"></select>
<input type="text" id="p-image" placeholder="URL Foto Utama (https://...)" class="p-2 border rounded-xl">
</div>
<textarea id="p-desc" placeholder="Deskripsi Singkat Produk" rows="2" class="w-full p-2 border rounded-xl"></textarea>
<div class="grid grid-cols-1 sm:grid-cols-2 gap-2">
<input type="text" id="p-variant1-name" placeholder="Nama Varian 1 (cth: Merah)" class="p-2 border rounded-xl">
<input type="text" id="p-variant1-img" placeholder="URL Foto Varian 1" class="p-2 border rounded-xl">
<input type="text" id="p-variant2-name" placeholder="Nama Varian 2 (cth: Biru)" class="p-2 border rounded-xl">
<input type="text" id="p-variant2-img" placeholder="URL Foto Varian 2" class="p-2 border rounded-xl">
</div>
<button onclick="saveNewProduct()" class="w-full bg-emerald-600 text-white font-bold py-2 rounded-xl shadow">Simpan Produk Baru</button>
</div>
<h5 class="font-bold text-xs text-gray-700 pt-2">Daftar Produk Terpasang (<span id="p-count-display">0</span>)</h5>
<div id="admin-products-list" class="space-y-2 max-h-[180px] overflow-y-auto"></div>
</div>
<!-- TAB 4: BANNERS -->
<div id="tab-banners" class="admin-tab-content hidden space-y-3">
<h4 class="font-bold text-sm text-gray-900">Kelola Slide Banner Header</h4>
<div class="flex space-x-2">
<input type="file" id="new-slide-file" accept="image/*" class="w-1/2 text-xs p-1 border rounded-xl">
<input type="text" id="new-slide-title" placeholder="Judul Banner Promo" class="w-1/2 p-2 border rounded-xl">
<button onclick="addSlideFromAdmin()" class="bg-indigo-600 text-white px-3 rounded-xl font-bold">Upload</button>
</div>
<div id="admin-slides-list" class="space-y-1.5"></div>
</div>
</div>
<div class="p-4 bg-gray-100 border-t flex items-center justify-between">
<button onclick="resetToDefaultData()" class="text-rose-600 font-bold text-xs hover:underline">Reset Data Awal</button>
<button onclick="saveAllAdminChanges()" class="bg-indigo-600 hover:bg-indigo-700 text-white font-bold px-6 py-2.5 rounded-xl text-xs shadow-lg">Simpan & Terapkan Perubahan</button>
</div>
</div>
</div>
<!-- MODAL DETAIL PRODUK & VARIAN -->
<div id="product-detail-modal" class="fixed inset-0 z-50 bg-black/70 backdrop-blur-sm hidden flex items-center justify-center p-3">
<div class="bg-white w-full max-w-lg rounded-3xl shadow-2xl overflow-hidden flex flex-col max-h-[90vh]">
<div class="p-3 bg-gray-50 border-b flex justify-between items-center">
<span class="text-xs font-bold text-gray-500 uppercase">Detail & Varian Produk</span>
<button onclick="closeProductDetailModal()" class="text-gray-400 hover:text-gray-600 p-1"><i class="fa-solid fa-xmark text-lg"></i></button>
</div>
<div class="p-4 overflow-y-auto space-y-4" id="modal-product-content"></div>
</div>
</div>
<!-- MODAL CARA ORDER -->
<div id="guide-modal" class="fixed inset-0 z-50 bg-black/70 backdrop-blur-sm hidden flex items-center justify-center p-4">
<div class="bg-white w-full max-w-sm rounded-3xl p-6 shadow-2xl">
<div class="flex justify-between items-center border-b pb-3 mb-4">
<h3 class="font-bold text-sm text-gray-900 flex items-center space-x-2">
<i class="fa-solid fa-circle-info text-indigo-600"></i>
<span>Panduan Belanja</span>
</h3>
<button onclick="toggleGuideModal()"><i class="fa-solid fa-xmark text-lg"></i></button>
</div>
<ol class="space-y-3 text-xs text-gray-600 list-decimal pl-4">
<li>Pilih produk favorit Anda.</li>
<li>Klik kartu produk untuk memilih varian warna/ukuran.</li>
<li>Klik <b>+ Keranjang</b> lalu buka menu Keranjang.</li>
<li>Isi Nama Lengkap & Alamat Pengiriman.</li>
<li>Klik <b>Checkout via WhatsApp</b> untuk terhubung dengan Admin.</li>
</ol>
<button onclick="toggleGuideModal()" class="w-full bg-indigo-600 text-white font-bold py-3 rounded-2xl text-xs mt-6">Paham, Terima Kasih</button>
</div>
</div>
<!-- MODAL KERANJANG BELANJA -->
<div id="cart-modal" class="fixed inset-0 z-50 bg-black/60 backdrop-blur-sm hidden flex justify-end">
<div class="bg-white w-full max-w-sm h-full shadow-2xl flex flex-col">
<div class="p-5 border-b flex items-center justify-between">
<h3 class="font-extrabold text-lg flex items-center space-x-2">
<i class="fa-solid fa-cart-shopping text-indigo-600"></i><span>Keranjang Belanja</span>
</h3>
<button onclick="toggleCart()"><i class="fa-solid fa-xmark text-xl text-gray-400"></i></button>
</div>
<div id="cart-items" class="flex-1 overflow-y-auto p-5 space-y-3"></div>
<div class="p-6 border-t bg-gray-50 space-y-3">
<input type="text" id="buyer-name" placeholder="Nama Lengkap Anda" class="w-full px-4 py-3 rounded-2xl border text-xs focus:ring-2 focus:ring-indigo-600 outline-none">
<textarea id="buyer-address" placeholder="Alamat Pengiriman Lengkap" rows="2" class="w-full px-4 py-3 rounded-2xl border text-xs focus:ring-2 focus:ring-indigo-600 outline-none"></textarea>
<div class="flex justify-between items-center"><span class="font-bold text-gray-500 text-xs">Total Harga:</span><span id="cart-total" class="font-black text-indigo-600 text-lg">Rp 0</span></div>
<button onclick="checkoutWhatsApp()" class="w-full bg-emerald-500 text-white font-black py-4 rounded-2xl shadow-lg flex items-center justify-center space-x-2 transition hover:bg-emerald-600">
<i class="fa-brands fa-whatsapp text-2xl"></i><span>Checkout via WhatsApp</span>
</button>
</div>
</div>
</div>
<!-- SCRIPT UTAMA & LOGIKA LOKAL PERSISTENCE -->
<script>
// CONFIG DEFAULT STATE
const defaultAppConfig = {
storeName: "Zulaikha Store",
storeSlogan: "Premium Online Shopping",
storeLogo: "", // Base64 or Image URL for Logo
waNumber: "6281234567890",
topAnnouncement: "Gratis Ongkir Seluruh Indonesia S&K Berlaku",
categories: [
{ id: "all", name: "Semua", icon: "fa-border-all" },
{ id: "fashion", name: "Fashion", icon: "fa-shirt" },
{ id: "aksesoris", name: "Aksesoris", icon: "fa-watch-smart" },
{ id: "tas", name: "Tas", icon: "fa-bag-shopping" },
{ id: "sepatu", name: "Sepatu", icon: "fa-shoe-prints" }
],
slides: [
{ id: 1, image: "https://images.unsplash.com/photo-1441984904996-e0b6ba687e04?auto=format&fit=crop&w=1200&q=80", title: "Fashion Trends 2026", subtitle: "Koleksi terkini berkualitas tinggi." },
{ id: 2, image: "https://images.unsplash.com/photo-1523275335684-37898b6baf30?auto=format&fit=crop&w=1200&q=80", title: "Aksesoris Eksklusif", subtitle: "Lengkapi gaya harianmu." }
]
};
const defaultProducts = [
{ id: 1, name: "Kemeja Flanel Premium", category: "fashion", price: 185000, rating: "4.9", reviews: 128, image: "https://images.unsplash.com/photo-1596755094514-f87e34085b2c?auto=format&w=500", variants: [{ name: "Merah Kotak", img: "https://images.unsplash.com/photo-1596755094514-f87e34085b2c?auto=format&w=500" }, { name: "Biru Navy", img: "https://images.unsplash.com/photo-1602810318383-e386cc2a3ccf?auto=format&w=500" }], description: "Bahan katun flanel tebal & halus." },
{ id: 2, name: "Jam Tangan Minimalist", category: "aksesoris", price: 299000, rating: "4.8", reviews: 95, image: "https://images.unsplash.com/photo-1523275335684-37898b6baf30?auto=format&w=500", variants: [{ name: "Silver Klasik", img: "https://images.unsplash.com/photo-1523275335684-37898b6baf30?auto=format&w=500" }, { name: "Rose Gold", img: "https://images.unsplash.com/photo-1522335789203-aabd1fc54bc9?auto=format&w=500" }], description: "Water resistant 3ATM." },
{ id: 3, name: "Tas Selempang Leather", category: "tas", price: 155000, rating: "5.0", reviews: 210, image: "https://images.unsplash.com/photo-1548036328-c9fa89d128fa?auto=format&w=500", variants: [{ name: "Cokelat Tan", img: "https://images.unsplash.com/photo-1548036328-c9fa89d128fa?auto=format&w=500" }], description: "Eksklusif kulit sintetis tebal." },
{ id: 4, name: "Sneakers White Casual", category: "sepatu", price: 320000, rating: "4.9", reviews: 176, image: "https://images.unsplash.com/photo-1549298916-b41d501d3772?auto=format&w=500", variants: [{ name: "Full White", img: "https://images.unsplash.com/photo-1549298916-b41d501d3772?auto=format&w=500" }], description: "Sol empuk nyaman seharian." }
];
let appConfig = JSON.parse(localStorage.getItem('zk_app_config')) || defaultAppConfig;
let products = JSON.parse(localStorage.getItem('zk_products_data')) || generateInitial20Products();
let tempLogoData = appConfig.storeLogo || "";
let cart = [];
let currentSlideIdx = 0, slideTimer = null, currentCategory = 'all', visibleCount = 20;
function generateInitial20Products() {
let list = [];
for(let i=0; i<20; i++) {
let base = defaultProducts[i % defaultProducts.length];
list.push({
...base,
id: i + 1,
name: base.name + (i >= 4 ? ` Vol. ${Math.floor(i/4)+1}` : '')
});
}
return list;
}
// INITIALIZE STORE BRANDING & LOGO
function initStore() {
document.title = appConfig.storeName;
document.getElementById('page-title').innerText = appConfig.storeName;
document.getElementById('brand-name').innerText = appConfig.storeName;
document.getElementById('brand-slogan').innerText = appConfig.storeSlogan;
document.getElementById('top-announcement').innerHTML = `<i class="fa-solid fa-truck-fast mr-1"></i> ${appConfig.topAnnouncement}`;
document.getElementById('top-cs-phone').innerText = `CS: ${appConfig.waNumber}`;
document.getElementById('footer-store-name').innerText = appConfig.storeName;
document.getElementById('copyright-store-name').innerText = appConfig.storeName;
// RENDER LOGO GAMBAR / IKON
const headerLogoIcon = document.getElementById('brand-logo-icon');
const footerLogoIcon = document.getElementById('footer-logo-icon');
if (appConfig.storeLogo) {
headerLogoIcon.className = "w-10 h-10 rounded-xl overflow-hidden shadow-sm border border-gray-100 bg-white flex items-center justify-center flex-shrink-0";
headerLogoIcon.innerHTML = `<img src="${appConfig.storeLogo}" class="w-full h-full object-cover">`;
if(footerLogoIcon) {
footerLogoIcon.className = "w-9 h-9 rounded-xl overflow-hidden shadow-sm border border-indigo-900 bg-white flex items-center justify-center flex-shrink-0";
footerLogoIcon.innerHTML = `<img src="${appConfig.storeLogo}" class="w-full h-full object-cover">`;
}
} else {
headerLogoIcon.className = "bg-indigo-600 text-white p-2 rounded-xl shadow-md flex items-center justify-center flex-shrink-0";
headerLogoIcon.innerHTML = `<i class="fa-solid fa-store text-lg"></i>`;
if(footerLogoIcon) {
footerLogoIcon.className = "bg-indigo-600 text-white p-2 rounded-xl flex items-center justify-center flex-shrink-0";
footerLogoIcon.innerHTML = `<i class="fa-solid fa-store text-base"></i>`;
}
}
renderCategoriesUI();
renderSlider();
startAutoSlide();
renderProductsUI();
renderFeaturedProducts();
}
function renderCategoriesUI() {
const sidebar = document.getElementById('category-sidebar-list');
const tabs = document.getElementById('category-tab-list');
const adminCatSel = document.getElementById('p-category');
sidebar.innerHTML = '';
tabs.innerHTML = '';
adminCatSel.innerHTML = '';
appConfig.categories.forEach((cat) => {
sidebar.innerHTML += `
<button onclick="filterProduct('${cat.id}', this)" class="category-item ${cat.id === currentCategory ? 'active' : ''} flex items-center justify-between px-3 py-1.5 transition text-[11px] flex-shrink-0 whitespace-nowrap">
<span class="flex items-center truncate"><i class="fa-solid ${cat.icon || 'fa-tag'} w-4"></i> <span>${cat.name}</span></span>
</button>
`;
tabs.innerHTML += `
<button onclick="selectTab('${cat.id}', this)" class="tab-btn ${cat.id === currentCategory ? 'active' : ''} px-3 py-1.5 rounded-xl text-xs font-bold bg-gray-100 text-gray-500 hover:bg-gray-200 transition flex-shrink-0 flex items-center space-x-1.5">
<i class="fa-solid ${cat.icon || 'fa-tag'} text-[10px]"></i><span>${cat.name}</span>
</button>
`;
if(cat.id !== 'all') {
adminCatSel.innerHTML += `<option value="${cat.id}">${cat.name}</option>`;
}
});
}
function renderSlider() {
const track = document.getElementById('slider-track'), dots = document.getElementById('slider-dots');
track.innerHTML = ''; dots.innerHTML = '';
appConfig.slides.forEach((slide, idx) => {
track.innerHTML += `<div class="w-full flex-shrink-0 h-full relative"><img src="${slide.image}" class="w-full h-full object-cover"><div class="absolute inset-0 bg-gradient-to-t from-black/80 via-transparent flex flex-col justify-end p-3"><h2 class="text-xs sm:text-sm font-black text-white leading-tight">${slide.title}</h2><p class="text-[9px] text-gray-200 truncate">${slide.subtitle || ''}</p></div></div>`;
dots.innerHTML += `<button onclick="goToSlide(${idx})" class="w-1.5 h-1.5 rounded-full transition-all ${idx === currentSlideIdx ? 'bg-indigo-500 w-4' : 'bg-white/50 hover:bg-white'}"></button>`;
});
updateSlidePosition();
}
function updateSlidePosition() {
if(!appConfig.slides.length) return;
document.getElementById('slider-track').style.transform = `translateX(-${currentSlideIdx * 100}%)`;
document.getElementById('slide-counter-badge').innerText = `Slide ${currentSlideIdx + 1} / ${appConfig.slides.length}`;
}
function nextSlide() { currentSlideIdx = (currentSlideIdx + 1) % appConfig.slides.length; updateSlidePosition(); }
function prevSlide() { currentSlideIdx = (currentSlideIdx - 1 + appConfig.slides.length) % appConfig.slides.length; updateSlidePosition(); }
function goToSlide(idx) { currentSlideIdx = idx; updateSlidePosition(); }
function startAutoSlide() { stopAutoSlide(); slideTimer = setInterval(nextSlide, 5000); }
function stopAutoSlide() { if(slideTimer) clearInterval(slideTimer); }
function renderStars(rating) {
let html = '';
for (let i = 1; i <= 5; i++) {
html += `<i class="fa-solid fa-star ${i <= Math.floor(rating) ? 'text-amber-400' : 'text-gray-300'} text-[9px]"></i>`;
}
return html;
}
function renderProductsUI() {
const grid = document.getElementById('product-grid'), loadMoreBtn = document.getElementById('load-more-container');
const filtered = currentCategory === 'all' ? products : products.filter(p => p.category === currentCategory);
const itemsToRender = filtered.slice(0, visibleCount);
document.getElementById('rendered-count').innerText = itemsToRender.length;
document.getElementById('total-count').innerText = filtered.length;
if(itemsToRender.length === 0) {
grid.innerHTML = `<div class="col-span-full text-center py-10 text-gray-400 text-xs">Belum ada produk untuk kategori ini.</div>`;
loadMoreBtn.classList.add('hidden'); return;
}
grid.innerHTML = itemsToRender.map(p => `
<div class="bg-white rounded-2xl p-2.5 shadow-sm border border-gray-100 flex flex-col justify-between group transform transition hover:-translate-y-1 cursor-pointer" onclick="openProductDetailModal(${p.id})">
<div>
<div class="h-32 sm:h-40 rounded-xl overflow-hidden relative mb-2 bg-gray-50">
<img src="${p.image}" class="w-full h-full object-cover group-hover:scale-105 transition duration-500" onerror="this.src='https://images.unsplash.com/photo-1523275335684-37898b6baf30?auto=format&w=500'">
<span class="absolute top-1.5 left-1.5 bg-white/90 backdrop-blur-md px-2 py-0.5 rounded-md text-[9px] font-black uppercase text-indigo-600">${p.category}</span>
</div>
<h4 class="font-bold text-gray-900 text-xs truncate mb-0.5">${p.name}</h4>
<div class="flex items-center space-x-1 mb-1">
<div class="flex items-center space-x-0.5">${renderStars(p.rating || 5)}</div>
<span class="text-[9px] font-bold text-gray-600">${p.rating || 5.0}</span>
</div>
<p class="text-[10px] text-gray-400 line-clamp-1 mb-2">${p.description}</p>
</div>
<div class="flex items-center justify-between pt-1 border-t" onclick="event.stopPropagation()">
<span class="font-black text-indigo-600 text-xs sm:text-sm">Rp ${Number(p.price).toLocaleString('id-ID')}</span>
<button onclick="addToCart(${p.id})" class="bg-indigo-600 text-white p-1.5 rounded-lg transition hover:bg-indigo-700 shadow" title="Tambah">
<i class="fa-solid fa-plus text-[10px]"></i>
</button>
</div>
</div>
`).join('');
itemsToRender.length < filtered.length ? loadMoreBtn.classList.remove('hidden') : loadMoreBtn.classList.add('hidden');
}
function renderFeaturedProducts() {
const grid = document.getElementById('featured-products-grid');
if (!grid || products.length === 0) return;
const featuredItems = products.slice(0, 3);
const badges = ["TERLARIS NO.1", "REKOMENDASI ADMIN", "HOT PROMO"];
const colors = ["bg-rose-500", "bg-amber-500", "bg-indigo-600"];
grid.innerHTML = featuredItems.map((p, idx) => `
<div class="bg-white rounded-2xl p-3 shadow-md border-2 border-indigo-50 hover:border-indigo-200 transition flex flex-col justify-between group cursor-pointer relative overflow-hidden" onclick="openProductDetailModal(${p.id})">
<div class="absolute top-3 left-3 z-10">
<span class="${colors[idx]} text-white text-[9px] font-black px-2.5 py-1 rounded-full uppercase tracking-wider shadow-sm flex items-center gap-1">
<i class="fa-solid fa-crown text-[8px]"></i>
<span>${badges[idx]}</span>
</span>
</div>
<div>
<div class="h-40 sm:h-48 rounded-xl overflow-hidden relative mb-2.5 bg-gray-100">
<img src="${p.image}" class="w-full h-full object-cover group-hover:scale-105 transition duration-500">
</div>
<h4 class="font-extrabold text-gray-900 text-xs sm:text-sm truncate mb-0.5">${p.name}</h4>
<p class="text-[10px] text-gray-400 line-clamp-1 mb-2">${p.description}</p>
</div>
<div class="pt-2 border-t flex items-center justify-between" onclick="event.stopPropagation()">
<span class="font-black text-indigo-600 text-sm sm:text-base">Rp ${Number(p.price).toLocaleString('id-ID')}</span>
<button onclick="addToCart(${p.id})" class="bg-indigo-600 text-white px-3 py-1.5 rounded-xl text-xs font-bold shadow">+ Troli</button>
</div>
</div>
`).join('');
}
function openProductDetailModal(id) {
const p = products.find(prod => prod.id === id);
if (!p) return;
const modalContent = document.getElementById('modal-product-content');
const variants = p.variants && p.variants.length > 0 ? p.variants : [{ name: "Standar", img: p.image }];
modalContent.innerHTML = `
<div class="space-y-2">
<div class="h-56 rounded-2xl overflow-hidden bg-gray-100 border relative">
<img id="main-product-img" src="${variants[0].img}" class="w-full h-full object-cover transition-all">
</div>
<div class="flex space-x-2 overflow-x-auto pb-1">
${variants.map((v, idx) => `
<button onclick="selectVariantByIndex(${idx}, '${v.img}')" class="variant-thumb-btn w-12 h-12 rounded-xl overflow-hidden border-2 ${idx === 0 ? 'border-indigo-600' : 'border-transparent'} flex-shrink-0">
<img src="${v.img}" class="w-full h-full object-cover">
</button>
`).join('')}
</div>
</div>
<div>
<div class="flex justify-between items-center mb-1">
<h3 class="font-bold text-gray-900 text-base">${p.name}</h3>
<span class="text-indigo-600 font-extrabold text-base">Rp ${Number(p.price).toLocaleString('id-ID')}</span>
</div>
<div class="mb-3">
<label class="block text-[10px] font-bold text-gray-400 uppercase mb-1">Pilihan Warna / Tipe</label>
<div class="flex flex-wrap gap-1.5">
${variants.map((v, idx) => `
<button onclick="selectVariantByIndex(${idx}, '${v.img}')" class="variant-btn text-xs px-3 py-1.5 rounded-xl border ${idx === 0 ? 'active-variant' : 'bg-gray-50 text-gray-600'}">
${v.name}
</button>
`).join('')}
</div>
</div>
<p class="text-xs text-gray-600 mb-4 leading-relaxed">${p.description}</p>
<button onclick="addToCart(${p.id}); closeProductDetailModal();" class="w-full bg-indigo-600 text-white font-bold py-3 rounded-2xl text-xs shadow-lg">+ Tambah ke Keranjang</button>
</div>
`;
document.getElementById('product-detail-modal').classList.remove('hidden');
}
function selectVariantByIndex(index, imgUrl) {
document.getElementById('main-product-img').src = imgUrl;
document.querySelectorAll('.variant-thumb-btn').forEach((b, idx) => {
b.className = `variant-thumb-btn w-12 h-12 rounded-xl overflow-hidden border-2 ${idx === index ? 'border-indigo-600' : 'border-transparent'} flex-shrink-0`;
});
document.querySelectorAll('.variant-btn').forEach((b, idx) => {
b.className = `variant-btn text-xs px-3 py-1.5 rounded-xl border ${idx === index ? 'active-variant' : 'bg-gray-50 text-gray-600'}`;
});
}
function closeProductDetailModal() { document.getElementById('product-detail-modal').classList.add('hidden'); }
function loadMoreProducts() { visibleCount += 12; renderProductsUI(); }
function selectTab(catId, btn) {
currentCategory = catId;
visibleCount = 20;
renderCategoriesUI();
renderProductsUI();
}
function filterProduct(catId, btn) {
currentCategory = catId;
visibleCount = 20;
renderCategoriesUI();
renderProductsUI();
}
function searchProduct() {
const q = document.getElementById('search-input').value.toLowerCase();
const filtered = products.filter(p => p.name.toLowerCase().includes(q) || p.description.toLowerCase().includes(q));
visibleCount = filtered.length;
renderProductsUI();
}
// CARTS & WHATSAPP
function addToCart(id) {
const p = products.find(prod => prod.id === id);
const exist = cart.find(item => item.id === id);
exist ? exist.qty++ : cart.push({...p, qty: 1});
updateCartUI();
toggleCart();
}
function updateCartUI() {
document.getElementById('cart-count').innerText = cart.reduce((s,i) => s+i.qty, 0);
const total = cart.reduce((s,i) => s + (i.price*i.qty), 0);
document.getElementById('cart-total').innerText = `Rp ${total.toLocaleString('id-ID')}`;
const items = document.getElementById('cart-items');
items.innerHTML = cart.map((i,idx) => `
<div class="flex items-center justify-between bg-gray-50 p-2.5 rounded-xl border">
<img src="${i.image}" class="w-10 h-10 object-cover rounded-lg">
<div class="flex-1 px-2.5 truncate">
<h5 class="text-xs font-black truncate">${i.name}</h5>
<p class="text-[10px] font-bold text-indigo-600">Rp ${Number(i.price).toLocaleString('id-ID')}</p>
</div>
<div class="flex items-center space-x-1.5">
<button onclick="changeQty(${idx}, -1)" class="w-5 h-5 bg-white border rounded font-bold text-xs">-</button>
<span class="text-xs font-bold">${i.qty}</span>
<button onclick="changeQty(${idx}, 1)" class="w-5 h-5 bg-white border rounded font-bold text-xs">+</button>
</div>
</div>
`).join('');
}
function changeQty(idx, amt) {
cart[idx].qty += amt;
if(cart[idx].qty <= 0) cart.splice(idx, 1);
updateCartUI();
}
function toggleCart() { document.getElementById('cart-modal').classList.toggle('hidden'); }
function toggleGuideModal() { document.getElementById('guide-modal').classList.toggle('hidden'); }
function openCSWhatsApp(customMessage) {
const msg = customMessage || `Halo CS ${appConfig.storeName}, saya ingin bertanya perihal produk.`;
window.open(`https://wa.me/${appConfig.waNumber}?text=${encodeURIComponent(msg)}`, '_blank');
}
function checkoutWhatsApp() {
const name = document.getElementById('buyer-name').value;
const addr = document.getElementById('buyer-address').value;
if(!name || !addr || cart.length === 0) return alert("Mohon lengkapi Nama, Alamat, & Keranjang!");
let txt = `Halo *${appConfig.storeName}*, saya mau pesan:\n\n`;
cart.forEach((i, idx) => txt += `${idx+1}. *${i.name}* (x${i.qty}) - Rp ${(i.price*i.qty).toLocaleString('id-ID')}\n`);
txt += `\n*Total: Rp ${cart.reduce((s,i)=>s+(i.price*i.qty),0).toLocaleString('id-ID')}*\n\n*Data Pemesan:*\nNama: ${name}\nAlamat: ${addr}`;
window.open(`https://wa.me/${appConfig.waNumber}?text=${encodeURIComponent(txt)}`, '_blank');
}
// ================= ADMIN CUSTOMIZER & LOGO HANDLERS =================
function openAdminModal() {
document.getElementById('cfg-store-name').value = appConfig.storeName;
document.getElementById('cfg-store-slogan').value = appConfig.storeSlogan;
document.getElementById('cfg-wa-number').value = appConfig.waNumber;
document.getElementById('cfg-announcement').value = appConfig.topAnnouncement;
document.getElementById('cfg-logo-url').value = appConfig.storeLogo.startsWith('data:') ? '' : appConfig.storeLogo;
tempLogoData = appConfig.storeLogo || "";
updateLogoPreview();
renderAdminCategoriesList();
renderAdminProductsList();
renderAdminSlidesList();
document.getElementById('admin-modal').classList.remove('hidden');
}
function closeAdminModal() { document.getElementById('admin-modal').classList.add('hidden'); }
function handleLogoFileSelect(event) {
const file = event.target.files[0];
if(file) {
const reader = new FileReader();
reader.onload = function(e) {
tempLogoData = e.target.result;
updateLogoPreview();
};
reader.readAsDataURL(file);
}
}
function handleLogoUrlInput(url) {
if(url.trim() !== '') {
tempLogoData = url.trim();
updateLogoPreview();
}
}
function clearLogo() {
tempLogoData = "";
document.getElementById('cfg-logo-file').value = '';
document.getElementById('cfg-logo-url').value = '';
updateLogoPreview();
}
function updateLogoPreview() {
const box = document.getElementById('logo-preview-box');
if(tempLogoData) {
box.innerHTML = `<img src="${tempLogoData}" class="w-full h-full object-cover">`;
} else {
box.innerHTML = `<i class="fa-solid fa-image text-gray-300 text-2xl"></i>`;
}
}
function switchAdminTab(tabId) {
document.querySelectorAll('.admin-tab-content').forEach(c => c.classList.add('hidden'));
document.querySelectorAll('.admin-tab-btn').forEach(b => {
b.classList.remove('active', 'border-indigo-600', 'text-indigo-600');
b.classList.add('border-transparent', 'text-gray-500');
});
document.getElementById(tabId).classList.remove('hidden');
event.target.classList.add('active', 'border-indigo-600', 'text-indigo-600');
}
function renderAdminCategoriesList() {
const list = document.getElementById('admin-category-list');
list.innerHTML = appConfig.categories.map((c, idx) => `
<div class="flex justify-between items-center bg-gray-50 p-2 rounded-xl border">
<span class="font-bold">${c.name} (ID: ${c.id})</span>
${c.id !== 'all' ? `<button onclick="deleteCategory(${idx})" class="text-rose-500 font-bold">Hapus</button>` : '<span class="text-gray-400">Default</span>'}
</div>
`).join('');
}
function addNewCategory() {
const id = document.getElementById('new-cat-id').value.trim().toLowerCase();
const name = document.getElementById('new-cat-name').value.trim();
if(!id || !name) return alert("Isi ID dan Nama Kategori!");
appConfig.categories.push({ id, name, icon: "fa-tag" });
renderAdminCategoriesList();
}
function deleteCategory(idx) {
appConfig.categories.splice(idx, 1);
renderAdminCategoriesList();
}
function renderAdminProductsList() {
const list = document.getElementById('admin-products-list');
document.getElementById('p-count-display').innerText = products.length;
list.innerHTML = products.map((p) => `
<div class="flex justify-between items-center bg-gray-50 p-2 rounded-xl border">
<div class="flex items-center space-x-2 truncate">
<img src="${p.image}" class="w-8 h-8 object-cover rounded">
<span class="font-bold truncate">${p.name} (Rp ${Number(p.price).toLocaleString('id-ID')})</span>
</div>
<button onclick="deleteProduct(${p.id})" class="text-rose-500 font-bold">Hapus</button>
</div>
`).join('');
}
function saveNewProduct() {
const name = document.getElementById('p-name').value;
const price = document.getElementById('p-price').value;
const category = document.getElementById('p-category').value;
const image = document.getElementById('p-image').value || "https://images.unsplash.com/photo-1523275335684-37898b6baf30?auto=format&w=500";
const desc = document.getElementById('p-desc').value || "Deskripsi produk berkualitas tinggi.";
const v1n = document.getElementById('p-variant1-name').value;
const v1i = document.getElementById('p-variant1-img').value;
const v2n = document.getElementById('p-variant2-name').value;
const v2i = document.getElementById('p-variant2-img').value;
let vars = [];
if(v1n) vars.push({ name: v1n, img: v1i || image });
if(v2n) vars.push({ name: v2n, img: v2i || image });
if(vars.length === 0) vars.push({ name: "Standar", img: image });
if(!name || !price) return alert("Isi Nama & Harga Produk!");
products.unshift({
id: Date.now(),
name, price: Number(price), category, image, description: desc, rating: "5.0", reviews: 1, variants: vars
});
renderAdminProductsList();
}
function deleteProduct(id) {
products = products.filter(p => p.id !== id);
renderAdminProductsList();
}
function renderAdminSlidesList() {
const list = document.getElementById('admin-slides-list');
list.innerHTML = appConfig.slides.map((s, idx) => `
<div class="flex justify-between items-center bg-gray-50 p-2 rounded-xl border">
<span class="font-bold truncate">${s.title}</span>
<button onclick="deleteSlideAdmin(${idx})" class="text-rose-500 font-bold">Hapus</button>
</div>
`).join('');
}
function addSlideFromAdmin() {
const file = document.getElementById('new-slide-file').files[0];
const title = document.getElementById('new-slide-title').value;
if(!file) return alert("Pilih file gambar!");
appConfig.slides.push({ id: Date.now(), image: URL.createObjectURL(file), title: title || "Promo Baru" });
renderAdminSlidesList();
}
function deleteSlideAdmin(idx) {
appConfig.slides.splice(idx, 1);
renderAdminSlidesList();
}
function saveAllAdminChanges() {
appConfig.storeName = document.getElementById('cfg-store-name').value.trim();
appConfig.storeSlogan = document.getElementById('cfg-store-slogan').value.trim();
appConfig.waNumber = document.getElementById('cfg-wa-number').value.trim();
appConfig.topAnnouncement = document.getElementById('cfg-announcement').value.trim();
appConfig.storeLogo = tempLogoData;
localStorage.setItem('zk_app_config', JSON.stringify(appConfig));
localStorage.setItem('zk_products_data', JSON.stringify(products));
initStore();
closeAdminModal();
alert("Semua perubahan termasuk logo berhasil disimpan!");
}
function resetToDefaultData() {
if(confirm("Apakah Anda yakin ingin mengembalikan semua data toko & logo ke pengaturan awal?")) {
localStorage.removeItem('zk_app_config');
localStorage.removeItem('zk_products_data');
location.reload();
}
}
// INITIAL LOAD
initStore();
</script>
</body>
</html>