MMCT TEAM
Server IP : 217.21.85.138  /  Your IP : 216.73.216.103
Web Server : LiteSpeed
System : Linux in-mum-web906.main-hosting.eu 4.18.0-553.37.1.lve.el8.x86_64 #1 SMP Mon Feb 10 22:45:17 UTC 2025 x86_64
User : u915722082 ( 915722082)
PHP Version : 7.4.33
Disable Function : system, exec, shell_exec, passthru, mysql_list_dbs, ini_alter, dl, symlink, link, chgrp, leak, popen, apache_child_terminate, virtual, mb_send_mail
MySQL : OFF  |  cURL : ON  |  WGET : ON  |  Perl : OFF  |  Python : OFF
Directory (0755) :  /home/u915722082/.nvm/../public_html/lohri/user/

[  Home  ][  C0mmand  ][  Upload File  ]

Current File : /home/u915722082/.nvm/../public_html/lohri/user/load_products.php
<!--load_products.php-->

<?php
if (session_status() === PHP_SESSION_NONE) {
    session_start();
}

require_once "../config/config.php";
require_once "../config/db.php";
// ... rest of the code
try {
    $pdo = new PDO(
        "mysql:host=" . DB_HOST . ";dbname=" . DB_NAME . ";charset=utf8mb4",
        DB_USER,
        DB_PASS,
        [
            PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
            PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
        ]
    );
} catch (PDOException $e) {
    die("❌ Database connection failed: " . htmlspecialchars($e->getMessage()));
}

// Get filters and sort from POST request
$filters = isset($_POST['filters']) ? json_decode($_POST['filters'], true) : [];
$sort = isset($_POST['sort']) ? $_POST['sort'] : '';
$currentPage = isset($_POST['page']) ? max(1, (int)$_POST['page']) : 1;
$productsPerPage = 10;

// Helper function to make URL-friendly strings
function makeUrl($string) {
    return strtolower(str_replace(' ', '-', preg_replace('/[^A-Za-z0-9 ]/', '', $string)));
}

function getProductGallery($pdo, $pid) {
    try {
        $sql = "SELECT pimg FROM products WHERE pid = ?";
        $stmt = $pdo->prepare($sql);
        $stmt->execute([$pid]);
        $pimg = $stmt->fetch(PDO::FETCH_COLUMN);
        
        if ($pimg) {
            $images = array_map('trim', explode(',', $pimg));
            return array_filter($images);
        }
        
        return [];
    } catch (PDOException $e) {
        return [];
    }
}

