File manager - Edit - /home/webapp69.cm.in.th/u69319090036/Shop/index.php
Back
<?php // index.php - Catalog & Homepage require_once 'db_connect.php'; // Retrieve Filters & Search parameters $search = $_GET['search'] ?? ''; $category = $_GET['category'] ?? ''; $size = $_GET['size'] ?? ''; $color = $_GET['color'] ?? ''; $min_price = isset($_GET['min_price']) && $_GET['min_price'] !== '' ? floatval($_GET['min_price']) : 0; $max_price = isset($_GET['max_price']) && $_GET['max_price'] !== '' ? floatval($_GET['max_price']) : 999999; $sort = $_GET['sort'] ?? 'newest'; // Build SQL query dynamically $query = "SELECT p.*, u.username AS seller_name FROM products p JOIN users u ON p.seller_id = u.id WHERE p.status = 'approved'"; $params = []; if (!empty($search)) { $query .= " AND (p.title LIKE ? OR p.description LIKE ? OR p.category LIKE ?)"; $params[] = "%$search%"; $params[] = "%$search%"; $params[] = "%$search%"; } if (!empty($category)) { $query .= " AND p.category = ?"; $params[] = $category; } if ($min_price >= 0) { $query .= " AND p.price >= ?"; $params[] = $min_price; } if ($max_price > 0 && $max_price > $min_price) { $query .= " AND p.price <= ?"; $params[] = $max_price; } if (isset($_GET['in_stock']) && $_GET['in_stock'] === '1') { $query .= " AND p.stock > 0"; } if (!empty($size)) { $query .= " AND FIND_IN_SET(?, p.sizes) > 0"; $params[] = $size; } if (!empty($color)) { $query .= " AND FIND_IN_SET(?, p.colors) > 0"; $params[] = $color; } // Sorting logic switch ($sort) { case 'price_asc': $query .= " ORDER BY p.price ASC"; break; case 'price_desc': $query .= " ORDER BY p.price DESC"; break; case 'best_selling': // Sum total quantities sold in order items $query .= " ORDER BY (SELECT IFNULL(SUM(oi.quantity), 0) FROM order_items oi WHERE oi.product_id = p.id) DESC"; break; case 'newest': default: $query .= " ORDER BY p.created_at DESC"; break; } $stmt = $pdo->prepare($query); $stmt->execute($params); $products = $stmt->fetchAll(); // Get Best Selling / Featured for Flash Sale block $flashStmt = $pdo->query("SELECT * FROM products WHERE status = 'approved' AND stock > 0 ORDER BY stock DESC LIMIT 4"); $flashProducts = $flashStmt->fetchAll(); renderHeader(__('index_page_title')); ?> <!-- 1. Hero Slide Carousel --> <section class="relative rounded-3xl overflow-hidden h-[260px] sm:h-[380px] mb-10 shadow-lg border border-gray-100"> <div id="carousel-slide-1" class="absolute inset-0 bg-gradient-to-r from-slate-900/90 to-indigo-900/90 flex items-center px-8 sm:px-16 transition-opacity duration-1000 ease-in-out opacity-100"> <div class="max-w-md text-white space-y-4"> <span class="px-3 py-1 bg-white/20 backdrop-blur text-xs font-bold uppercase rounded-full tracking-widest text-orange-300"><?php echo __('hero1_badge'); ?></span> <h1 class="text-3xl sm:text-5xl font-black tracking-tight leading-tight"><?php echo __('hero1_title'); ?></h1> <p class="text-xs sm:text-sm text-gray-200"><?php echo __('hero1_desc'); ?></p> <a href="index.php?category=Electronics" class="inline-block px-5 py-2.5 bg-white text-indigo-600 hover:bg-indigo-50 font-bold rounded-xl shadow-md transition-all text-xs sm:text-sm"><?php echo __('hero1_btn'); ?></a> </div> <div class="absolute right-0 bottom-0 h-full w-1/2 hidden md:block bg-[url('https://images.unsplash.com/photo-1505740420928-5e560c06d30e?w=800')] bg-cover bg-center"></div> </div> <div id="carousel-slide-2" class="absolute inset-0 bg-gradient-to-r from-orange-600/95 to-amber-700/95 flex items-center px-8 sm:px-16 transition-opacity duration-1000 ease-in-out opacity-0 pointer-events-none"> <div class="max-w-md text-white space-y-4"> <span class="px-3 py-1 bg-white/20 backdrop-blur text-xs font-bold uppercase rounded-full tracking-widest text-amber-200"><?php echo __('hero2_badge'); ?></span> <h1 class="text-3xl sm:text-5xl font-black tracking-tight leading-tight"><?php echo __('hero2_title'); ?></h1> <p class="text-xs sm:text-sm text-gray-100"><?php echo __('hero2_desc'); ?></p> <a href="index.php?category=Home+%26+Living" class="inline-block px-5 py-2.5 bg-white text-orange-600 hover:bg-orange-50 font-bold rounded-xl shadow-md transition-all text-xs sm:text-sm"><?php echo __('hero2_btn'); ?></a> </div> <div class="absolute right-0 bottom-0 h-full w-1/2 hidden md:block bg-[url('https://images.unsplash.com/photo-1517668808822-9ebe02f2a698?w=800')] bg-cover bg-center"></div> </div> <!-- Dots --> <div class="absolute bottom-5 left-1/2 -translate-x-1/2 flex gap-2 z-10"> <button onclick="setSlide(1)" id="carousel-dot-1" class="w-2.5 h-2.5 rounded-full bg-white transition-all"></button> <button onclick="setSlide(2)" id="carousel-dot-2" class="w-2.5 h-2.5 rounded-full bg-white/50 transition-all"></button> </div> </section> <!-- 2. Flash Sale countdown banner --> <section class="mb-12 bg-gradient-to-r from-red-600 to-orange-500 rounded-3xl p-6 text-white shadow-xl"> <div class="flex flex-col sm:flex-row sm:items-center justify-between gap-4 mb-6"> <div class="flex items-center gap-3"> <svg class="w-6 h-6 text-amber-300 animate-pulse flex-shrink-0" fill="currentColor" viewBox="0 0 24 24"><path d="M13 10V3L4 14h7v7l9-11h-7z"/></svg> <h2 class="text-xl sm:text-2xl font-black tracking-tight"><?php echo __('flash_sale_title'); ?></h2> <div class="flex gap-2 items-center ml-2"> <span id="timer-hours" class="bg-black/40 backdrop-blur px-2.5 py-1.5 rounded-lg text-sm font-black font-mono">02</span> <span class="font-bold">:</span> <span id="timer-mins" class="bg-black/40 backdrop-blur px-2.5 py-1.5 rounded-lg text-sm font-black font-mono">14</span> <span class="font-bold">:</span> <span id="timer-secs" class="bg-black/40 backdrop-blur px-2.5 py-1.5 rounded-lg text-sm font-black font-mono">55</span> </div> </div> <span class="text-xs font-bold bg-white/20 px-3.5 py-1.5 rounded-full backdrop-blur"><?php echo __('flash_ends_soon'); ?></span> </div> <div class="grid grid-cols-2 md:grid-cols-4 gap-4"> <?php foreach ($flashProducts as $flash): $originalPrice = floatval($flash['price']); $discountPrice = ($originalPrice * 0.75); // 25% off $img = getProductImgUrl($flash['id'], $flash['images']); ?> <a href="javascript:void(0)" onclick="openProductModal(<?php echo htmlspecialchars(json_encode($flash)); ?>)" class="bg-white/10 hover:bg-white/20 backdrop-blur p-3 rounded-2xl flex flex-col justify-between text-white transition-all transform hover:-translate-y-0.5 border border-white/10"> <div class="relative rounded-xl overflow-hidden mb-3 h-28 bg-gray-100/10"> <img src="<?php echo $img; ?>" class="w-full h-full object-cover" onerror="this.onerror=null; this.src='https://images.unsplash.com/photo-1526170375885-4d8ecf77b99f?w=300';"> <span class="absolute top-2 left-2 bg-yellow-400 text-slate-900 text-[9px] font-black px-1.5 py-0.5 rounded uppercase">-25%</span> </div> <div> <h4 class="font-bold text-xs line-clamp-1"><?php echo sanitize($flash['title']); ?></h4> <div class="flex items-baseline gap-2 mt-1"> <span class="text-sm font-black text-yellow-300">$<?php echo number_format($discountPrice, 2); ?></span> <span class="text-[10px] line-through text-white/50">$<?php echo number_format($originalPrice, 2); ?></span> </div> </div> </a> <?php endforeach; ?> </div> </section> <!-- 3. Category shortcuts --> <section class="mb-12"> <h3 class="text-xs font-bold text-gray-400 uppercase tracking-widest mb-6"><?php echo __('cat_featured'); ?></h3> <div class="grid grid-cols-2 sm:grid-cols-4 gap-4"> <a href="index.php?category=Electronics" class="group relative rounded-2xl overflow-hidden h-24 sm:h-28 flex items-center justify-center shadow hover:shadow-lg transition-all duration-300"> <div class="absolute inset-0 bg-cover bg-center bg-[url('https://images.unsplash.com/photo-1505740420928-5e560c06d30e?w=400')] group-hover:scale-110 transition-transform duration-300"></div> <div class="absolute inset-0 bg-slate-900/50 group-hover:bg-slate-900/65 transition-colors"></div> <span class="relative text-white font-extrabold text-sm sm:text-base tracking-wider text-center px-2"><?php echo __('cat_electronics'); ?></span> </a> <a href="index.php?category=Home+%26+Living" class="group relative rounded-2xl overflow-hidden h-24 sm:h-28 flex items-center justify-center shadow hover:shadow-lg transition-all duration-300"> <div class="absolute inset-0 bg-cover bg-center bg-[url('https://images.unsplash.com/photo-1517668808822-9ebe02f2a698?w=400')] group-hover:scale-110 transition-transform duration-300"></div> <div class="absolute inset-0 bg-slate-900/50 group-hover:bg-slate-900/65 transition-colors"></div> <span class="relative text-white font-extrabold text-sm sm:text-base tracking-wider text-center px-2"><?php echo __('cat_home'); ?></span> </a> <a href="index.php?category=Fashion" class="group relative rounded-2xl overflow-hidden h-24 sm:h-28 flex items-center justify-center shadow hover:shadow-lg transition-all duration-300"> <div class="absolute inset-0 bg-cover bg-center bg-[url('https://images.unsplash.com/photo-1553062407-98eeb64c6a62?w=400')] group-hover:scale-110 transition-transform duration-300"></div> <div class="absolute inset-0 bg-slate-900/50 group-hover:bg-slate-900/65 transition-colors"></div> <span class="relative text-white font-extrabold text-sm sm:text-base tracking-wider text-center px-2"><?php echo __('cat_fashion'); ?></span> </a> <a href="index.php?category=Food+%26+Beverages" class="group relative rounded-2xl overflow-hidden h-24 sm:h-28 flex items-center justify-center shadow hover:shadow-lg transition-all duration-300"> <div class="absolute inset-0 bg-cover bg-center bg-[url('https://images.unsplash.com/photo-1536256263959-770b48d82b0a?w=400')] group-hover:scale-110 transition-transform duration-300"></div> <div class="absolute inset-0 bg-slate-900/50 group-hover:bg-slate-900/65 transition-colors"></div> <span class="relative text-white font-extrabold text-sm sm:text-base tracking-wider text-center px-2"><?php echo __('cat_food'); ?></span> </a> </div> </section> <!-- 4. Marketplace Filters & Grid --> <div class="flex flex-col lg:flex-row gap-8"> <!-- Filter Sidebar (GET Form) --> <aside class="w-full lg:w-64 flex-shrink-0 bg-white p-6 rounded-2xl border border-gray-100 shadow-sm h-fit"> <form action="index.php" method="GET" class="space-y-6"> <!-- Persist search query --> <?php if (!empty($search)): ?> <input type="hidden" name="search" value="<?php echo sanitize($search); ?>"> <?php endif; ?> <div class="flex justify-between items-center border-b border-gray-100 pb-3"> <h3 class="font-bold text-gray-900 text-lg"><?php echo __('filter_title'); ?></h3> <a href="index.php" class="text-xs font-semibold text-orange-500 hover:underline"><?php echo __('filter_reset'); ?></a> </div> <!-- Price Filters --> <div> <h4 class="text-xs font-bold uppercase tracking-wider text-gray-400 mb-3"><?php echo __('filter_price'); ?></h4> <div class="flex gap-2"> <input type="number" name="min_price" placeholder="<?php echo __('filter_price_min'); ?>" value="<?php echo isset($_GET['min_price']) ? sanitize($_GET['min_price']) : ''; ?>" class="w-1/2 p-2 bg-gray-50 border border-gray-200 rounded-lg text-xs focus:outline-none focus:bg-white"> <input type="number" name="max_price" placeholder="<?php echo __('filter_price_max'); ?>" value="<?php echo isset($_GET['max_price']) ? sanitize($_GET['max_price']) : ''; ?>" class="w-1/2 p-2 bg-gray-50 border border-gray-200 rounded-lg text-xs focus:outline-none focus:bg-white"> </div> </div> <!-- Category Radio Filters --> <div> <h4 class="text-xs font-bold uppercase tracking-wider text-gray-400 mb-3"><?php echo __('filter_categories'); ?></h4> <div class="space-y-2 max-h-56 overflow-y-auto pr-1"> <?php $categoriesList = [ __('cat_all') => '', 'Electronics' => 'Electronics', 'Gadgets' => 'Gadgets', 'Home & Living' => 'Home & Living', 'Fashion' => 'Fashion', 'Beauty & Health' => 'Beauty & Health', 'Sports & Outdoors' => 'Sports & Outdoors', 'Food & Beverages' => 'Food & Beverages', 'Books & Stationery' => 'Books & Stationery', 'Toys & Hobbies' => 'Toys & Hobbies', 'Other' => 'Other' ]; foreach ($categoriesList as $label => $val): $isChecked = $category === $val; ?> <label class="flex items-center gap-2.5 text-sm text-gray-600 hover:text-orange-500 cursor-pointer"> <input type="radio" name="category" value="<?php echo sanitize($val); ?>" <?php echo $isChecked ? 'checked' : ''; ?> class="text-orange-500 focus:ring-orange-500"> <?php echo sanitize($label); ?> </label> <?php endforeach; ?> </div> </div> <!-- Availability Filter --> <div> <h4 class="text-xs font-bold uppercase tracking-wider text-gray-400 mb-3"><?php echo __('filter_availability'); ?></h4> <label class="flex items-center gap-2.5 text-sm text-gray-600 hover:text-orange-500 cursor-pointer"> <input type="checkbox" name="in_stock" value="1" <?php echo isset($_GET['in_stock']) && $_GET['in_stock'] === '1' ? 'checked' : ''; ?> class="rounded text-orange-500 focus:ring-orange-500"> <span><?php echo __('filter_in_stock'); ?></span> </label> </div> <!-- Color / Variant Filters (Universal) --> <div> <h4 class="text-xs font-bold uppercase tracking-wider text-gray-400 mb-3"><?php echo __('filter_color'); ?></h4> <div class="flex flex-wrap gap-1.5"> <?php $colorsList = ['Black', 'White', 'Silver', 'Gray', 'Blue', 'Red']; foreach ($colorsList as $col): $isSelected = $color === $col; ?> <label class="cursor-pointer"> <input type="radio" name="color" value="<?php echo $col; ?>" <?php echo $isSelected ? 'checked' : ''; ?> class="sr-only"> <span class="px-2.5 py-1 text-xs font-semibold rounded-lg border block transition-all <?php echo $isSelected ? 'border-orange-500 text-orange-500 bg-orange-50/50 shadow-sm' : 'border-gray-200 text-gray-600 bg-gray-50 hover:border-orange-500 hover:text-orange-500'; ?>"> <?php echo $col; ?> </span> </label> <?php endforeach; ?> </div> </div> <button type="submit" class="w-full py-2.5 bg-gray-900 text-white font-bold text-sm rounded-xl hover:bg-gray-800 transition-colors"> <?php echo __('filter_apply'); ?> </button> </form> </aside> <!-- Product catalog Grid Area --> <div class="flex-grow space-y-6"> <!-- Sort bar --> <div class="flex flex-col sm:flex-row sm:items-center justify-between gap-4 bg-white p-4 rounded-2xl border border-gray-100 shadow-sm"> <span class="text-xs font-semibold text-gray-400 uppercase tracking-wider"> <?php echo __('products_found', ['count' => count($products)]); ?> </span> <div class="flex items-center gap-2"> <span class="text-xs font-bold text-gray-400 uppercase tracking-widest"><?php echo __('sort_by'); ?></span> <select onchange="location = this.value;" class="p-2 bg-gray-50 border border-gray-200 rounded-lg text-xs font-bold text-gray-700 focus:outline-none"> <?php // Build sort options mapping $sorts = [ 'newest' => __('sort_newest'), 'price_asc' => __('sort_price_asc'), 'price_desc' => __('sort_price_desc'), 'best_selling' => __('sort_best_selling'), ]; // Generate full query params excluding sort $sortParams = $_GET; foreach ($sorts as $key => $label) { $sortParams['sort'] = $key; $url = 'index.php?' . http_build_query($sortParams); $selected = $sort === $key ? 'selected' : ''; echo "<option value='".sanitize($url)."' {$selected}>" . sanitize($label) . "</option>"; } ?> </select> </div> </div> <?php if (empty($products)): ?> <div class="text-center py-20 bg-white rounded-3xl border border-gray-100 shadow-sm space-y-4"> <div class="w-16 h-16 bg-gray-50 border border-gray-100 text-gray-400 rounded-2xl flex items-center justify-center mx-auto"> <svg class="w-8 h-8" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M16 11V7a4 4 0 00-8 0v4M5 11h14l1 12H4L5 11z"/></svg> </div> <h3 class="text-xl font-bold text-gray-900"><?php echo __('no_products'); ?></h3> <p class="text-sm text-gray-500 max-w-xs mx-auto"><?php echo __('no_products_desc'); ?></p> </div> <?php else: ?> <div class="grid grid-cols-2 md:grid-cols-3 gap-6"> <?php foreach ($products as $prod): $price = floatval($prod['price']); $img = getProductImgUrl($prod['id'], $prod['images']); $isOutOfStock = intval($prod['stock']) === 0; ?> <div class="group bg-white rounded-2xl overflow-hidden border border-gray-100 shadow-sm hover:shadow-xl transition-all duration-300 flex flex-col justify-between relative hover:-translate-y-1"> <?php if ($isOutOfStock): ?> <div class="absolute inset-0 bg-white/70 backdrop-blur-[1px] flex items-center justify-center z-10"> <span class="px-4 py-2 bg-slate-900/90 text-white text-xs font-black uppercase rounded-lg tracking-widest"><?php echo __('out_of_stock'); ?></span> </div> <?php endif; ?> <!-- Product Link --> <a href="javascript:void(0)" onclick="openProductModal(<?php echo htmlspecialchars(json_encode($prod)); ?>)" class="block relative aspect-w-4 aspect-h-5 bg-gray-100 overflow-hidden h-60"> <img src="<?php echo $img; ?>" class="w-full h-full object-cover group-hover:scale-105 transition-transform duration-500" onerror="this.onerror=null; this.src='https://images.unsplash.com/photo-1526170375885-4d8ecf77b99f?w=300';"> </a> <div class="p-4 flex-grow flex flex-col justify-between space-y-3"> <div> <span class="text-[9px] font-bold text-orange-500 uppercase tracking-widest"><?php echo sanitize($prod['category']); ?></span> <a href="javascript:void(0)" onclick="openProductModal(<?php echo htmlspecialchars(json_encode($prod)); ?>)" class="block mt-1 font-bold text-gray-900 group-hover:text-orange-500 transition-colors text-sm sm:text-base line-clamp-2"> <?php echo sanitize($prod['title']); ?> </a> </div> <div class="flex items-center justify-between"> <span class="text-base font-black text-rose-600">$<?php echo number_format($price, 2); ?></span> <span class="text-xs text-gray-400 font-semibold"><?php echo __('stock_label'); ?> <?php echo $prod['stock']; ?></span> </div> </div> </div> <?php endforeach; ?> </div> <?php endif; ?> </div> </div> <!-- 5. Product Details Modal Drawer (Populated dynamically) --> <div id="product-modal" class="fixed inset-0 z-50 flex items-center justify-center p-4 bg-slate-900/40 backdrop-blur-sm transition-all duration-300 opacity-0 pointer-events-none"> <div class="bg-white max-w-2xl w-full rounded-3xl shadow-2xl border border-gray-100 overflow-hidden flex flex-col md:flex-row relative max-h-[90vh]"> <!-- Close Button --> <button onclick="closeProductModal()" class="absolute top-4 right-4 z-10 w-8 h-8 rounded-full bg-slate-900/60 hover:bg-slate-900 text-white font-bold flex items-center justify-center transition-colors"> × </button> <!-- Product Image (Left side) --> <div class="md:w-1/2 h-64 md:h-auto bg-gray-100 relative"> <img id="modal-image" src="" alt="" class="w-full h-full object-cover"> </div> <!-- Product Controls & Data (Right side) --> <form action="cart.php?action=add" method="POST" class="md:w-1/2 p-6 sm:p-8 flex flex-col justify-between overflow-y-auto"> <input type="hidden" name="product_id" id="modal-product-id"> <div class="space-y-4"> <div> <span id="modal-category" class="text-[10px] font-bold text-orange-500 uppercase tracking-widest">Category</span> <h2 id="modal-title" class="text-xl sm:text-2xl font-extrabold text-gray-900 mt-1 line-clamp-2">Product Title</h2> <span id="modal-price" class="text-2xl font-black text-rose-600 block mt-2">$0.00</span> </div> <div class="text-xs text-gray-500 leading-relaxed border-t border-b border-gray-50 py-3"> <p id="modal-description" class="line-clamp-4"></p> </div> <!-- Attributes selections --> <div class="space-y-3"> <!-- Sizes options (Conditional) --> <div id="modal-sizes-wrapper"> <h4 class="text-xs font-bold uppercase tracking-wider text-gray-400 mb-1.5"><?php echo __('modal_size_option'); ?></h4> <div class="flex flex-wrap gap-2" id="modal-sizes-container"> <!-- Populated in JS --> </div> </div> <!-- Colors options (Conditional) --> <div id="modal-colors-wrapper"> <h4 class="text-xs font-bold uppercase tracking-wider text-gray-400 mb-1.5"><?php echo __('modal_color_variant'); ?></h4> <div class="flex flex-wrap gap-2" id="modal-colors-container"> <!-- Populated in JS --> </div> </div> <!-- Quantity adjustments --> <div class="flex items-center gap-3"> <span class="text-xs font-bold uppercase tracking-wider text-gray-400"><?php echo __('modal_qty'); ?></span> <div class="flex items-center border border-gray-200 rounded-lg overflow-hidden bg-gray-50"> <button type="button" onclick="adjustModalQty(-1)" class="px-2 py-1 text-gray-500 hover:bg-gray-100 font-bold">-</button> <input type="number" name="quantity" id="modal-qty-input" value="1" min="1" max="99" class="w-10 text-center bg-white font-bold text-xs border-x border-gray-100 py-1 focus:outline-none"> <button type="button" onclick="adjustModalQty(1)" class="px-2 py-1 text-gray-500 hover:bg-gray-100 font-bold">+</button> </div> <span id="modal-stock-info" class="text-xs text-gray-400 font-medium ml-2"><?php echo __('stock_label'); ?> 0</span> </div> </div> </div> <!-- Modal Action Footer --> <div class="pt-6 mt-6 border-t border-gray-50 flex gap-3 items-center"> <button type="submit" class="flex-grow py-3 bg-gradient-to-r from-orange-500 to-rose-500 text-white font-extrabold text-sm rounded-xl shadow-lg hover:shadow-xl transition-all focus:outline-none"> <?php echo __('modal_add_cart'); ?> </button> <button type="button" onclick="openReportModal()" class="px-3.5 py-3 text-gray-400 hover:text-red-600 hover:bg-red-50 rounded-xl transition-colors border border-gray-200 text-xs font-bold flex items-center gap-1.5" title="Report Prohibited Listing"> <svg class="w-4 h-4 text-red-500" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"/></svg> </button> </div> </form> </div> </div> <!-- Report Product Dialog Modal --> <div id="report-modal" class="fixed inset-0 z-50 flex items-center justify-center p-4 bg-slate-900/50 backdrop-blur-sm transition-all duration-300 opacity-0 pointer-events-none"> <div class="bg-white max-w-md w-full rounded-3xl shadow-2xl border border-gray-100 p-6 sm:p-8 relative"> <button onclick="closeReportModal()" class="absolute top-4 right-4 text-gray-400 hover:text-gray-600 font-bold text-lg">×</button> <h3 class="font-extrabold text-gray-900 text-lg mb-1 flex items-center gap-2"> <svg class="w-5 h-5 text-red-500" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"/></svg> Report Prohibited Listing </h3> <p class="text-xs text-gray-500 mb-5">Flag this item to Admin for safety violations, illegal items, or prohibited content.</p> <form action="index.php?action=report_product" method="POST" class="space-y-4"> <input type="hidden" name="product_id" id="report-product-id"> <div> <label for="report_reason" class="block text-xs font-bold uppercase tracking-wider text-gray-500 mb-1.5">Reason for Report</label> <select name="reason" id="report_reason" required class="w-full p-3 bg-gray-50 border border-gray-200 rounded-xl text-sm focus:outline-none focus:bg-white"> <option value="Illegal or Prohibited Item">Illegal or Prohibited Item (Weapons, Drugs, etc.)</option> <option value="Counterfeit / Fake Document">Counterfeit / Fake Document or Currency</option> <option value="Prohibited Adult Content">Prohibited Adult Content or Gambling</option> <option value="Fraud / Misleading Listing">Fraud or Misleading Information</option> <option value="Other Safety Violation">Other Safety Violation</option> </select> </div> <div> <label for="report_details" class="block text-xs font-bold uppercase tracking-wider text-gray-500 mb-1.5">Additional Details (Optional)</label> <textarea name="details" id="report_details" rows="3" placeholder="Provide details to help admin review this product..." class="w-full p-3 bg-gray-50 border border-gray-200 rounded-xl text-sm focus:outline-none focus:bg-white"></textarea> </div> <button type="submit" class="w-full py-3 bg-red-600 hover:bg-red-700 text-white font-bold rounded-xl shadow text-sm transition-all"> Submit Report to Admin </button> </form> </div> </div> <script> // Slide show parameters let slideIdx = 1; setInterval(() => { setSlide(slideIdx === 1 ? 2 : 1); }, 6000); function setSlide(num) { slideIdx = num; const s1 = document.getElementById('carousel-slide-1'); const s2 = document.getElementById('carousel-slide-2'); const d1 = document.getElementById('carousel-dot-1'); const d2 = document.getElementById('carousel-dot-2'); if (num === 1) { s1.className = "absolute inset-0 bg-gradient-to-r from-slate-900/90 to-indigo-900/90 flex items-center px-8 sm:px-16 transition-opacity duration-1000 ease-in-out opacity-100"; s2.className = "absolute inset-0 bg-gradient-to-r from-orange-600/95 to-amber-700/95 flex items-center px-8 sm:px-16 transition-opacity duration-1000 ease-in-out opacity-0 pointer-events-none"; d1.className = "w-2.5 h-2.5 rounded-full bg-white transition-all"; d2.className = "w-2.5 h-2.5 rounded-full bg-white/50 transition-all"; } else { s2.className = "absolute inset-0 bg-gradient-to-r from-orange-600/95 to-amber-700/95 flex items-center px-8 sm:px-16 transition-opacity duration-1000 ease-in-out opacity-100"; s1.className = "absolute inset-0 bg-gradient-to-r from-slate-900/90 to-indigo-900/90 flex items-center px-8 sm:px-16 transition-opacity duration-1000 ease-in-out opacity-0 pointer-events-none"; d2.className = "w-2.5 h-2.5 rounded-full bg-white transition-all"; d1.className = "w-2.5 h-2.5 rounded-full bg-white/50 transition-all"; } } // Flash sale countdown mock timer let countSeconds = 2 * 3600 + 14 * 60 + 55; setInterval(() => { if (countSeconds > 0) { countSeconds--; const hrs = Math.floor(countSeconds / 3600); const mns = Math.floor((countSeconds % 3600) / 60); const scs = countSeconds % 60; document.getElementById('timer-hours').innerText = hrs.toString().padStart(2, '0'); document.getElementById('timer-mins').innerText = mns.toString().padStart(2, '0'); document.getElementById('timer-secs').innerText = scs.toString().padStart(2, '0'); } }, 1000); // Product Modal controller let modalStock = 0; // Mapping of mock Unsplash items const UNSPLASH_IMAGES = { 1: "https://images.unsplash.com/photo-1505740420928-5e560c06d30e?w=800", 2: "https://images.unsplash.com/photo-1523275335684-37898b6baf30?w=800", 3: "https://images.unsplash.com/photo-1517668808822-9ebe02f2a698?w=800", 4: "https://images.unsplash.com/photo-1587829741301-dc798b83add3?w=800", 5: "https://images.unsplash.com/photo-1553062407-98eeb64c6a62?w=800", 6: "https://images.unsplash.com/photo-1580481072645-022f9a6d8310?w=800", 7: "https://images.unsplash.com/photo-1536256263959-770b48d82b0a?w=800", 8: "https://images.unsplash.com/photo-1542291026-7eec264c27ff?w=800" }; function openProductModal(prod) { const modal = document.getElementById('product-modal'); // Populate inputs document.getElementById('modal-product-id').value = prod.id; document.getElementById('modal-category').innerText = prod.category; document.getElementById('modal-title').innerText = prod.title; document.getElementById('modal-price').innerText = '$' + parseFloat(prod.price).toFixed(2); document.getElementById('modal-description').innerText = prod.description; document.getElementById('modal-stock-info').innerText = '<?php echo addslashes(__('stock_label')); ?> ' + prod.stock; modalStock = parseInt(prod.stock); document.getElementById('modal-qty-input').value = 1; document.getElementById('modal-qty-input').max = modalStock; // Image fallback check let imgUrl = ''; let parsedImgs = []; try { parsedImgs = JSON.parse(prod.images) || []; } catch (e) { parsedImgs = []; } if (parsedImgs.length > 0 && !parsedImgs[0].includes('/uploads/mock-') && !parsedImgs[0].includes('placeholder-product.jpg')) { imgUrl = parsedImgs[0]; } else { imgUrl = UNSPLASH_IMAGES[prod.id] || (parsedImgs.length > 0 ? parsedImgs[0] : 'https://images.unsplash.com/photo-1526170375885-4d8ecf77b99f?w=800'); } // Strip leading slash if present to make path relative if (imgUrl && imgUrl.startsWith('/')) { imgUrl = imgUrl.substring(1); } document.getElementById('modal-image').src = imgUrl; // Render Sizes Radio select list (if available) const sizesWrapper = document.getElementById('modal-sizes-wrapper'); const sizesDiv = document.getElementById('modal-sizes-container'); const sizes = prod.sizes ? prod.sizes.split(',').map(s => s.trim()).filter(s => s) : []; if (sizes.length > 0) { sizesWrapper.classList.remove('hidden'); sizesDiv.innerHTML = sizes.map((sz, idx) => ` <label class="cursor-pointer"> <input type="radio" name="size" value="${sz}" ${idx === 0 ? 'checked' : ''} class="sr-only"> <span class="px-3 py-1.5 text-xs font-bold rounded-lg border block border-gray-200 text-gray-700 bg-gray-50"> ${sz} </span> </label> `).join(''); setupBadgeRadioSwaps('size'); } else { sizesWrapper.classList.add('hidden'); sizesDiv.innerHTML = '<input type="hidden" name="size" value="Standard">'; } // Render Colors Radio select list (if available) const colorsWrapper = document.getElementById('modal-colors-wrapper'); const colorsDiv = document.getElementById('modal-colors-container'); const colors = prod.colors ? prod.colors.split(',').map(c => c.trim()).filter(c => c) : []; if (colors.length > 0) { colorsWrapper.classList.remove('hidden'); colorsDiv.innerHTML = colors.map((col, idx) => ` <label class="cursor-pointer"> <input type="radio" name="color" value="${col}" ${idx === 0 ? 'checked' : ''} class="sr-only"> <span class="px-3 py-1.5 text-xs font-bold rounded-lg border block border-gray-200 text-gray-700 bg-gray-50"> ${col} </span> </label> `).join(''); setupBadgeRadioSwaps('color'); } else { colorsWrapper.classList.add('hidden'); colorsDiv.innerHTML = '<input type="hidden" name="color" value="Standard">'; } // Show Modal modal.classList.remove('opacity-0', 'pointer-events-none'); modal.classList.add('opacity-100'); } function setupBadgeRadioSwaps(name) { const radios = document.querySelectorAll(`input[name="${name}"]`); radios.forEach((rad, idx) => { const span = rad.nextElementSibling; if (span && rad.checked) { span.className = "px-3 py-1.5 text-xs font-bold rounded-lg border-2 border-orange-500 text-orange-500 bg-orange-50/50 block"; } rad.addEventListener('change', () => { document.querySelectorAll(`input[name="${name}"]`).forEach(r => { if (r.nextElementSibling) { r.nextElementSibling.className = "px-3 py-1.5 text-xs font-bold rounded-lg border border-gray-200 text-gray-700 bg-gray-50 block"; } }); if (span) { span.className = "px-3 py-1.5 text-xs font-bold rounded-lg border-2 border-orange-500 text-orange-500 bg-orange-50/50 block"; } }); }); } function closeProductModal() { const modal = document.getElementById('product-modal'); modal.classList.add('opacity-0', 'pointer-events-none'); modal.classList.remove('opacity-100'); } function adjustModalQty(val) { const input = document.getElementById('modal-qty-input'); let current = parseInt(input.value) + val; if (current >= 1 && current <= modalStock) { input.value = current; } } function openReportModal() { const prodId = document.getElementById('modal-product-id').value; document.getElementById('report-product-id').value = prodId; const reportModal = document.getElementById('report-modal'); reportModal.classList.remove('opacity-0', 'pointer-events-none'); reportModal.classList.add('opacity-100'); } function closeReportModal() { const reportModal = document.getElementById('report-modal'); reportModal.classList.add('opacity-0', 'pointer-events-none'); reportModal.classList.remove('opacity-100'); } </script> <?php renderFooter(); ?>
| ver. 1.4 |
Github
|
.
| PHP 7.4.33 | Generation time: 0.22 |
proxy
|
phpinfo
|
Settings