Simplified cart dropdown footer to exactly match wishlist layout: - Removed cart summary (Subtotal display) - Removed 'Proceed to Checkout' button - Kept only 'Continue Shopping' button with btn-outline style Cart and wishlist footers now have identical layout and styling. Files updated: - shop.html - contact.html - product.html - about.html
1254 lines
37 KiB
HTML
1254 lines
37 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
<meta name="description" content="Shop all products - Sky Art Shop" />
|
|
<title>Shop - Sky Art Shop</title>
|
|
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
|
<link
|
|
href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;600;700&family=Inter:wght@400;500;600;700&family=Poppins:wght@600;700;800&display=swap"
|
|
rel="stylesheet"
|
|
/>
|
|
<link
|
|
rel="stylesheet"
|
|
href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css"
|
|
/>
|
|
<link rel="stylesheet" href="/assets/css/theme-colors.css" />
|
|
<link rel="stylesheet" href="/assets/css/main.css?v=1735692100" />
|
|
<link rel="stylesheet" href="/assets/css/navbar.css?v=1767233028" />
|
|
<link rel="stylesheet" href="/assets/css/page-overrides.css?v=1736790001" />
|
|
<link rel="stylesheet" href="/assets/css/cart-wishlist.css" />
|
|
<link rel="stylesheet" href="/assets/css/shopping.css" />
|
|
<link rel="stylesheet" href="/assets/css/responsive.css" />
|
|
<link
|
|
rel="stylesheet"
|
|
href="/assets/css/navbar-mobile-fix.css?v=1736790000"
|
|
/>
|
|
<style>
|
|
/* Body Reset */
|
|
body {
|
|
margin: 0;
|
|
padding: 0;
|
|
background-color: #ffebeb;
|
|
min-height: 100vh;
|
|
}
|
|
|
|
/* Sticky Banner Container */
|
|
.sticky-banner-wrapper {
|
|
position: sticky;
|
|
top: 0;
|
|
z-index: 1000;
|
|
background: #ffd0d0;
|
|
}
|
|
|
|
/* Override navbar position when inside sticky wrapper */
|
|
.sticky-banner-wrapper .modern-navbar {
|
|
position: relative;
|
|
box-shadow: none;
|
|
}
|
|
|
|
/* Shipping Banner */
|
|
.shipping-banner {
|
|
background: linear-gradient(135deg, #f6ccde 0%, #fcb1d8 100%);
|
|
color: #202023;
|
|
text-align: center;
|
|
padding: 12px 0;
|
|
font-size: 14px;
|
|
font-weight: 500;
|
|
}
|
|
|
|
/* Utility Bar - Combined Header and Search */
|
|
.utility-bar {
|
|
background: #ffd0d0;
|
|
padding: 24px 0;
|
|
border-bottom: 1px solid #fcb1d8;
|
|
}
|
|
|
|
.utility-bar-content {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
gap: 40px;
|
|
}
|
|
|
|
.utility-bar-left {
|
|
flex: 1;
|
|
max-width: 500px;
|
|
}
|
|
|
|
.utility-bar-left h1 {
|
|
font-family: "Roboto", sans-serif;
|
|
font-size: 28px;
|
|
font-weight: 700;
|
|
color: #202023;
|
|
margin: 0 0 8px 0;
|
|
line-height: 1.2;
|
|
}
|
|
|
|
.utility-bar-left p {
|
|
font-family: "Roboto", sans-serif;
|
|
font-size: 15px;
|
|
font-weight: 400;
|
|
color: #202023;
|
|
margin: 0;
|
|
line-height: 1.5;
|
|
}
|
|
|
|
.utility-bar-right {
|
|
flex: 0 0 450px;
|
|
}
|
|
|
|
.search-container {
|
|
position: relative;
|
|
width: 100%;
|
|
}
|
|
|
|
.search-container input {
|
|
width: 100%;
|
|
padding: 14px 60px 14px 20px;
|
|
border: 2px solid #ffd0d0;
|
|
border-radius: 50px;
|
|
font-family: "Roboto", sans-serif;
|
|
font-size: 15px;
|
|
transition: all 0.3s;
|
|
background: white;
|
|
color: #202023;
|
|
}
|
|
|
|
.search-container input:focus {
|
|
outline: none;
|
|
border-color: #fcb1d8;
|
|
box-shadow: 0 0 0 3px rgba(252, 177, 216, 0.2);
|
|
}
|
|
|
|
.search-container button {
|
|
position: absolute;
|
|
right: 5px;
|
|
top: 50%;
|
|
transform: translateY(-50%);
|
|
background: #fcb1d8;
|
|
color: #202023;
|
|
border: none;
|
|
padding: 10px 24px;
|
|
border-radius: 50px;
|
|
cursor: pointer;
|
|
font-family: "Roboto", sans-serif;
|
|
font-weight: 600;
|
|
font-size: 14px;
|
|
transition: background 0.3s;
|
|
}
|
|
|
|
.search-container button:hover {
|
|
background: #f6ccde;
|
|
}
|
|
|
|
/* Shop Page Container Override */
|
|
body .container {
|
|
max-width: 1400px;
|
|
padding: 0 40px;
|
|
}
|
|
|
|
/* Shop Page Container Override - Extend to more screen width */
|
|
body .container {
|
|
max-width: 1400px;
|
|
padding: 0 40px;
|
|
}
|
|
|
|
/* Category Chips */
|
|
.categories-section {
|
|
padding: 20px 0;
|
|
background: #ffebeb;
|
|
border-bottom: 1px solid #ffd0d0;
|
|
}
|
|
|
|
.category-chips {
|
|
display: flex;
|
|
gap: 12px;
|
|
flex-wrap: wrap;
|
|
}
|
|
|
|
.category-chip {
|
|
padding: 10px 24px;
|
|
background: white;
|
|
border: 2px solid #ffd0d0;
|
|
border-radius: 50px;
|
|
cursor: pointer;
|
|
font-weight: 500;
|
|
color: #202023;
|
|
transition: all 0.3s;
|
|
font-size: 14px;
|
|
}
|
|
|
|
.category-chip:hover {
|
|
border-color: #fcb1d8;
|
|
color: #fcb1d8;
|
|
transform: translateY(-2px);
|
|
}
|
|
|
|
.category-chip.active {
|
|
background: #fcb1d8;
|
|
border-color: #fcb1d8;
|
|
color: #202023;
|
|
}
|
|
|
|
/* Products Grid */
|
|
.shop-main {
|
|
min-height: 400px;
|
|
}
|
|
|
|
.shop-toolbar {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
margin-bottom: 30px;
|
|
flex-wrap: wrap;
|
|
gap: 16px;
|
|
}
|
|
|
|
.results-count {
|
|
font-family: "Roboto", sans-serif;
|
|
font-size: 16px;
|
|
color: #2d3436;
|
|
font-weight: 500;
|
|
}
|
|
|
|
.filter-select {
|
|
padding: 10px 16px;
|
|
border: 1px solid #e1e8ed;
|
|
border-radius: 8px;
|
|
font-family: "Roboto", sans-serif;
|
|
font-size: 14px;
|
|
background: white;
|
|
cursor: pointer;
|
|
transition: all 0.3s;
|
|
}
|
|
|
|
.filter-select:focus {
|
|
outline: none;
|
|
border-color: #ff6b6b;
|
|
}
|
|
|
|
.products-grid {
|
|
display: grid;
|
|
grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
|
|
gap: 20px;
|
|
margin-bottom: 40px;
|
|
}
|
|
|
|
body .product-card {
|
|
background: white;
|
|
border: 1px solid #ffd0d0;
|
|
border-radius: 12px;
|
|
overflow: hidden !important;
|
|
transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
|
|
position: relative;
|
|
display: flex !important;
|
|
flex-direction: column !important;
|
|
box-shadow: 0 2px 8px rgba(252, 177, 216, 0.15);
|
|
}
|
|
|
|
.product-card:hover {
|
|
transform: translateY(-8px);
|
|
box-shadow: 0 8px 20px rgba(252, 177, 216, 0.3);
|
|
border-color: #fcb1d8;
|
|
}
|
|
|
|
.product-badges {
|
|
position: absolute;
|
|
top: 12px;
|
|
left: 12px;
|
|
z-index: 10;
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 6px;
|
|
}
|
|
|
|
.badge-featured {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: 3px;
|
|
padding: 5px 10px;
|
|
background: #fcb1d8;
|
|
color: #202023;
|
|
border-radius: 6px;
|
|
font-size: 10px;
|
|
font-weight: 600;
|
|
box-shadow: 0 2px 4px rgba(252, 177, 216, 0.4);
|
|
}
|
|
|
|
.badge-bestseller {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: 3px;
|
|
padding: 5px 10px;
|
|
background: #f6ccde;
|
|
color: #202023;
|
|
border-radius: 6px;
|
|
font-size: 10px;
|
|
font-weight: 600;
|
|
box-shadow: 0 2px 4px rgba(252, 177, 216, 0.4);
|
|
}
|
|
|
|
.product-link {
|
|
display: block;
|
|
text-decoration: none;
|
|
color: inherit;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.product-image {
|
|
width: 100%;
|
|
height: 220px;
|
|
overflow: hidden;
|
|
background: #f8f9fa;
|
|
flex-shrink: 0;
|
|
position: relative;
|
|
}
|
|
|
|
.product-image img {
|
|
width: 100%;
|
|
height: 100%;
|
|
object-fit: cover;
|
|
transition: transform 0.3s;
|
|
}
|
|
|
|
.product-card:hover .product-image img {
|
|
transform: scale(1.05);
|
|
}
|
|
|
|
body .product-card h3 {
|
|
font-family: "Roboto", sans-serif;
|
|
font-size: 15px;
|
|
font-weight: 600;
|
|
color: #1a1a1a !important;
|
|
margin: 0 0 6px 0;
|
|
line-height: 1.4;
|
|
display: block !important;
|
|
visibility: visible !important;
|
|
opacity: 1 !important;
|
|
height: auto !important;
|
|
overflow: visible !important;
|
|
position: static !important;
|
|
}
|
|
|
|
/* Product Title Link - Make entire title clickable */
|
|
.product-title-link {
|
|
text-decoration: none !important;
|
|
color: #202023 !important;
|
|
display: block !important;
|
|
cursor: pointer !important;
|
|
transition: color 0.3s ease;
|
|
position: relative;
|
|
z-index: 10;
|
|
}
|
|
|
|
.product-title-link:hover {
|
|
color: #fcb1d8 !important;
|
|
}
|
|
|
|
.product-title-link h3 {
|
|
color: inherit;
|
|
transition: color 0.3s ease;
|
|
margin: 0 0 8px 0;
|
|
pointer-events: none;
|
|
}
|
|
|
|
.product-title-link:hover h3 {
|
|
color: #fcb1d8 !important;
|
|
}
|
|
|
|
body .product-info {
|
|
padding: 16px;
|
|
background: white;
|
|
display: block !important;
|
|
visibility: visible !important;
|
|
opacity: 1 !important;
|
|
height: auto !important;
|
|
overflow: visible !important;
|
|
min-height: 120px;
|
|
position: relative !important;
|
|
transform: none !important;
|
|
transition: none !important;
|
|
flex-grow: 1;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.product-actions {
|
|
display: flex;
|
|
gap: 0.5rem;
|
|
padding: 0 14px 14px;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
body .product-description {
|
|
font-family: "Roboto", sans-serif;
|
|
font-size: 13px;
|
|
color: #6b7280 !important;
|
|
margin: 0 0 8px 0;
|
|
line-height: 1.5;
|
|
display: block !important;
|
|
visibility: visible !important;
|
|
opacity: 1 !important;
|
|
height: auto !important;
|
|
position: static !important;
|
|
}
|
|
|
|
.product-category {
|
|
font-family: "Roboto", sans-serif;
|
|
font-size: 12px;
|
|
color: #6b7280 !important;
|
|
margin: 0 0 10px 0;
|
|
display: flex !important;
|
|
align-items: center;
|
|
gap: 6px;
|
|
visibility: visible !important;
|
|
opacity: 1 !important;
|
|
height: auto !important;
|
|
}
|
|
|
|
.product-category i {
|
|
font-size: 14px;
|
|
}
|
|
|
|
body .product-footer {
|
|
display: flex !important;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
visibility: visible !important;
|
|
opacity: 1 !important;
|
|
height: auto !important;
|
|
position: static !important;
|
|
}
|
|
|
|
body .product-card .price {
|
|
font-family: "Roboto", sans-serif;
|
|
font-size: 18px;
|
|
font-weight: 700;
|
|
color: #6b46c1 !important;
|
|
margin: 0;
|
|
display: block !important;
|
|
visibility: visible !important;
|
|
opacity: 1 !important;
|
|
height: auto !important;
|
|
position: static !important;
|
|
}
|
|
|
|
.stock-status {
|
|
font-family: "Roboto", sans-serif;
|
|
font-size: 12px;
|
|
font-weight: 500;
|
|
margin: 0;
|
|
display: flex !important;
|
|
align-items: center;
|
|
gap: 4px;
|
|
visibility: visible !important;
|
|
}
|
|
|
|
.stock-status.in-stock {
|
|
color: #10b981 !important;
|
|
}
|
|
|
|
.stock-status.out-of-stock {
|
|
color: #ef4444 !important;
|
|
}
|
|
|
|
.stock-status i {
|
|
font-size: 14px;
|
|
}
|
|
|
|
.product-color-badge {
|
|
display: inline-block;
|
|
padding: 4px 12px;
|
|
background: #f8f9fa;
|
|
border-radius: 12px;
|
|
font-size: 12px;
|
|
color: #636e72;
|
|
margin: 0 16px 12px;
|
|
}
|
|
|
|
.btn {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
padding: 8px 16px;
|
|
border: none;
|
|
border-radius: 8px;
|
|
font-family: "Roboto", sans-serif;
|
|
font-size: 14px;
|
|
font-weight: 500;
|
|
cursor: pointer;
|
|
transition: all 0.3s;
|
|
}
|
|
|
|
.btn-small {
|
|
padding: 8px 12px;
|
|
}
|
|
|
|
.btn-icon {
|
|
background: #f8f9fa;
|
|
color: #636e72;
|
|
border: 1px solid #e1e8ed;
|
|
}
|
|
|
|
.btn-icon:hover {
|
|
background: #ff6b6b;
|
|
color: white;
|
|
border-color: #ff6b6b;
|
|
}
|
|
|
|
#noProducts {
|
|
text-align: center;
|
|
padding: 60px 20px;
|
|
font-family: "Roboto", sans-serif;
|
|
font-size: 16px;
|
|
color: #636e72;
|
|
}
|
|
|
|
/* Notification Animations */
|
|
@keyframes slideIn {
|
|
from {
|
|
transform: translateX(400px);
|
|
opacity: 0;
|
|
}
|
|
to {
|
|
transform: translateX(0);
|
|
opacity: 1;
|
|
}
|
|
}
|
|
|
|
@keyframes slideOut {
|
|
from {
|
|
transform: translateX(0);
|
|
opacity: 1;
|
|
}
|
|
to {
|
|
transform: translateX(400px);
|
|
opacity: 0;
|
|
}
|
|
}
|
|
|
|
@media (max-width: 1200px) {
|
|
body .container {
|
|
max-width: 100%;
|
|
padding: 0 30px;
|
|
}
|
|
|
|
.products-grid {
|
|
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
|
|
gap: 18px;
|
|
}
|
|
}
|
|
|
|
@media (max-width: 968px) {
|
|
body .container {
|
|
padding: 0 20px;
|
|
}
|
|
|
|
.products-grid {
|
|
grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
|
|
gap: 14px;
|
|
}
|
|
|
|
.product-image {
|
|
height: 180px;
|
|
}
|
|
|
|
.utility-bar-content {
|
|
flex-direction: column;
|
|
gap: 20px;
|
|
}
|
|
|
|
.utility-bar-left {
|
|
max-width: 100%;
|
|
text-align: center;
|
|
}
|
|
|
|
.utility-bar-left h1 {
|
|
font-size: 24px;
|
|
}
|
|
|
|
.utility-bar-left p {
|
|
font-size: 14px;
|
|
}
|
|
|
|
.utility-bar-right {
|
|
flex: 1;
|
|
width: 100%;
|
|
}
|
|
|
|
.category-chips {
|
|
overflow-x: auto;
|
|
flex-wrap: nowrap;
|
|
padding-bottom: 10px;
|
|
}
|
|
|
|
.category-chip {
|
|
white-space: nowrap;
|
|
}
|
|
}
|
|
</style>
|
|
<link rel="stylesheet" href="/assets/css/theme-colors.css" />
|
|
</head>
|
|
<body>
|
|
<!-- Sticky Banner Wrapper -->
|
|
<div class="sticky-banner-wrapper">
|
|
<!-- Modern Navigation -->
|
|
<nav class="modern-navbar">
|
|
<div class="navbar-wrapper">
|
|
<div class="navbar-brand">
|
|
<a href="/home" class="brand-link">
|
|
<img
|
|
src="/uploads/cat-png-1767324141436-368259437.png"
|
|
alt="Sky Art Shop Logo"
|
|
class="brand-logo"
|
|
/>
|
|
<span class="brand-name">Sky' Art Shop</span>
|
|
</a>
|
|
</div>
|
|
|
|
<div class="navbar-menu">
|
|
<ul class="nav-menu-list">
|
|
<li class="nav-item">
|
|
<a href="/home" class="nav-link">Home</a>
|
|
</li>
|
|
<li class="nav-item">
|
|
<a href="/shop" class="nav-link active">Shop</a>
|
|
</li>
|
|
<li class="nav-item">
|
|
<a href="/portfolio" class="nav-link">Portfolio</a>
|
|
</li>
|
|
<li class="nav-item">
|
|
<a href="/about" class="nav-link">About</a>
|
|
</li>
|
|
<li class="nav-item">
|
|
<a href="/blog" class="nav-link">Blog</a>
|
|
</li>
|
|
<li class="nav-item">
|
|
<a href="/contact" class="nav-link">Contact</a>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
|
|
<div class="navbar-actions">
|
|
<div class="action-item wishlist-dropdown-wrapper">
|
|
<button
|
|
class="action-btn"
|
|
id="wishlistToggle"
|
|
aria-label="Wishlist"
|
|
>
|
|
<i class="bi bi-heart"></i>
|
|
<span class="action-badge" id="wishlistCount">0</span>
|
|
</button>
|
|
<div class="action-dropdown wishlist-dropdown" id="wishlistPanel">
|
|
<div class="dropdown-head">
|
|
<h3>My Wishlist</h3>
|
|
<button class="dropdown-close" id="wishlistClose">
|
|
<i class="bi bi-x-lg"></i>
|
|
</button>
|
|
</div>
|
|
<div class="dropdown-body" id="wishlistContent">
|
|
<p class="empty-state">Your wishlist is empty</p>
|
|
</div>
|
|
<div class="dropdown-foot">
|
|
<a href="/shop" class="btn-outline">Continue Shopping</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="action-item cart-dropdown-wrapper">
|
|
<button
|
|
class="action-btn"
|
|
id="cartToggle"
|
|
aria-label="Shopping Cart"
|
|
>
|
|
<i class="bi bi-cart3"></i>
|
|
<span class="action-badge" id="cartCount">0</span>
|
|
</button>
|
|
<div class="action-dropdown cart-dropdown" id="cartPanel">
|
|
<div class="dropdown-head">
|
|
<h3>Shopping Cart</h3>
|
|
<button class="dropdown-close" id="cartClose">
|
|
<i class="bi bi-x-lg"></i>
|
|
</button>
|
|
</div>
|
|
<div class="dropdown-body" id="cartContent">
|
|
<p class="empty-state">Your cart is empty</p>
|
|
</div>
|
|
<div class="dropdown-foot">
|
|
<a href="/shop" class="btn-outline">Continue Shopping</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<button
|
|
class="mobile-toggle"
|
|
id="mobileMenuToggle"
|
|
aria-label="Menu"
|
|
>
|
|
<span class="toggle-line"></span>
|
|
<span class="toggle-line"></span>
|
|
<span class="toggle-line"></span>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="mobile-menu" id="mobileMenu">
|
|
<div class="mobile-menu-header">
|
|
<span class="mobile-brand">Sky' Art Shop</span>
|
|
<button class="mobile-close" id="mobileMenuClose">
|
|
<i class="bi bi-x-lg"></i>
|
|
</button>
|
|
</div>
|
|
<ul class="mobile-menu-list">
|
|
<li><a href="/home" class="mobile-link">Home</a></li>
|
|
<li><a href="/shop" class="mobile-link">Shop</a></li>
|
|
<li><a href="/portfolio" class="mobile-link">Portfolio</a></li>
|
|
<li><a href="/about" class="mobile-link">About</a></li>
|
|
<li><a href="/blog" class="mobile-link">Blog</a></li>
|
|
<li><a href="/contact" class="mobile-link">Contact</a></li>
|
|
</ul>
|
|
</div>
|
|
</nav>
|
|
|
|
<!-- Shipping Banner -->
|
|
<div class="shipping-banner">⚡ Free shipping on orders over $50</div>
|
|
</div>
|
|
|
|
<!-- Utility Bar: Header + Search -->
|
|
<section class="utility-bar">
|
|
<div class="container">
|
|
<div class="utility-bar-content">
|
|
<!-- Left: Title and Description -->
|
|
<div class="utility-bar-left">
|
|
<h1>Shop All Products</h1>
|
|
<p>
|
|
Discover unique art pieces and creative supplies for your next
|
|
project
|
|
</p>
|
|
</div>
|
|
|
|
<!-- Right: Search Bar -->
|
|
<div class="utility-bar-right">
|
|
<div class="search-container">
|
|
<input
|
|
type="search"
|
|
placeholder="Search products..."
|
|
id="productSearch"
|
|
/>
|
|
<button type="button">Search</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- Categories -->
|
|
<section class="categories-section">
|
|
<div class="container">
|
|
<div class="category-chips">
|
|
<!-- Categories will be dynamically loaded from API -->
|
|
<button class="category-chip active" data-category="all">
|
|
All Products
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- Shop Main Content -->
|
|
<section class="shop-main" style="padding: 40px 0">
|
|
<div class="container">
|
|
<div class="shop-layout">
|
|
<!-- Products Grid (Main Content) -->
|
|
<div class="shop-content" style="width: 100%">
|
|
<div class="shop-toolbar">
|
|
<p class="results-count" id="resultsCount">Loading products...</p>
|
|
|
|
<!-- Sort Dropdown -->
|
|
<select
|
|
class="filter-select"
|
|
id="sortSelect"
|
|
style="
|
|
padding: 8px 12px;
|
|
border: 1px solid #e1e8ed;
|
|
border-radius: 8px;
|
|
"
|
|
>
|
|
<option value="featured">Featured</option>
|
|
<option value="newest">Newest</option>
|
|
<option value="price-low">Price: Low to High</option>
|
|
<option value="price-high">Price: High to Low</option>
|
|
<option value="name">Name: A to Z</option>
|
|
</select>
|
|
</div>
|
|
|
|
<div class="products-grid" id="productsGrid">
|
|
<!-- Products will be loaded here -->
|
|
</div>
|
|
|
|
<div
|
|
id="noProducts"
|
|
style="display: none; text-align: center; padding: 40px"
|
|
>
|
|
<p>No products found.</p>
|
|
</div>
|
|
|
|
<div class="pagination" id="pagination">
|
|
<!-- Pagination will be inserted here -->
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- Footer -->
|
|
<footer class="footer">
|
|
<div class="container">
|
|
<div class="footer-grid">
|
|
<div class="footer-col">
|
|
<h3 class="footer-title">Sky Art Shop</h3>
|
|
<p class="footer-text">
|
|
Your destination for unique art pieces and creative supplies.
|
|
</p>
|
|
<div class="social-links">
|
|
<a href="#" class="social-link"><i class="bi bi-facebook"></i></a>
|
|
<a href="#" class="social-link"
|
|
><i class="bi bi-instagram"></i
|
|
></a>
|
|
<a href="#" class="social-link"><i class="bi bi-twitter"></i></a>
|
|
<a href="#" class="social-link"
|
|
><i class="bi bi-pinterest"></i
|
|
></a>
|
|
</div>
|
|
</div>
|
|
<div class="footer-col">
|
|
<h4 class="footer-heading">Shop</h4>
|
|
<ul class="footer-links">
|
|
<li><a href="/shop">All Products</a></li>
|
|
<li><a href="/shop?category=paintings">Paintings</a></li>
|
|
<li><a href="/shop?category=prints">Prints</a></li>
|
|
<li><a href="/shop?category=supplies">Art Supplies</a></li>
|
|
</ul>
|
|
</div>
|
|
<div class="footer-col">
|
|
<h4 class="footer-heading">About</h4>
|
|
<ul class="footer-links">
|
|
<li><a href="/about">Our Story</a></li>
|
|
<li><a href="/portfolio">Portfolio</a></li>
|
|
<li><a href="/blog">Blog</a></li>
|
|
<li><a href="/contact">Contact</a></li>
|
|
</ul>
|
|
</div>
|
|
<div class="footer-col">
|
|
<h4 class="footer-heading">Customer Service</h4>
|
|
<ul class="footer-links">
|
|
<li><a href="/shipping-info">Shipping Info</a></li>
|
|
<li><a href="/returns">Returns</a></li>
|
|
<li><a href="/faq">FAQ</a></li>
|
|
<li><a href="/privacy">Privacy Policy</a></li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
<div class="footer-bottom">
|
|
<p>© 2025 Sky Art Shop. All rights reserved.</p>
|
|
</div>
|
|
</div>
|
|
</footer>
|
|
|
|
<!-- Core Scripts -->
|
|
<script src="/assets/js/api-cache.js"></script>
|
|
<script src="/assets/js/shop-system.js"></script>
|
|
<script src="/assets/js/cart.js"></script>
|
|
<script src="/assets/js/api-client.js"></script>
|
|
<script src="/assets/js/notifications.js"></script>
|
|
<script src="/assets/js/page-transitions.js?v=1767228800"></script>
|
|
<script src="/assets/js/back-button-control.js?v=1767228687"></script>
|
|
<script src="/assets/js/navigation.js?v=1767228687"></script>
|
|
<script>
|
|
// Mobile Menu Toggle (Same as other pages)
|
|
const mobileMenuToggle = document.getElementById("mobileMenuToggle");
|
|
const mobileMenu = document.getElementById("mobileMenu");
|
|
const mobileMenuClose = document.getElementById("mobileMenuClose");
|
|
|
|
if (mobileMenuToggle) {
|
|
mobileMenuToggle.addEventListener("click", () => {
|
|
mobileMenu.classList.toggle("active");
|
|
});
|
|
}
|
|
|
|
if (mobileMenuClose) {
|
|
mobileMenuClose.addEventListener("click", () => {
|
|
mobileMenu.classList.remove("active");
|
|
});
|
|
}
|
|
|
|
// Load and Display Products
|
|
let allProducts = [];
|
|
let filteredProducts = [];
|
|
let currentCategory = "all";
|
|
|
|
// Load Categories from API
|
|
async function loadCategories() {
|
|
try {
|
|
console.log("Shop page: Loading categories from API...");
|
|
const response = await fetch("/api/categories");
|
|
const data = await response.json();
|
|
console.log("Shop page: Categories API response:", data);
|
|
|
|
if (data.success && data.categories) {
|
|
displayCategoryChips(data.categories);
|
|
}
|
|
} catch (error) {
|
|
console.error("Error loading categories:", error);
|
|
}
|
|
}
|
|
|
|
// Display Category Filter Chips
|
|
function displayCategoryChips(categories) {
|
|
const categoryChipsContainer =
|
|
document.querySelector(".category-chips");
|
|
if (!categoryChipsContainer) return;
|
|
|
|
// Build HTML for all categories
|
|
let chipsHTML =
|
|
'<button class="category-chip active" data-category="all">All Products</button>';
|
|
|
|
categories.forEach((category) => {
|
|
const categorySlug = category.toLowerCase().replace(/\s+/g, "-");
|
|
chipsHTML += `<button class="category-chip" data-category="${categorySlug}">${category}</button>`;
|
|
});
|
|
|
|
categoryChipsContainer.innerHTML = chipsHTML;
|
|
|
|
// Attach event listeners to new chips
|
|
attachCategoryListeners();
|
|
}
|
|
|
|
// Attach Category Click Listeners
|
|
function attachCategoryListeners() {
|
|
document.querySelectorAll(".category-chip").forEach((chip) => {
|
|
chip.addEventListener("click", function () {
|
|
document
|
|
.querySelectorAll(".category-chip")
|
|
.forEach((c) => c.classList.remove("active"));
|
|
this.classList.add("active");
|
|
|
|
currentCategory = this.dataset.category;
|
|
|
|
if (currentCategory === "all") {
|
|
filteredProducts = allProducts;
|
|
} else {
|
|
filteredProducts = allProducts.filter(
|
|
(p) =>
|
|
p.category?.toLowerCase().replace(/\s+/g, "-") ===
|
|
currentCategory
|
|
);
|
|
}
|
|
|
|
applySorting();
|
|
});
|
|
});
|
|
}
|
|
|
|
async function loadProducts() {
|
|
try {
|
|
console.log("Shop page: Loading products from API...");
|
|
const response = await window.apiCache.fetch("/api/products");
|
|
const data = await response.json();
|
|
console.log("Shop page: API response:", data);
|
|
|
|
if (data.success) {
|
|
allProducts = data.products || data.data || [];
|
|
filteredProducts = allProducts;
|
|
console.log("Shop page: Loaded", allProducts.length, "products");
|
|
|
|
// Apply initial sort (featured by default)
|
|
applySorting();
|
|
} else {
|
|
console.error("Shop page: API returned success=false");
|
|
}
|
|
} catch (error) {
|
|
console.error("Error loading products:", error);
|
|
document.getElementById("resultsCount").textContent =
|
|
"Error loading products";
|
|
}
|
|
}
|
|
|
|
// Apply current sorting to filtered products
|
|
function applySorting() {
|
|
const sortBy =
|
|
document.getElementById("sortSelect")?.value || "featured";
|
|
let sorted = [...filteredProducts];
|
|
|
|
switch (sortBy) {
|
|
case "featured":
|
|
// Sort by featured first, then by best seller, then by newest
|
|
sorted.sort((a, b) => {
|
|
// Featured products first
|
|
if (a.isfeatured && !b.isfeatured) return -1;
|
|
if (!a.isfeatured && b.isfeatured) return 1;
|
|
|
|
// Then best sellers
|
|
if (a.isbestseller && !b.isbestseller) return -1;
|
|
if (!a.isbestseller && b.isbestseller) return 1;
|
|
|
|
// Then by newest
|
|
return new Date(b.createdat) - new Date(a.createdat);
|
|
});
|
|
break;
|
|
case "price-low":
|
|
sorted.sort((a, b) => parseFloat(a.price) - parseFloat(b.price));
|
|
break;
|
|
case "price-high":
|
|
sorted.sort((a, b) => parseFloat(b.price) - parseFloat(a.price));
|
|
break;
|
|
case "name":
|
|
sorted.sort((a, b) => a.name.localeCompare(b.name));
|
|
break;
|
|
case "newest":
|
|
sorted.sort(
|
|
(a, b) => new Date(b.createdat) - new Date(a.createdat)
|
|
);
|
|
break;
|
|
}
|
|
|
|
displayProducts(sorted);
|
|
updateResultsCount(sorted.length);
|
|
}
|
|
|
|
function displayProducts(products) {
|
|
const grid = document.getElementById("productsGrid");
|
|
const noProducts = document.getElementById("noProducts");
|
|
|
|
console.log(
|
|
"Shop page: displayProducts called with",
|
|
products.length,
|
|
"products"
|
|
);
|
|
|
|
if (products.length === 0) {
|
|
grid.style.display = "none";
|
|
noProducts.style.display = "block";
|
|
console.log("Shop page: No products to display");
|
|
return;
|
|
}
|
|
|
|
grid.style.display = "grid";
|
|
noProducts.style.display = "none";
|
|
|
|
console.log("Shop page: Rendering product cards...");
|
|
|
|
grid.innerHTML = products
|
|
.map((product) => {
|
|
// Get the primary image from images array
|
|
let productImage = "/assets/images/placeholder.svg";
|
|
if (
|
|
product.images &&
|
|
Array.isArray(product.images) &&
|
|
product.images.length > 0
|
|
) {
|
|
// Find primary image or use first one
|
|
const primaryImg = product.images.find((img) => img.is_primary);
|
|
productImage = primaryImg
|
|
? primaryImg.image_url
|
|
: product.images[0].image_url;
|
|
} else if (product.imageurl) {
|
|
// Fallback to old imageurl field
|
|
productImage = product.imageurl;
|
|
}
|
|
|
|
// Build badges HTML
|
|
let badges = "";
|
|
if (product.isfeatured) {
|
|
badges +=
|
|
'<span class="badge-featured"><i class="bi bi-star-fill"></i> Featured</span>';
|
|
}
|
|
if (product.isbestseller) {
|
|
badges +=
|
|
'<span class="badge-bestseller"><i class="bi bi-trophy-fill"></i> Best Seller</span>';
|
|
}
|
|
|
|
return `
|
|
<div class="product-card">
|
|
${badges ? `<div class="product-badges">${badges}</div>` : ""}
|
|
<a href="/product?id=${product.id}" class="product-link">
|
|
<div class="product-image">
|
|
<img src="${productImage}" alt="${
|
|
product.name
|
|
}" loading="lazy" onerror="this.src='/assets/images/placeholder.svg'" />
|
|
</div>
|
|
</a>
|
|
<div class="product-info">
|
|
<a href="/product?id=${product.id}" class="product-title-link">
|
|
<h3>${product.name}</h3>
|
|
</a>
|
|
${
|
|
product.shortdescription || product.description
|
|
? `<p class="product-description">${
|
|
product.shortdescription ||
|
|
(product.description
|
|
? product.description
|
|
.replace(/<[^>]*>/g, "")
|
|
.substring(0, 60)
|
|
: "")
|
|
}</p>`
|
|
: ""
|
|
}
|
|
${
|
|
product.category
|
|
? `<p class="product-category"><i class="bi bi-tag-fill"></i> ${product.category}</p>`
|
|
: ""
|
|
}
|
|
<div class="product-footer">
|
|
<p class="price">$${parseFloat(product.price).toFixed(2)}</p>
|
|
${
|
|
product.stockquantity > 0
|
|
? '<p class="stock-status in-stock"><i class="bi bi-check-circle-fill"></i> In Stock</p>'
|
|
: '<p class="stock-status out-of-stock"><i class="bi bi-x-circle-fill"></i> Out of Stock</p>'
|
|
}
|
|
</div>
|
|
</div>
|
|
<div class="product-actions">
|
|
<button class="btn btn-small btn-icon"
|
|
onclick="event.stopPropagation(); addToWishlist('${
|
|
product.id
|
|
}', '${product.name.replace(/'/g, "\\'")}', ${
|
|
product.price
|
|
}, '${productImage.replace(/'/g, "\\'")}')"
|
|
aria-label="Add to wishlist">
|
|
<i class="bi bi-heart"></i>
|
|
</button>
|
|
<button class="btn btn-small btn-icon"
|
|
onclick="event.stopPropagation(); addToCart('${
|
|
product.id
|
|
}', '${product.name.replace(/'/g, "\\'")}', ${
|
|
product.price
|
|
}, '${productImage.replace(/'/g, "\\'")}')"
|
|
aria-label="Add to cart"
|
|
${
|
|
product.stockquantity <= 0
|
|
? 'disabled style="opacity: 0.5; cursor: not-allowed;"'
|
|
: ""
|
|
}>
|
|
<i class="bi bi-cart-plus"></i>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
`;
|
|
})
|
|
.join("");
|
|
}
|
|
|
|
function updateResultsCount(count) {
|
|
document.getElementById(
|
|
"resultsCount"
|
|
).textContent = `Showing ${count} product${count !== 1 ? "s" : ""}`;
|
|
}
|
|
|
|
// Category Filter - Now handled by attachCategoryListeners()
|
|
|
|
// Sort
|
|
document
|
|
.getElementById("sortSelect")
|
|
?.addEventListener("change", function () {
|
|
applySorting();
|
|
});
|
|
|
|
// Price Filter
|
|
document
|
|
.getElementById("applyPriceFilter")
|
|
?.addEventListener("click", function () {
|
|
const min =
|
|
parseFloat(document.getElementById("priceMin").value) || 0;
|
|
const max =
|
|
parseFloat(document.getElementById("priceMax").value) || Infinity;
|
|
|
|
filteredProducts = allProducts.filter((p) => {
|
|
const price = parseFloat(p.price);
|
|
return price >= min && price <= max;
|
|
});
|
|
|
|
applySorting();
|
|
});
|
|
|
|
// Simple Cart and Wishlist Functions
|
|
function addToCart(productId, name, price, imageurl) {
|
|
window.ShopSystem.addToCart(
|
|
{
|
|
id: String(productId),
|
|
name,
|
|
price: parseFloat(price),
|
|
imageurl,
|
|
},
|
|
1
|
|
);
|
|
}
|
|
|
|
function addToWishlist(productId, name, price, imageurl) {
|
|
window.ShopSystem.addToWishlist({
|
|
id: String(productId),
|
|
name,
|
|
price: parseFloat(price),
|
|
imageurl,
|
|
});
|
|
}
|
|
|
|
function showNotification(message, type = "info") {
|
|
const notification = document.createElement("div");
|
|
notification.className = `notification notification-${type}`;
|
|
notification.textContent = message;
|
|
notification.style.cssText = `
|
|
position: fixed;
|
|
top: 80px;
|
|
right: 20px;
|
|
background: ${
|
|
type === "success"
|
|
? "#10b981"
|
|
: type === "error"
|
|
? "#ef4444"
|
|
: "#3b82f6"
|
|
};
|
|
color: white;
|
|
padding: 12px 24px;
|
|
border-radius: 8px;
|
|
box-shadow: 0 4px 12px rgba(0,0,0,0.15);
|
|
z-index: 10000;
|
|
animation: slideIn 0.3s ease;
|
|
`;
|
|
document.body.appendChild(notification);
|
|
|
|
setTimeout(() => {
|
|
notification.style.animation = "slideOut 0.3s ease";
|
|
setTimeout(() => notification.remove(), 300);
|
|
}, 3000);
|
|
}
|
|
|
|
// Search functionality
|
|
document
|
|
.getElementById("productSearch")
|
|
?.addEventListener("input", function (e) {
|
|
const searchTerm = e.target.value.toLowerCase();
|
|
|
|
if (searchTerm === "") {
|
|
filteredProducts = allProducts;
|
|
} else {
|
|
filteredProducts = allProducts.filter(
|
|
(p) =>
|
|
p.name.toLowerCase().includes(searchTerm) ||
|
|
(p.description &&
|
|
p.description.toLowerCase().includes(searchTerm))
|
|
);
|
|
}
|
|
|
|
displayProducts(filteredProducts);
|
|
updateResultsCount(filteredProducts.length);
|
|
});
|
|
|
|
// Initialize
|
|
loadCategories();
|
|
loadProducts();
|
|
</script>
|
|
</body>
|
|
</html>
|