function buildProductQuery($pdo, $filters, $sort) {
$baseQuery = "
SELECT
    p.pid            AS PID,
    p.pname          AS PNAME,
    p.pthumb         AS THUMBNAIL,
    p.pimg           AS SINGLE_THUMB,
    p.pdes           AS PDES,
    p.category       AS CATEGORY,
    p.ptag           AS PTAG,
    p.status         AS STATUS,

    s.MIN_PRICE,
    s.MAX_PRICE,
    s.TOTAL_QUANTITY,

    lp.variant_title AS VNAME,
    s.MIN_PRICE      AS NEW_PRICE,
    s.MAX_PRICE      AS OLD_PRICE,

    lp.image_path    AS VARIANT_IMAGE,
    lp.variant_data  AS VARIANT_DATA,
    
    -- Add offer data
    o.offer_id       AS OFFER_ID,
    o.offer_amount   AS OFFER_PRICE,
    o.offer_valid_until AS OFFER_VALID_UNTIL

FROM products p
LEFT JOIN (
    SELECT
        pv.PID,
        MIN(pv.price)                AS MIN_PRICE,
        MAX(pv.price)                AS MAX_PRICE,
        COALESCE(SUM(pv.quantity),0) AS TOTAL_QUANTITY
    FROM product_variations pv
    GROUP BY pv.PID
) s ON s.PID = p.pid

LEFT JOIN (
    SELECT pv.*
    FROM product_variations pv
    INNER JOIN (
        SELECT PID, MIN(price) AS min_price
        FROM product_variations
        GROUP BY PID
    ) mm ON mm.PID = pv.PID AND mm.min_price = pv.price
) lp ON lp.PID = p.pid

-- Join with offers table for logged-in users
LEFT JOIN tbl_offers o ON o.product_id = p.pid 
    AND o.status = 'accepted' 
    AND o.offer_valid_until > NOW()
    " . (isset($_SESSION['user_id']) ? "AND o.user_id = " . (int)$_SESSION['user_id'] : "AND 1=0") . "
";

    $whereConditions = [];
    $havingConditions = [];
    $params = [];

    $whereConditions[] = "p.status IN ('approved','published')";

    if (!empty($filters)) {
        foreach ($filters as $filterType => $filterValues) {
            if ($filterValues === null || $filterValues === '' || $filterValues === []) continue;

            switch ($filterType) {
                case 'offers':
                    // ✅ NEW: Filter for offer products only
                    if ($filterValues === 'true' || $filterValues === true) {
                        if (isset($_SESSION['user_id'])) {
                            $whereConditions[] = "o.offer_id IS NOT NULL";
                        } else {
                            // If not logged in, show nothing
                            $whereConditions[] = "1 = 0";
                        }
                    }
                    break;

                case 'search':
                  $whereConditions[] = "(
                      LOWER(p.pname)    LIKE LOWER(?)
                      OR LOWER(p.pdes)  LIKE LOWER(?)
                      OR LOWER(p.category) LIKE LOWER(?)
                      OR LOWER(p.ptag)  LIKE LOWER(?)
                  )";
                  $searchTerm = "%{$filterValues}%";
                  $params[] = $searchTerm;
                  $params[] = $searchTerm;
                  $params[] = $searchTerm;
                  $params[] = $searchTerm;
                  break;

                case 'tag':
                  $whereConditions[] = "LOWER(p.ptag) LIKE LOWER(?)";
                  $params[] = "%{$filterValues}%";
                  break;

                case 'collection':
                    if (!empty($filterValues)) {
                        try {
                            // Get collection ID from name
                            $collectionQuery = "SELECT id FROM collections WHERE collection_name = ? LIMIT 1";
                            $collectionStmt = $pdo->prepare($collectionQuery);
                            $collectionStmt->execute([$filterValues]);
                            $collectionId = $collectionStmt->fetchColumn();
                            
                            if ($collectionId !== false && $collectionId !== null) {
                                // Filter products with this exact collection_id
                                $whereConditions[] = "p.collection_id = ?";
                                $params[] = (int)$collectionId;
                            } else {
                                // Collection name doesn't exist - show nothing
                                $whereConditions[] = "1 = 0";
                            }
                        } catch (PDOException $e) {
                            error_log("Collection filter error: " . $e->getMessage());
                            // If error, don't filter by collection
                        }
                    }
                    break;

                case 'brand':
                    if (is_array($filterValues) && $filterValues) {
                        $placeholders = implode(',', array_fill(0, count($filterValues), '?'));
                        $whereConditions[] = "p.pid IN (
                            SELECT DISTINCT PID 
                            FROM product_variation_options 
                            WHERE option_name = 'brand' 
                            AND option_value IN ($placeholders)
                        )";
                        $params = array_merge($params, $filterValues);
                    }
                    break;

                case 'price':
                    if (preg_match('/₹(\d+)-₹(\d+)/', $filterValues, $m)) {
                        $minPrice = (int)$m[1];
                        $maxPrice = (int)$m[2];
                        $havingConditions[] = "s.MIN_PRICE <= ? AND s.MAX_PRICE >= ?";
                        $params[] = $maxPrice;
                        $params[] = $minPrice;
                    }
                    break;

                case 'availability':
                    if (is_array($filterValues)) {
                        $availORs = [];
                        if (in_array('in_stock', $filterValues, true))  $availORs[] = "s.TOTAL_QUANTITY > 0";
                        if (in_array('out_of_stock', $filterValues, true)) $availORs[] = "s.TOTAL_QUANTITY <= 0";
                        if ($availORs) $havingConditions[] = '(' . implode(' OR ', $availORs) . ')';
                    }
                    break;

case 'category':
                    if (is_array($filterValues) && $filterValues) {
                        $placeholders = implode(',', array_fill(0, count($filterValues), '?'));
                        $whereConditions[] = "p.category IN ($placeholders)";
                        $params = array_merge($params, $filterValues);
                    }
                    break;

                case 'product_condition':
                    if (is_array($filterValues) && count($filterValues) > 0) {
                        $placeholders = implode(',', array_fill(0, count($filterValues), '?'));
                        $whereConditions[] = "p.product_condition IN ($placeholders)";
                        $params = array_merge($params, $filterValues);
                    }
                    break;

                default:
                    if (is_array($filterValues) && $filterValues) {
                        $placeholders = implode(',', array_fill(0, count($filterValues), '?'));
                        $whereConditions[] = "p.pid IN (
                            SELECT DISTINCT PID
                            FROM product_variation_options
                            WHERE option_name = ? AND option_value IN ($placeholders)
                        )";
                        $params[] = $filterType;
                        $params = array_merge($params, $filterValues);
                    }
                    break;
            }
        }
    }

    if ($whereConditions)  $baseQuery .= " WHERE " . implode(" AND ", $whereConditions);
    $baseQuery .= " GROUP BY p.pid";

    if ($havingConditions) $baseQuery .= " HAVING " . implode(" AND ", $havingConditions);

    switch ($sort) {
        case 'name_asc':   $baseQuery .= " ORDER BY p.pname ASC";      break;
        case 'name_desc':  $baseQuery .= " ORDER BY p.pname DESC";     break;
        case 'price_asc':  $baseQuery .= " ORDER BY s.MIN_PRICE ASC";  break;
        case 'price_desc': $baseQuery .= " ORDER BY s.MAX_PRICE DESC"; break;
        case 'newest':     $baseQuery .= " ORDER BY p.pid DESC";       break;
        default:           $baseQuery .= " ORDER BY p.pid DESC";       break;
    }

    return ['query' => $baseQuery, 'params' => $params];
}

