mirror of
https://github.com/myronblair/tomsjavajive
synced 2026-06-30 17:50:32 -05:00
Fix product images, add-to-cart, and add Sub Categories filter
- Add display:block to .product-card-image so padding-top aspect ratio works on anchor tags - Add Cache-Control: no-transform header to disable Cloudflare Rocket Loader (was deferring main.js and breaking add-to-cart click handlers) - Add Sub Categories filter row on shop page using product_types table - Show category · sub-category on product cards - Add Sub Categories section to footer - Preserve subcat param across category/sort filter links Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -338,6 +338,7 @@ img {
|
||||
}
|
||||
|
||||
.product-card-image {
|
||||
display: block;
|
||||
position: relative;
|
||||
padding-top: 100%;
|
||||
overflow: hidden;
|
||||
|
||||
@@ -23,6 +23,17 @@
|
||||
<li><a href="/shop.php?category=blends">Blends</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h4>Sub Categories</h4>
|
||||
<ul class="footer-links">
|
||||
<?php
|
||||
$footerTypes = db()->fetchAll("SELECT type_id, name FROM product_types WHERE is_active=1 ORDER BY sort_order ASC");
|
||||
foreach ($footerTypes as $ft): ?>
|
||||
<li><a href="/shop.php?subcat=<?= urlencode($ft['type_id']) ?>"><?= htmlspecialchars($ft['name']) ?></a></li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h4>Company</h4>
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
if (session_status() === PHP_SESSION_NONE) {
|
||||
session_start();
|
||||
}
|
||||
header('Cache-Control: no-store, no-cache, must-revalidate, no-transform');
|
||||
|
||||
require_once __DIR__ . '/db.php';
|
||||
require_once __DIR__ . '/../config/config.php';
|
||||
|
||||
@@ -8,6 +8,7 @@ require_once __DIR__ . '/includes/functions.php';
|
||||
|
||||
// Get filters
|
||||
$category = $_GET['category'] ?? '';
|
||||
$subcat = $_GET['subcat'] ?? '';
|
||||
$search = $_GET['search'] ?? '';
|
||||
$sort = $_GET['sort'] ?? 'newest';
|
||||
$page = max(1, intval($_GET['page'] ?? 1));
|
||||
@@ -21,6 +22,11 @@ if ($category) {
|
||||
$params['category'] = $category;
|
||||
}
|
||||
|
||||
if ($subcat) {
|
||||
$where[] = 'product_type_id = :subcat';
|
||||
$params['subcat'] = $subcat;
|
||||
}
|
||||
|
||||
if ($search) {
|
||||
$where[] = '(name LIKE :search OR description LIKE :search)';
|
||||
$params['search'] = '%' . $search . '%';
|
||||
@@ -42,7 +48,7 @@ $pagination = paginate($totalProducts, $page, 12);
|
||||
|
||||
// Get products
|
||||
$products = db()->fetchAll(
|
||||
"SELECT * FROM products WHERE {$whereClause} ORDER BY {$orderBy} LIMIT :limit OFFSET :offset",
|
||||
"SELECT p.*, pt.name AS type_name, pt.type_id AS type_slug FROM products p LEFT JOIN product_types pt ON p.product_type_id = pt.type_id WHERE {$whereClause} ORDER BY {$orderBy} LIMIT :limit OFFSET :offset",
|
||||
array_merge($params, ['limit' => $pagination['per_page'], 'offset' => $pagination['offset']])
|
||||
);
|
||||
|
||||
@@ -71,15 +77,29 @@ $productTypesList = db()->fetchAll("SELECT type_id, name, slug FROM product_type
|
||||
<section class="section">
|
||||
<div class="container">
|
||||
<!-- Filters Bar -->
|
||||
<div style="display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 1rem; margin-bottom: 2rem;">
|
||||
<div style="display: flex; gap: 1rem; flex-wrap: wrap;">
|
||||
<a href="/shop.php" class="btn <?= !$category ? 'btn-primary' : 'btn-secondary' ?>">All</a>
|
||||
<?php foreach ($categories as $cat): ?>
|
||||
<a href="/shop.php?category=<?= urlencode($cat['category']) ?>"
|
||||
class="btn <?= $category === $cat['category'] ? 'btn-primary' : 'btn-secondary' ?>">
|
||||
<?= htmlspecialchars(ucfirst($cat['category'])) ?>
|
||||
</a>
|
||||
<?php endforeach; ?>
|
||||
<div style="display: flex; justify-content: space-between; align-items: flex-start; flex-wrap: wrap; gap: 1rem; margin-bottom: 2rem;">
|
||||
<div style="display: flex; flex-direction: column; gap: 0.75rem;">
|
||||
<div style="display: flex; gap: 0.75rem; flex-wrap: wrap; align-items: center;">
|
||||
<a href="/shop.php<?= $subcat ? '?subcat=' . urlencode($subcat) : '' ?>" class="btn <?= !$category ? 'btn-primary' : 'btn-secondary' ?>">All</a>
|
||||
<?php foreach ($categories as $cat): ?>
|
||||
<a href="/shop.php?category=<?= urlencode($cat['category']) ?><?= $subcat ? '&subcat=' . urlencode($subcat) : '' ?>"
|
||||
class="btn <?= $category === $cat['category'] ? 'btn-primary' : 'btn-secondary' ?>">
|
||||
<?= htmlspecialchars(ucfirst($cat['category'])) ?>
|
||||
</a>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<?php if (!empty($productTypesList)): ?>
|
||||
<div style="display: flex; gap: 0.75rem; flex-wrap: wrap; align-items: center;">
|
||||
<span class="text-muted" style="font-size: 0.85rem; font-weight: 600; white-space: nowrap;">Sub Categories:</span>
|
||||
<a href="/shop.php<?= $category ? '?category=' . urlencode($category) : '' ?>" class="btn btn-sm <?= !$subcat ? 'btn-primary' : 'btn-secondary' ?>">All</a>
|
||||
<?php foreach ($productTypesList as $pt): ?>
|
||||
<a href="/shop.php?subcat=<?= urlencode($pt['type_id']) ?><?= $category ? '&category=' . urlencode($category) : '' ?>"
|
||||
class="btn btn-sm <?= $subcat === $pt['type_id'] ? 'btn-primary' : 'btn-secondary' ?>">
|
||||
<?= htmlspecialchars($pt['name']) ?>
|
||||
</a>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<div style="display: flex; gap: 1rem; align-items: center;">
|
||||
@@ -87,24 +107,39 @@ $productTypesList = db()->fetchAll("SELECT type_id, name, slug FROM product_type
|
||||
<?php if ($category): ?>
|
||||
<input type="hidden" name="category" value="<?= htmlspecialchars($category) ?>">
|
||||
<?php endif; ?>
|
||||
<input type="text" name="search" class="form-input" placeholder="Search..."
|
||||
<?php if ($subcat): ?>
|
||||
<input type="hidden" name="subcat" value="<?= htmlspecialchars($subcat) ?>">
|
||||
<?php endif; ?>
|
||||
<input type="text" name="search" class="form-input" placeholder="Search..."
|
||||
value="<?= htmlspecialchars($search) ?>" style="width: 200px;">
|
||||
<button type="submit" class="btn btn-secondary"><i class="fas fa-search"></i></button>
|
||||
</form>
|
||||
|
||||
<?php
|
||||
$filterQs = http_build_query(array_filter(['category' => $category, 'subcat' => $subcat]));
|
||||
$filterQs = $filterQs ? '&' . $filterQs : '';
|
||||
?>
|
||||
<select onchange="window.location.href=this.value" class="form-select" style="width: auto;">
|
||||
<option value="/shop.php?sort=newest<?= $category ? '&category=' . urlencode($category) : '' ?>" <?= $sort === 'newest' ? 'selected' : '' ?>>Newest</option>
|
||||
<option value="/shop.php?sort=price_low<?= $category ? '&category=' . urlencode($category) : '' ?>" <?= $sort === 'price_low' ? 'selected' : '' ?>>Price: Low to High</option>
|
||||
<option value="/shop.php?sort=price_high<?= $category ? '&category=' . urlencode($category) : '' ?>" <?= $sort === 'price_high' ? 'selected' : '' ?>>Price: High to Low</option>
|
||||
<option value="/shop.php?sort=name<?= $category ? '&category=' . urlencode($category) : '' ?>" <?= $sort === 'name' ? 'selected' : '' ?>>Name</option>
|
||||
<option value="/shop.php?sort=newest<?= $filterQs ?>" <?= $sort === 'newest' ? 'selected' : '' ?>>Newest</option>
|
||||
<option value="/shop.php?sort=price_low<?= $filterQs ?>" <?= $sort === 'price_low' ? 'selected' : '' ?>>Price: Low to High</option>
|
||||
<option value="/shop.php?sort=price_high<?= $filterQs ?>" <?= $sort === 'price_high' ? 'selected' : '' ?>>Price: High to Low</option>
|
||||
<option value="/shop.php?sort=name<?= $filterQs ?>" <?= $sort === 'name' ? 'selected' : '' ?>>Name</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Results count -->
|
||||
<?php
|
||||
$subcatName = '';
|
||||
if ($subcat) {
|
||||
foreach ($productTypesList as $pt) {
|
||||
if ($pt['type_id'] === $subcat) { $subcatName = $pt['name']; break; }
|
||||
}
|
||||
}
|
||||
?>
|
||||
<p class="text-muted" style="margin-bottom: 1.5rem;">
|
||||
Showing <?= count($products) ?> of <?= $totalProducts ?> products
|
||||
<?= $category ? ' in ' . htmlspecialchars(ucfirst($category)) : '' ?>
|
||||
<?= $subcatName ? ' · ' . htmlspecialchars($subcatName) : '' ?>
|
||||
</p>
|
||||
|
||||
<!-- Product Grid -->
|
||||
@@ -132,8 +167,13 @@ $productTypesList = db()->fetchAll("SELECT type_id, name, slug FROM product_type
|
||||
<?php endif; ?>
|
||||
</a>
|
||||
<div class="product-card-body">
|
||||
<?php if ($product['category']): ?>
|
||||
<div class="product-card-category"><?= htmlspecialchars($product['category']) ?></div>
|
||||
<?php if ($product['category'] || !empty($product['type_name'])): ?>
|
||||
<div class="product-card-category">
|
||||
<?= htmlspecialchars($product['category'] ?? '') ?>
|
||||
<?php if (!empty($product['type_name'])): ?>
|
||||
<?= $product['category'] ? ' · ' : '' ?><?= htmlspecialchars($product['type_name']) ?>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<h3 class="product-card-title">
|
||||
<a href="/product.php?id=<?= $product['product_id'] ?>"><?= htmlspecialchars($product['name']) ?></a>
|
||||
|
||||
Reference in New Issue
Block a user