`;
@@ -227,6 +223,9 @@ function clearFilters() {
}
applyFilters();
+ if (window.innerWidth < 992) {
+ closeFilterDrawer();
+ }
}
function setupInfiniteScroll() {
@@ -314,3 +313,20 @@ document.addEventListener('DOMContentLoaded', () => {
}
});
});
+
+// ─── Mobile filter drawer ────────────────────────────────────────────────────
+function openFilterDrawer() {
+ const col = document.getElementById('filterCol');
+ const backdrop = document.getElementById('filterBackdrop');
+ if (col) col.classList.add('is-open');
+ if (backdrop) backdrop.classList.add('is-visible');
+ document.body.classList.add('filter-drawer-open');
+}
+
+function closeFilterDrawer() {
+ const col = document.getElementById('filterCol');
+ const backdrop = document.getElementById('filterBackdrop');
+ if (col) col.classList.remove('is-open');
+ if (backdrop) backdrop.classList.remove('is-visible');
+ document.body.classList.remove('filter-drawer-open');
+}
diff --git a/src/public/js/wishlist.js b/src/public/js/wishlist.js
index 3f94c3b..3456521 100644
--- a/src/public/js/wishlist.js
+++ b/src/public/js/wishlist.js
@@ -20,18 +20,20 @@ function removeItemFromDOM(productId) {
el.remove();
}
- // If no more items, swap list area with the empty-state message
- const remaining = document.querySelectorAll('.wishlist-item');
+ // If no more items, swap list area with the modern empty-state message
+ const remaining = document.querySelectorAll('[id^="wishlist-item-"]');
if (remaining.length === 0) {
- const container = document.querySelector('.container.my-4');
+ const container = document.querySelector('.container.px-lg-5');
if (container) {
container.innerHTML = `
-
-
Your wishlist is empty.
-
Browse the shop to add items!
+
+
+
+
+
+
Your wishlist is empty
+
Looks like you haven't added anything to your wishlist yet.
+
Explore Products
`;
}
@@ -133,7 +135,7 @@ async function moveAllToCart() {
btn.textContent = 'Moving…';
}
- const items = [...document.querySelectorAll('.wishlist-item')];
+ const items = [...document.querySelectorAll('[id^="wishlist-item-"]')];
let movedCount = 0;
let failedCount = 0;
@@ -142,9 +144,9 @@ async function moveAllToCart() {
const productId = item.id.replace('wishlist-item-', '');
// Skip out-of-stock items (button is hidden, but guard here too)
- if (item.querySelector('.badge.bg-danger')) {
+ if (item.querySelector('.product-card.is-out-of-stock')) {
failedCount += 1;
- continue; // eslint-disable-line no-continue
+ continue;
}
/* eslint-disable no-await-in-loop */
diff --git a/src/routes/userRoutes.js b/src/routes/userRoutes.js
index 2a8235c..27ff4c0 100644
--- a/src/routes/userRoutes.js
+++ b/src/routes/userRoutes.js
@@ -57,7 +57,7 @@ router.get('/signup', (req, res) => {
title: 'Sign Up',
header: 'partials/header',
viewName: 'users/signup',
- activePage: 'home',
+ activePage: 'signup',
isAdmin: false,
});
});
@@ -82,7 +82,7 @@ router.get('/login', (req, res) => {
title: 'Login',
header: 'partials/header',
viewName: 'users/login',
- activePage: 'home',
+ activePage: 'login',
isAdmin: false,
});
});
@@ -102,7 +102,7 @@ router.get('/login/forgot-password', (req, res) => {
title: 'Login',
header: 'partials/header',
viewName: 'users/forgotPassword',
- activePage: 'home',
+ activePage: 'login',
isAdmin: false,
});
});
@@ -120,7 +120,7 @@ router.post('/forgot-password', authLimiter, async (req, res) => {
title: 'Login',
header: 'partials/header',
viewName: 'users/resetPassword',
- activePage: 'home',
+ activePage: 'login',
isAdmin: false,
});
} catch (err) {
diff --git a/src/views/404.ejs b/src/views/404.ejs
index 5481575..12438fd 100644
--- a/src/views/404.ejs
+++ b/src/views/404.ejs
@@ -4,6 +4,7 @@
<%= title %>
+
@@ -20,9 +21,11 @@
<% } %>
diff --git a/src/views/admin/categoryManagement.ejs b/src/views/admin/categoryManagement.ejs
index 3fbbe4d..a64d16d 100644
--- a/src/views/admin/categoryManagement.ejs
+++ b/src/views/admin/categoryManagement.ejs
@@ -132,7 +132,7 @@