// Updated function calls - now pass $pdo
function getTotalProductCount($pdo, $filters) {
    $queryData = buildProductQuery($pdo, $filters, '');
    
    $stmt = $pdo->prepare($queryData['query']);
    $stmt->execute($queryData['params']);
    $results = $stmt->fetchAll(PDO::FETCH_ASSOC);
    
    return count($results);
}

function getPaginatedResults($pdo, $filters, $sort, $page = 1, $perPage = 3) {
    $queryData = buildProductQuery($pdo, $filters, $sort);
    $offset = ($page - 1) * $perPage;
    
    $paginatedQuery = $queryData['query'] . " LIMIT $perPage OFFSET $offset";
    
    try {
        $stmt = $pdo->prepare($paginatedQuery);
        $stmt->execute($queryData['params']);
        return $stmt->fetchAll(PDO::FETCH_ASSOC);
    } catch (PDOException $e) {
        error_log("Pagination query error: " . $e->getMessage());
        return [];
    }
}

function getProductHoverImage($pdo, $pid, $mainImage) {
    try {
        $sql = "SELECT pimg FROM products WHERE pid = ?";
        $stmt = $pdo->prepare($sql);
        $stmt->execute([$pid]);
        $pimg = $stmt->fetch(PDO::FETCH_COLUMN);
        
        if ($pimg) {
            $galleryImages = array_map('trim', explode(',', $pimg));
            $galleryImages = array_filter($galleryImages);
            
            if (!empty($galleryImages)) {
                foreach ($galleryImages as $img) {
                    if ($img != $mainImage) {
                        return $img;
                    }
                }
            }
        }
        
        $sql = "SELECT pthumb FROM products WHERE pid = ?";
        $stmt = $pdo->prepare($sql);
        $stmt->execute([$pid]);
        $pthumb = $stmt->fetch(PDO::FETCH_COLUMN);
        
        if ($pthumb && $pthumb != $mainImage) {
            return $pthumb;
        }
        
        $sql = "SELECT image_path FROM product_variations WHERE PID = ? AND image_path IS NOT NULL AND image_path != '' AND image_path != ? LIMIT 1";
        $stmt = $pdo->prepare($sql);
        $stmt->execute([$pid, $mainImage]);
        $result = $stmt->fetch(PDO::FETCH_COLUMN);
        
        if ($result) {
            return $result;
        }
        
        return null;
    } catch (PDOException $e) {
        error_log("Hover image error: " . $e->getMessage());
        return null;
    }
}

// Get total count and calculate pagination
$totalProducts = getTotalProductCount($pdo, $filters);
$totalPages = ceil($totalProducts / $productsPerPage);

if ($currentPage > $totalPages && $totalPages > 0) {
    $currentPage = $totalPages;
}

// Get paginated products
$products = getPaginatedResults($pdo, $filters, $sort, $currentPage, $productsPerPage);

// Set image URL base path
$imageUrl = '../Images/Product';

// ========== DEBUG OUTPUT ==========
echo "<!-- ========== PAGINATION DEBUG ========== -->\n";
echo "<!-- Total Products: " . $totalProducts . " -->\n";
echo "<!-- Products Per Page: " . $productsPerPage . " -->\n";
echo "<!-- Total Pages: " . $totalPages . " -->\n";
echo "<!-- Current Page: " . $currentPage . " -->\n";
echo "<!-- Products Retrieved: " . count($products) . " -->\n";
echo "<!-- Products Empty: " . (empty($products) ? 'YES' : 'NO') . " -->\n";
echo "<!-- Condition \$totalPages > 1: " . (($totalPages > 1) ? 'TRUE' : 'FALSE') . " -->\n";
echo "<!-- ====================================== -->\n\n";

// Start output buffering for products
ob_start();
?>



<?php if(!empty($products)): ?>
    <?php foreach($products as $row): ?>
    <?php 
    $displayImage = !empty($row['VARIANT_IMAGE']) ? $row['VARIANT_IMAGE'] : 
                   (!empty($row['THUMBNAIL']) ? $row['THUMBNAIL'] : $row['SINGLE_THUMB']);
    
    $hoverImage = getProductHoverImage($pdo, $row['PID'], $displayImage);
    if (empty($hoverImage) && !empty($row['SINGLE_THUMB']) && $row['SINGLE_THUMB'] != $displayImage) {
        $hoverImage = $row['SINGLE_THUMB'];
    }
    
    $hasOffer = !empty($row['OFFER_ID']) && !empty($row['OFFER_VALID_UNTIL']);
    $offerPrice = $hasOffer ? $row['OFFER_PRICE'] : null;
    $offerValidUntil = $hasOffer ? $row['OFFER_VALID_UNTIL'] : null;
    
    $displayPrice = $hasOffer ? $offerPrice : $row['NEW_PRICE'];
    $originalPrice = $row['OLD_PRICE'];
    
    $discountPercent = 0;
    if($originalPrice > $displayPrice) {
        $discountPercent = round((($originalPrice - $displayPrice) / $originalPrice) * 100);
    }
    
    $productDetailUrl = "product_details.php?product=" . makeUrl($row['PNAME']) . "&variant=" . makeUrl($row['VNAME']) . "&pid=" . $row['PID'];
    ?>
    
    <div class="col-6 col-xl-3 col-lg-4 col-md-4 col-sm-6 shop-ui-products-count">
        <div class="card product-card" 
             data-product-url="<?php echo $productDetailUrl; ?>"
             <?php if(!empty($hoverImage)): ?>data-hover-image="<?php echo $imageUrl; ?>/<?php echo $hoverImage; ?>"<?php endif; ?>
             onclick="window.location.href='<?php echo $productDetailUrl; ?>'"
             style="cursor: pointer;">
            
            <div class="product-image">
                <img src="<?php echo $imageUrl; ?>/<?php echo $displayImage; ?>" 
                     alt="<?php echo htmlspecialchars($row['PNAME']); ?>" 
                     class="main-image">
                
                <?php if(!empty($hoverImage)): ?>
                    <img src="<?php echo $imageUrl; ?>/<?php echo $hoverImage; ?>" 
                         alt="<?php echo htmlspecialchars($row['PNAME']); ?>" 
                         class="hover-image">
                <?php endif; ?>
                
                <!-- Product Badges (Top Left) -->
                <?php if($row['TOTAL_QUANTITY'] <= 0): ?>
                <div class="product-badge out-of-stock">
                    <span>Out of Stock</span>
                </div>
                <?php elseif($hasOffer): ?>
                <div class="product-badge offer-badge">
                    <span>Offer Product</span>
                </div>
                <?php elseif($discountPercent > 0): ?>
                <div class="product-badge discount">
                    <span><?php echo $discountPercent; ?>% Off</span>
                </div>
                <?php endif; ?>
                
               <!-- Wishlist Button (Top Right - Hover Only) -->
<!-- Wishlist Button (Top Right - Hover Only) -->
<button class="btn-wishlist-overlay" 
        onclick="handleProductCardWishlist(<?php echo $row['PID']; ?>, event); return false;"
        data-pid="<?php echo $row['PID']; ?>"
        title="Add to Wishlist">
    <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
        <path d="M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z"/>
    </svg>
</button>

<!-- Add to Cart Button (Bottom Center - Hover Only) -->
<button class="btn-cart-overlay" 
        onclick="openVariantModal(<?php echo $row['PID']; ?>, 'cart'); return false;"
        <?php echo $row['TOTAL_QUANTITY'] <= 0 ? 'disabled' : ''; ?>>
    <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
        <circle cx="9" cy="21" r="1"></circle>
        <circle cx="20" cy="21" r="1"></circle>
        <path d="M1 1h4l2.68 13.39a2 2 0 0 0 2 1.61h9.72a2 2 0 0 0 2-1.61L23 6H6"></path>
    </svg>
    Add to Cart
</button>
            </div>
            
            <div class="product-info">
                <div class="product-brand"><?php echo htmlspecialchars($row['CATEGORY'] ?: 'Product'); ?></div>
                <div class="product-title">
                    <a style="text-decoration:none" href="<?php echo $productDetailUrl; ?>" onclick="event.stopPropagation();">
                        <?php echo htmlspecialchars($row['PNAME']); ?>
                    </a>
                </div>
                
                <?php if($hasOffer): ?>
                <div class="product-price-row">
                    <div class="product-price">
                        <span class="current-price offer-price">₹<?php echo number_format($offerPrice, 2); ?></span>
                        <span class="original-price">₹<?php echo number_format($originalPrice, 2); ?></span>
                    </div>
                    <div class="offer-timer" data-offer-end="<?php echo $offerValidUntil; ?>">
                        <i class="fas fa-clock"></i>
                        <span class="timer-text"></span>
                    </div>
                </div>
                <?php else: ?>
                <div class="product-price">
                    <span class="current-price">₹<?php echo number_format($displayPrice, 2); ?></span>
                    <?php if($displayPrice != $originalPrice): ?>
                        <span class="original-price">₹<?php echo number_format($originalPrice, 2); ?></span>
                    <?php endif; ?>
                </div>
                <?php endif; ?>
                
                <!-- Keep Existing: Shop Now & Quick View Buttons -->
                <div class="product-actions">
                    <button class="btn-shop" 
                            onclick="event.stopPropagation(); window.location.href='<?php echo $productDetailUrl; ?>'">
                        Shop Now
                    </button>
                    <span class="action-separator">|</span>
                    <button class="btn-quick-view"
                        onclick="event.stopPropagation(); openQuickView(<?php echo $row['PID']; ?>)"
                        data-bs-toggle="modal" 
                        data-bs-target="#productModal"
                        data-id='<?php echo $row['PID']; ?>' 
                        data-image='<?php echo $displayImage; ?>' 
                        data-pname='<?php echo htmlspecialchars($row['PNAME']); ?>' 
                        data-vname='<?php echo htmlspecialchars($row['VNAME']); ?>' 
                        data-des='<?php echo htmlspecialchars($row['PDES']); ?>'
                        data-price='₹<?php echo number_format($displayPrice, 2); ?>' 
                        data-old-price='₹<?php echo number_format($originalPrice, 2); ?>' 
                        data-cname='<?php echo htmlspecialchars($row['CATEGORY']); ?>' 
                        data-quantity='<?php echo $row['TOTAL_QUANTITY']; ?>'
                        data-product-url='<?php echo $productDetailUrl; ?>'>
                    Quick View
                    </button>
                </div>
            </div>
        </div>
    </div>
    <?php endforeach; ?>
    
    <!-- PAGINATION DEBUG BOX -->
    <!-- <div class="col-12 mt-3" style="background: #2196F3; color: white; padding: 15px; border-radius: 5px;">
        <h4>📄 Pagination Check:</h4>
        <p>Will pagination show? <strong><?php echo ($totalPages > 1) ? '✅ YES' : '❌ NO'; ?></strong></p>
        <p>Reason: totalPages (<?php echo $totalPages; ?>) <?php echo ($totalPages > 1) ? '> 1' : '<= 1'; ?></p>
    </div> -->
    
    <!-- ACTUAL PAGINATION -->
    <?php if($totalPages > 1): ?>
    <div class="col-12 mt-5 mt-smm-0" style="padding: 20px;">
     <nav aria-label="Page navigation">
    <ul class="pagination justify-content-center align-items-center gap-2">
        <!-- Previous Button -->
        <li class="page-item <?php echo $currentPage <= 1 ? 'disabled' : ''; ?>">
            <a class="page-link border-0 d-flex align-items-center justify-content-center" 
               href="#" 
               onclick="<?php echo $currentPage > 1 ? 'goToPage('.($currentPage - 1).'); return false;' : 'return false;'; ?>"
               style="background: transparent;">
                <!-- Left Arrow -->
                <svg width="35" height="35" viewBox="0 0 45 44" fill="none" xmlns="http://www.w3.org/2000/svg">
                    <path d="M16.8189 22.8597H31.5V21.1344H16.8189L23.7285 14.2249L22.5 13L13.5 22L22.5 31L23.7285 29.7751L16.8189 22.8597Z" fill="#000"/>
                </svg>
            </a>
        </li>
        
        <!-- Page Numbers -->
        <?php 
        $startPage = max(1, min($currentPage - 1, $totalPages - 2));
        $endPage = min($totalPages, max($currentPage + 1, 3));

        for($i = $startPage; $i <= $endPage; $i++): ?>
        <li class="page-item">
            <a class="page-link d-flex align-items-center justify-content-center <?php echo $i === $currentPage ? 'active' : ''; ?>" 
               href="#" 
               onclick="goToPage(<?php echo $i; ?>); return false;"
               style="width: 35px; height: 35px; border: none; background: <?php echo $i === $currentPage ? '#000' : 'transparent'; ?>; color: <?php echo $i === $currentPage ? '#fff' : '#000'; ?>; border-radius: 4px; font-weight: 500;font-size: 13px;">
                <?php echo $i; ?>
            </a>
        </li>
        <?php endfor; ?>

        <!-- Next Button -->
        <li class="page-item <?php echo $currentPage >= $totalPages ? 'disabled' : ''; ?>">
            <a class="page-link border-0 d-flex align-items-center justify-content-center" 
               href="#" 
               onclick="<?php echo $currentPage < $totalPages ? 'goToPage('.($currentPage + 1).'); return false;' : 'return false;'; ?>"
               style="background: transparent;">
                <!-- Right Arrow -->
                <svg width="35" height="35" viewBox="0 0 45 44" fill="none" xmlns="http://www.w3.org/2000/svg">
                    <path d="M28.1811 22.8597H13.5V21.1344H28.1811L21.2715 14.2249L22.5 13L31.5 22L22.5 31L21.2715 29.7751L28.1811 22.8597Z" fill="#000"/>
                </svg>
            </a>
        </li>
    </ul>
</nav>

    </div>
    
    <?php endif; ?>
    
<?php else: ?>
    <div class="col-12 text-center py-5">
        <h4>No products found</h4>
        <p>Try adjusting your filters or search criteria.</p>
        <button class="btn btn-dark mt-3" onclick="clearAllFilters()">Clear All Filters</button>
    </div>
<?php endif; ?>

<?php
$output = ob_get_clean();
echo $output;
?>










<style>
/* ============================================ */
/* PRODUCT CARD STYLES - COMPLETE              */
/* ============================================ */

/* Product Card Container */
.product-card {
  overflow: hidden;
  transition: transform 0.3s ease;
  border: none;
  height: 100%;
  box-shadow: none;
  position: relative;
}

.product-card:hover {
  transform: translateY(-5px);
  box-shadow: none;
}

/* Product Image Container */
.product-image {
  position: relative;
  height: 600px;
  overflow: hidden;
}

.product-image .main-image,
.product-image .hover-image {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: opacity 0.3s ease;
  border-radius: 10px;
}

.product-image .hover-image {
  opacity: 0;
}

.product-card:hover .product-image .main-image {
  opacity: 0;
}

.product-card:hover .product-image .hover-image {
  opacity: 1;
}

/* ============================================ */
/* HOVER OVERLAY BUTTONS                       */
/* ============================================ */

/* Wishlist Button (Top Right Corner - Hover Only) */
.btn-wishlist-overlay {
  position: absolute;
  top: 12px;
  right: 12px;
  width: 40px;
  height: 40px;
  background: rgba(255, 255, 255, 0.95);
  border: none;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  opacity: 0;
  transform: translateY(-10px);
  transition: all 0.3s ease;
  z-index: 10;
  box-shadow: 0 2px 8px rgba(0,0,0,0.1);
}

.btn-wishlist-overlay:hover {

  transform: translateY(-10px) scale(1.1);
}

.btn-wishlist-overlay:hover svg {
  stroke: #fff;
  fill: #fff;
}

.product-card:hover .btn-wishlist-overlay {
  opacity: 1;
  transform: translateY(0);
}

.btn-wishlist-overlay svg {
  stroke: #000;
  transition: all 0.3s ease;
}

/* Add to Cart Button (Bottom Center - Hover Only) */
.btn-cart-overlay {
  position: absolute;
  bottom: 20px;
  left: 50%;
  transform: translateX(-50%) translateY(20px);
  background: #000;
  color: white;
  border: none;
  border-radius: 8px;
  padding: 12px 100px;
  font-size: 14px;
  font-weight: 500;
  display: flex;
  align-items: center;
  gap: 8px;
  cursor: pointer;
  opacity: 0;
  transition: all 0.3s ease;
  z-index: 10;
  box-shadow: 0 4px 12px rgba(0,0,0,0.2);
  white-space: nowrap;
}

.btn-cart-overlay:hover {
  background: #333;
  transform: translateX(-50%) translateY(20px) scale(1.05);
}

.btn-cart-overlay:disabled {
  background: #999;
  cursor: not-allowed;
  opacity: 0.6;
}

.btn-cart-overlay:disabled:hover {
  transform: translateX(-50%) translateY(20px);
}

.product-card:hover .btn-cart-overlay {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
}

.btn-cart-overlay svg {
  width: 18px;
  height: 18px;
}

/* ============================================ */
/* PRODUCT BADGES (Top Left)                   */
/* ============================================ */

.product-badge {
  position: absolute;
  top: 10px;
  left: 10px;
  z-index: 2;
}

.product-badge.out-of-stock {
  background: #dc3545;
  color: white;
  padding: 5px 10px;
  border-radius: 4px;
  font-size: 12px;
}

.product-badge.discount {
  background: black;
  color: white;
  padding: 5px 10px;
  border-radius: 4px;
  font-size: 12px;
}

/* Offer Badge (Top Left - NOT Top Right) */
.product-badge.offer-badge {
  background: black;
  color: white;
  padding: 6px 12px;
  border-radius: 4px;
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.5px;
  text-transform: uppercase;
}

/* ============================================ */
/* PRODUCT INFO SECTION                        */
/* ============================================ */

.product-info {
  padding: 20px 0;
  position: relative;
}

.product-brand {
  color: black;
  font-size: 14px;
  margin-bottom: 5px;
}

.product-title {
  font-size: 13px;
  margin-bottom: 10px;
  color: #666666;
}

.product-title a {
  color: #666666;
  font-size: 13px;
  text-decoration: none;
}

/* ============================================ */
/* PRICE DISPLAY                               */
/* ============================================ */

.product-price {
  font-size: 14px;
  color: black;
  transition: opacity 0.3s ease;
  font-weight: 500;
}

.product-price .current-price {
  color: black;
  font-weight: 500;
}

.product-price .original-price {
  text-decoration: line-through;
  color: #999;
  margin-left: 8px;
  font-size: 13px;
}

.product-price .offer-price {
  color: #667eea;
  font-weight: 700;
}

/* Price Row (for offer products with timer) */
.product-price-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 10px;
  transition: opacity 0.3s ease;
}

/* Hide price on hover */
.product-card:hover .product-price,
.product-card:hover .product-price-row {
  opacity: 0;
}

/* ============================================ */
/* OFFER TIMER                                 */
/* ============================================ */

.offer-timer {
  display: flex;
  align-items: center;
  gap: 4px;
  font-size: 11px;
  color: #dc3545;
  font-weight: 500;
  white-space: nowrap;
  flex-shrink: 0;
}

.offer-timer i {
  font-size: 11px;
}

.offer-timer .timer-text {
  font-weight: 600;
}

.offer-timer.expiring-soon {
  animation: pulse 1.5s ease-in-out infinite;
}

@keyframes pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.6; }
}

/* ============================================ */
/* SHOP NOW & QUICK VIEW BUTTONS               */
/* (Bottom - Show on Hover)                    */
/* ============================================ */

.product-actions {
  position: absolute;
  bottom: 20px;
  left: 0;
  display: flex;
  align-items: center;
  opacity: 0;
  transition: opacity 0.3s ease;
  gap: 0;
}

.product-card:hover .product-actions {
  opacity: 1;
}

.btn-shop,
.btn-quick-view {
  background: none;
  border: none;
  color: #666;
  font-size: 14px;
  text-decoration: none;
  margin: 0;
  cursor: pointer;
  transition: color 0.3s ease;
}

.btn-shop {
  padding-right: 8px;
  border-right: 1px solid #ccc;
}

.btn-quick-view {
  padding-left: 8px;
}

.btn-shop:hover,
.btn-quick-view:hover {
  color: #000;
}

.action-separator {
  display: none;
}

/* ============================================ */
/* PAGINATION STYLES                           */
/* ============================================ */

.pagination {
  list-style: none;
  padding: 0;
  margin: 0;
}

.pagination .page-link:hover:not(.active) {
  background-color: #f5f5f5 !important;
}

.pagination .page-item.disabled .page-link {
  opacity: 0.4;
  cursor: not-allowed;
  pointer-events: none;
}

/* ============================================ */
/* MOBILE RESPONSIVE                           */
/* ============================================ */

@media (max-width: 767px) {
  .product-card {
    border-top: 1px solid #e5e7eb;
    border-radius: 0 !important;
  }
  
  .product-image {
    height: 250px !important;
    border-radius: 0 !important;
    border: none !important;
  }
  
  .product-image .main-image, 
  .product-image .hover-image {
    border-radius: 0 !important;
  }
  
  .btn-cart-overlay {
    font-size: 12px;
    padding: 10px 16px;
    bottom: 15px;
  }
  
  .btn-wishlist-overlay {
    width: 36px;
    height: 36px;
    top: 10px;
    right: 10px;
  }
  
  .btn-wishlist-overlay svg {
    width: 16px;
    height: 16px;
  }
  
  .product-info {
    padding: 11px 0 !important;
  }
  
  .product-title {
    margin-bottom: 6px !important;
  }
  
  .product-actions {
    bottom: 12px !important;
  }
  
  .product-actions button {
    font-size: 13px !important;
  }
}

/* Quantity Input Validation */
.quantity-input:invalid,
.quantity-input.error {
  border-color: #dc3545;
}

/* Disabled Add to Cart Button */
#modalAddToCartBtn:disabled {
  background: #6c757d !important;
  cursor: not-allowed;
  opacity: 0.6;
}

#modalAddToCartBtn:disabled:hover {
  transform: none;
  box-shadow: none;
}
</style>

MMCT - 2023