diff --git a/assets/images/prod-catalog.jpg b/assets/images/prod-catalog.jpg new file mode 100644 index 0000000..1fe7884 Binary files /dev/null and b/assets/images/prod-catalog.jpg differ diff --git a/data/products.json b/data/products.json index 5e1f3c7..006faab 100644 --- a/data/products.json +++ b/data/products.json @@ -8,8 +8,13 @@ "alt": "Modesty Panels", "category": "training-tables", "modelNo": "SE001", - "tags": ["Chair", "Seating", "Office", "Ergonomic"], - "sizes": ["XS", "S", "M", "L", "XL"], + "sizes": [ + "XS", + "S", + "M", + "L", + "XL" + ], "colors": [ { "name": "Black", @@ -30,9 +35,6 @@ "selectedSize": "M", "selectedColor": "Black", "price": 250, - "originalPrice": 250, - "rating": "4.4", - "reviews": 88, "inStock": true, "images": [ "assets/images/products/categories/training-tables/modesty-panels/training-desk-4-1000x1000.jpg", @@ -52,7 +54,6 @@ "coveredInWarranty": "Manufacturing defects", "notCoveredInWarranty": "Wear and tear not covered" }, - "reviewsCount": 88, "galleryPairs": [ "assets/images/products/categories/training-tables/modesty-panels/training-desk-4-1000x1000.jpg", "assets/images/products/categories/training-tables/modesty-panels/Student-set-up-300x300.jpg" @@ -80,8 +81,11 @@ "alt": "Domino", "category": "training-tables", "modelNo": "TA002", - "tags": ["Table", "Workstation", "Office", "Conference"], - "sizes": ["S", "M", "L"], + "sizes": [ + "S", + "M", + "L" + ], "colors": [ { "name": "Natural", @@ -102,9 +106,6 @@ "selectedSize": "L", "selectedColor": "Natural", "price": 899.99, - "originalPrice": 899.99, - "rating": "4.9", - "reviews": 69, "inStock": true, "images": [ "assets/images/products/categories/training-tables/domino/Thumbnail_Desks-Tables_Training_Tables_Domino-Nesting_Table_Categories_Gallery_04_600x600px-1.webp", @@ -124,7 +125,6 @@ "coveredInWarranty": "Manufacturing defects", "notCoveredInWarranty": "Wear and tear not covered" }, - "reviewsCount": 69, "galleryPairs": [ "assets/images/products/categories/training-tables/domino/Thumbnail_Desks-Tables_Training_Tables_Domino-Nesting_Table_Categories_Gallery_04_600x600px-1.webp", "assets/images/products/categories/training-tables/domino/Thumbnail_Desks-Tables_Training_Tables_Domino-Nesting_Table_Categories_Gallery_03_600x600px-1.webp" @@ -152,8 +152,11 @@ "alt": "Slim", "category": "training-tables", "modelNo": "ST003", - "tags": ["Storage", "Cabinet", "Office", "Organization"], - "sizes": ["M", "L", "XL"], + "sizes": [ + "M", + "L", + "XL" + ], "colors": [ { "name": "White", @@ -228,8 +231,11 @@ "price": 599.99, "inStock": true, "modelNo": "ST004", - "tags": ["Storage", "Cabinet", "Office", "Organization"], - "sizes": ["M", "L", "XL"], + "sizes": [ + "M", + "L", + "XL" + ], "colors": [ { "name": "White", @@ -301,8 +307,13 @@ "price": 299.99, "inStock": true, "modelNo": "SE005", - "tags": ["Chair", "Seating", "Office", "Ergonomic"], - "sizes": ["XS", "S", "M", "L", "XL"], + "sizes": [ + "XS", + "S", + "M", + "L", + "XL" + ], "colors": [ { "name": "Black", @@ -374,8 +385,13 @@ "price": 349.99, "inStock": true, "modelNo": "SC006", - "tags": ["Screen", "Privacy", "Office", "Acoustic"], - "sizes": ["XS", "S", "M", "L", "XL"], + "sizes": [ + "XS", + "S", + "M", + "L", + "XL" + ], "colors": [ { "name": "Black", @@ -446,8 +462,11 @@ "price": 899.99, "inStock": true, "modelNo": "SC007", - "tags": ["Screen", "Privacy", "Acoustic", "Technology"], - "sizes": ["S", "M", "L"], + "sizes": [ + "S", + "M", + "L" + ], "colors": [ { "name": "Natural", @@ -517,8 +536,11 @@ "price": 599.99, "inStock": true, "modelNo": "SC008", - "tags": ["Screen", "Desk", "Privacy", "Technology"], - "sizes": ["M", "L", "XL"], + "sizes": [ + "M", + "L", + "XL" + ], "colors": [ { "name": "White", @@ -589,8 +611,13 @@ "price": 299.99, "inStock": true, "modelNo": "SC009", - "tags": ["Screen", "Privacy", "Minimalist", "Office"], - "sizes": ["XS", "S", "M", "L", "XL"], + "sizes": [ + "XS", + "S", + "M", + "L", + "XL" + ], "colors": [ { "name": "Black", @@ -661,8 +688,13 @@ "price": 349.99, "inStock": true, "modelNo": "ED010", - "tags": ["Desk", "Executive", "Office", "Premium"], - "sizes": ["XS", "S", "M", "L", "XL"], + "sizes": [ + "XS", + "S", + "M", + "L", + "XL" + ], "colors": [ { "name": "Black", @@ -733,8 +765,11 @@ "price": 899.99, "inStock": true, "modelNo": "ED011", - "tags": ["Desk", "Executive", "Elegant", "Premium"], - "sizes": ["S", "M", "L"], + "sizes": [ + "S", + "M", + "L" + ], "colors": [ { "name": "Natural", @@ -805,8 +840,11 @@ "price": 599.99, "inStock": true, "modelNo": "ED012", - "tags": ["Desk", "Executive", "Sustainable", "Eco-friendly"], - "sizes": ["M", "L", "XL"], + "sizes": [ + "M", + "L", + "XL" + ], "colors": [ { "name": "White", @@ -878,8 +916,13 @@ "price": 299.99, "inStock": true, "modelNo": "ED013", - "tags": ["Desk", "Executive", "L-Shape", "Versatile"], - "sizes": ["XS", "S", "M", "L", "XL"], + "sizes": [ + "XS", + "S", + "M", + "L", + "XL" + ], "colors": [ { "name": "Black", @@ -951,8 +994,13 @@ "price": 349.99, "inStock": true, "modelNo": "ED014", - "tags": ["Desk", "Executive", "Premium", "Professional"], - "sizes": ["XS", "S", "M", "L", "XL"], + "sizes": [ + "XS", + "S", + "M", + "L", + "XL" + ], "colors": [ { "name": "Black", @@ -1024,8 +1072,11 @@ "price": 899.99, "inStock": true, "modelNo": "CC015", - "tags": ["Chair", "Conference", "Classical", "Traditional"], - "sizes": ["S", "M", "L"], + "sizes": [ + "S", + "M", + "L" + ], "colors": [ { "name": "Natural", @@ -1099,8 +1150,11 @@ "price": 599.99, "inStock": true, "modelNo": "CC016", - "tags": ["Chair", "Conference", "Modern", "Contemporary"], - "sizes": ["M", "L", "XL"], + "sizes": [ + "M", + "L", + "XL" + ], "colors": [ { "name": "White", @@ -1172,8 +1226,11 @@ "price": 499.99, "inStock": true, "modelNo": "CC017", - "tags": ["Chair", "Conference", "Executive", "Premium"], - "sizes": ["S", "M", "L"], + "sizes": [ + "S", + "M", + "L" + ], "colors": [ { "name": "Natural", @@ -1245,8 +1302,11 @@ "price": 259.99, "inStock": true, "modelNo": "CC018", - "tags": ["Chair", "Conference", "Swivel", "Professional"], - "sizes": ["M", "L", "XL"], + "sizes": [ + "M", + "L", + "XL" + ], "colors": [ { "name": "White", @@ -1318,8 +1378,10 @@ "price": 1299.99, "inStock": true, "modelNo": "CC019", - "tags": ["Chair", "Conference", "Swivel", "Professional"], - "sizes": ["M", "L"], + "sizes": [ + "M", + "L" + ], "colors": [ { "name": "Blue", @@ -1391,8 +1453,10 @@ "price": 399.99, "inStock": true, "modelNo": "CC020", - "tags": ["Chair", "Conference", "Flexible", "Professional"], - "sizes": ["M", "L"], + "sizes": [ + "M", + "L" + ], "colors": [ { "name": "Blue", @@ -1465,8 +1529,11 @@ "price": 149.99, "inStock": true, "modelNo": "CC021", - "tags": ["Chair", "Conference", "Professional", "Comfortable"], - "sizes": ["M", "L", "XL"], + "sizes": [ + "M", + "L", + "XL" + ], "colors": [ { "name": "White", @@ -1538,8 +1605,13 @@ "price": 349.99, "inStock": true, "modelNo": "CC022", - "tags": ["Chair", "Conference", "Premium", "Luxury"], - "sizes": ["XS", "S", "M", "L", "XL"], + "sizes": [ + "XS", + "S", + "M", + "L", + "XL" + ], "colors": [ { "name": "Black", @@ -1606,8 +1678,13 @@ "price": 399.99, "inStock": true, "modelNo": "VC023", - "tags": ["Chair", "Visitors", "Reception", "Guest"], - "sizes": ["XS", "S", "M", "L", "XL"], + "sizes": [ + "XS", + "S", + "M", + "L", + "XL" + ], "colors": [ { "name": "Black", @@ -1679,8 +1756,11 @@ "price": 1099.99, "inStock": true, "modelNo": "VC024", - "tags": ["Chair", "Visitors", "Reception", "Guest"], - "sizes": ["S", "M", "L"], + "sizes": [ + "S", + "M", + "L" + ], "colors": [ { "name": "Natural", @@ -1752,8 +1832,11 @@ "price": 2199.99, "inStock": true, "modelNo": "VC025", - "tags": ["Chair", "Visitors", "Reception", "Guest"], - "sizes": ["S", "M", "L"], + "sizes": [ + "S", + "M", + "L" + ], "colors": [ { "name": "Natural", @@ -1827,8 +1910,10 @@ "price": 299.99, "inStock": true, "modelNo": "VC026", - "tags": ["Chair", "Visitors", "Reception", "Guest"], - "sizes": ["M", "L"], + "sizes": [ + "M", + "L" + ], "colors": [ { "name": "Black", @@ -1893,8 +1978,10 @@ "price": 199.99, "inStock": true, "modelNo": "VC027", - "tags": ["Chair", "Visitors", "Reception", "Guest"], - "sizes": ["M", "L"], + "sizes": [ + "M", + "L" + ], "colors": [ { "name": "Brown", @@ -1959,8 +2046,11 @@ "price": 249.99, "inStock": true, "modelNo": "VC028", - "tags": ["Chair", "Visitors", "Reception", "Guest"], - "sizes": ["M", "L", "XL"], + "sizes": [ + "M", + "L", + "XL" + ], "colors": [ { "name": "White", @@ -2024,8 +2114,10 @@ "price": 599.99, "inStock": true, "modelNo": "SS029", - "tags": ["Soft Seating", "Lounge", "Comfort", "Modern"], - "sizes": ["M", "L"], + "sizes": [ + "M", + "L" + ], "colors": [ { "name": "Grey", @@ -2092,8 +2184,10 @@ "price": 899.99, "inStock": true, "modelNo": "SS030", - "tags": ["Soft Seating", "Lounge", "Luxury", "Executive"], - "sizes": ["L", "XL"], + "sizes": [ + "L", + "XL" + ], "colors": [ { "name": "Black", @@ -2160,8 +2254,10 @@ "price": 499.99, "inStock": true, "modelNo": "SS031", - "tags": ["Soft Seating", "Break Area", "Casual", "Comfort"], - "sizes": ["M", "L"], + "sizes": [ + "M", + "L" + ], "colors": [ { "name": "Green", @@ -2229,8 +2325,10 @@ "price": 699.99, "inStock": true, "modelNo": "SS032", - "tags": ["Soft Seating", "Reception", "Elegant", "Formal"], - "sizes": ["M", "L"], + "sizes": [ + "M", + "L" + ], "colors": [ { "name": "Blue", @@ -2298,8 +2396,10 @@ "price": 549.99, "inStock": true, "modelNo": "SS033", - "tags": ["Soft Seating", "Modern", "Contemporary", "Sleek"], - "sizes": ["M", "L"], + "sizes": [ + "M", + "L" + ], "colors": [ { "name": "White", @@ -2364,8 +2464,10 @@ "price": 399.99, "inStock": true, "modelNo": "SS034", - "tags": ["Soft Seating", "Creative", "Playful", "Vibrant"], - "sizes": ["S", "M"], + "sizes": [ + "S", + "M" + ], "colors": [ { "name": "Yellow", @@ -2430,8 +2532,10 @@ "price": 649.99, "inStock": true, "modelNo": "SS035", - "tags": ["Soft Seating", "Elegant", "Coastal", "Sophisticated"], - "sizes": ["M", "L"], + "sizes": [ + "M", + "L" + ], "colors": [ { "name": "Navy", @@ -2502,8 +2606,10 @@ "price": 749.99, "inStock": true, "modelNo": "SS036", - "tags": ["Soft Seating", "Collaborative", "Meeting", "Interactive"], - "sizes": ["L", "XL"], + "sizes": [ + "L", + "XL" + ], "colors": [ { "name": "Orange", @@ -2567,8 +2673,10 @@ "price": 999.99, "inStock": true, "modelNo": "SS037", - "tags": ["Soft Seating", "Premium", "Luxury", "Exclusive"], - "sizes": ["L", "XL"], + "sizes": [ + "L", + "XL" + ], "colors": [ { "name": "Gold", @@ -2637,8 +2745,10 @@ "price": 599.99, "inStock": true, "modelNo": "SS038", - "tags": ["Soft Seating", "Classic", "Traditional", "Timeless"], - "sizes": ["M", "L"], + "sizes": [ + "M", + "L" + ], "colors": [ { "name": "Brown", @@ -2707,8 +2817,10 @@ "price": 299.99, "inStock": true, "modelNo": "BS039", - "tags": ["Barstool", "Reception", "Casual", "Modern"], - "sizes": ["M", "L"], + "sizes": [ + "M", + "L" + ], "colors": [ { "name": "Black", @@ -2774,8 +2886,10 @@ "price": 399.99, "inStock": true, "modelNo": "BS040", - "tags": ["Barstool", "Cafe", "Elegant", "Stylish"], - "sizes": ["M", "L"], + "sizes": [ + "M", + "L" + ], "colors": [ { "name": "Anthracite", @@ -2840,8 +2954,10 @@ "price": 249.99, "inStock": true, "modelNo": "BS041", - "tags": ["Barstool", "Casual", "Dining", "Comfort"], - "sizes": ["M", "L"], + "sizes": [ + "M", + "L" + ], "colors": [ { "name": "Brown", @@ -2907,8 +3023,10 @@ "price": 549.99, "inStock": true, "modelNo": "BS042", - "tags": ["Barstool", "Premium", "Luxury", "Reception"], - "sizes": ["M", "L"], + "sizes": [ + "M", + "L" + ], "colors": [ { "name": "Chrome", @@ -2973,8 +3091,10 @@ "price": 349.99, "inStock": true, "modelNo": "BS043", - "tags": ["Barstool", "Versatile", "Flexible", "Modern"], - "sizes": ["M", "L"], + "sizes": [ + "M", + "L" + ], "colors": [ { "name": "Black", @@ -3039,8 +3159,10 @@ "price": 899.99, "inStock": true, "modelNo": "WS044", - "tags": ["Work Station", "Compact", "Individual", "Efficient"], - "sizes": ["M", "L"], + "sizes": [ + "M", + "L" + ], "colors": [ { "name": "White", @@ -3105,8 +3227,10 @@ "price": 1299.99, "inStock": true, "modelNo": "WS045", - "tags": ["Work Station", "Versatile", "Collaborative", "Flexible"], - "sizes": ["L", "XL"], + "sizes": [ + "L", + "XL" + ], "colors": [ { "name": "White", @@ -3174,8 +3298,10 @@ "price": 1099.99, "inStock": true, "modelNo": "WS046", - "tags": ["Work Station", "Modern", "Contemporary", "Sleek"], - "sizes": ["M", "L"], + "sizes": [ + "M", + "L" + ], "colors": [ { "name": "White", @@ -3241,8 +3367,10 @@ "price": 1899.99, "inStock": true, "modelNo": "WS047", - "tags": ["Work Station", "Collaborative", "Team", "Shared"], - "sizes": ["L", "XL"], + "sizes": [ + "L", + "XL" + ], "colors": [ { "name": "White", @@ -3307,8 +3435,10 @@ "price": 699.99, "inStock": true, "modelNo": "WS048", - "tags": ["Work Station", "Lightweight", "Home Office", "Portable"], - "sizes": ["M", "L"], + "sizes": [ + "M", + "L" + ], "colors": [ { "name": "White", @@ -3373,8 +3503,10 @@ "price": 1599.99, "inStock": true, "modelNo": "WS049", - "tags": ["Work Station", "Professional", "Executive", "Premium"], - "sizes": ["L", "XL"], + "sizes": [ + "L", + "XL" + ], "colors": [ { "name": "White", @@ -3439,8 +3571,10 @@ "price": 1299.99, "inStock": true, "modelNo": "ETC050", - "tags": ["Executive", "Task Chair", "Premium", "Ergonomic"], - "sizes": ["M", "L"], + "sizes": [ + "M", + "L" + ], "colors": [ { "name": "Black", @@ -3505,8 +3639,10 @@ "price": 1199.99, "inStock": true, "modelNo": "ETC051", - "tags": ["Executive", "Task Chair", "Elegant", "Professional"], - "sizes": ["M", "L"], + "sizes": [ + "M", + "L" + ], "colors": [ { "name": "Black", @@ -3570,8 +3706,10 @@ "price": 1499.99, "inStock": true, "modelNo": "ETC052", - "tags": ["Executive", "Task Chair", "Luxury", "Premium"], - "sizes": ["M", "L"], + "sizes": [ + "M", + "L" + ], "colors": [ { "name": "Black", @@ -3636,8 +3774,10 @@ "price": 1099.99, "inStock": true, "modelNo": "ETC053", - "tags": ["Executive", "Task Chair", "Professional", "Ergonomic"], - "sizes": ["M", "L"], + "sizes": [ + "M", + "L" + ], "colors": [ { "name": "Amber", @@ -3704,8 +3844,10 @@ "price": 199.99, "inStock": true, "modelNo": "CC054", - "tags": ["Canteen Chair", "Dining", "Comfortable", "Modern"], - "sizes": ["M", "L"], + "sizes": [ + "M", + "L" + ], "colors": [ { "name": "White", @@ -3771,8 +3913,10 @@ "price": 249.99, "inStock": true, "modelNo": "CC055", - "tags": ["Canteen Chair", "Premium", "Upscale", "Luxury"], - "sizes": ["M", "L"], + "sizes": [ + "M", + "L" + ], "colors": [ { "name": "Black", @@ -3837,8 +3981,10 @@ "price": 189.99, "inStock": true, "modelNo": "CC056", - "tags": ["Canteen Chair", "Classic", "Traditional", "Timeless"], - "sizes": ["M", "L"], + "sizes": [ + "M", + "L" + ], "colors": [ { "name": "Brown", @@ -3908,8 +4054,10 @@ "price": 229.99, "inStock": true, "modelNo": "CC057", - "tags": ["Canteen Chair", "Elegant", "Upscale", "Sophisticated"], - "sizes": ["M", "L"], + "sizes": [ + "M", + "L" + ], "colors": [ { "name": "Anthracite", @@ -3974,8 +4122,10 @@ "price": 209.99, "inStock": true, "modelNo": "CC058", - "tags": ["Canteen Chair", "Vibrant", "Colorful", "Creative"], - "sizes": ["M", "L"], + "sizes": [ + "M", + "L" + ], "colors": [ { "name": "Green", @@ -4043,8 +4193,10 @@ "price": 219.99, "inStock": true, "modelNo": "CC059", - "tags": ["Canteen Chair", "Durable", "High-Traffic", "Robust"], - "sizes": ["M", "L"], + "sizes": [ + "M", + "L" + ], "colors": [ { "name": "Black", @@ -4110,8 +4262,10 @@ "price": 279.99, "inStock": true, "modelNo": "CC060", - "tags": ["Canteen Chair", "Premium", "Luxury", "High-End"], - "sizes": ["M", "L"], + "sizes": [ + "M", + "L" + ], "colors": [ { "name": "Anthracite", @@ -4176,8 +4330,10 @@ "price": 399.99, "inStock": true, "modelNo": "ST061", - "tags": ["Storage", "Lockers", "Security", "Organization"], - "sizes": ["M", "L"], + "sizes": [ + "M", + "L" + ], "colors": [ { "name": "White", @@ -4249,8 +4405,10 @@ "price": 299.99, "inStock": true, "modelNo": "ST062", - "tags": ["Storage", "Melamine", "Durable", "Modern"], - "sizes": ["M", "L"], + "sizes": [ + "M", + "L" + ], "colors": [ { "name": "White", @@ -4317,8 +4475,10 @@ "price": 449.99, "inStock": true, "modelNo": "ST063", - "tags": ["Storage", "Metal", "Robust", "Industrial"], - "sizes": ["M", "L"], + "sizes": [ + "M", + "L" + ], "colors": [ { "name": "Gray", @@ -4383,8 +4543,10 @@ "price": 199.99, "inStock": true, "modelNo": "TC064", - "tags": ["Training Chair", "Comfortable", "Educational", "Ergonomic"], - "sizes": ["M", "L"], + "sizes": [ + "M", + "L" + ], "colors": [ { "name": "Black", @@ -4451,8 +4613,10 @@ "price": 219.99, "inStock": true, "modelNo": "TC065", - "tags": ["Training Chair", "Dynamic", "Active Learning", "Responsive"], - "sizes": ["M", "L"], + "sizes": [ + "M", + "L" + ], "colors": [ { "name": "Black", @@ -4517,8 +4681,10 @@ "price": 249.99, "inStock": true, "modelNo": "TC066", - "tags": ["Training Chair", "Iconic", "Professional", "Premium"], - "sizes": ["M", "L"], + "sizes": [ + "M", + "L" + ], "colors": [ { "name": "Black", @@ -4585,8 +4751,10 @@ "price": 189.99, "inStock": true, "modelNo": "TC067", - "tags": ["Training Chair", "Vibrant", "Creative", "Dynamic"], - "sizes": ["M", "L"], + "sizes": [ + "M", + "L" + ], "colors": [ { "name": "Blue", @@ -4656,8 +4824,10 @@ "price": 229.99, "inStock": true, "modelNo": "TC068", - "tags": ["Training Chair", "Flexible", "Adaptable", "Responsive"], - "sizes": ["M", "L"], + "sizes": [ + "M", + "L" + ], "colors": [ { "name": "Black", @@ -4722,8 +4892,10 @@ "price": 279.99, "inStock": true, "modelNo": "TC069", - "tags": ["Training Chair", "Versatile", "Integrated Table", "All-in-One"], - "sizes": ["M", "L"], + "sizes": [ + "M", + "L" + ], "colors": [ { "name": "Black", @@ -4786,8 +4958,10 @@ "price": 329.99, "inStock": true, "modelNo": "TC070", - "tags": ["Task Chair", "Elegant", "Professional", "Sophisticated"], - "sizes": ["M", "L"], + "sizes": [ + "M", + "L" + ], "colors": [ { "name": "Black", @@ -4856,8 +5030,10 @@ "price": 299.99, "inStock": true, "modelNo": "TC071", - "tags": ["Task Chair", "Advanced", "Modern", "Innovative"], - "sizes": ["M", "L"], + "sizes": [ + "M", + "L" + ], "colors": [ { "name": "Black", @@ -4925,8 +5101,10 @@ "price": 259.99, "inStock": true, "modelNo": "TC072", - "tags": ["Task Chair", "Adaptable", "Dynamic", "Responsive"], - "sizes": ["M", "L"], + "sizes": [ + "M", + "L" + ], "colors": [ { "name": "Black", @@ -4994,8 +5172,10 @@ "price": 379.99, "inStock": true, "modelNo": "TC073", - "tags": ["Task Chair", "Premium", "Executive", "Superior"], - "sizes": ["M", "L"], + "sizes": [ + "M", + "L" + ], "colors": [ { "name": "Black", @@ -5062,8 +5242,10 @@ "price": 279.99, "inStock": true, "modelNo": "TC074", - "tags": ["Task Chair", "Connected", "Collaborative", "Ergonomic"], - "sizes": ["M", "L"], + "sizes": [ + "M", + "L" + ], "colors": [ { "name": "Black", @@ -5129,8 +5311,10 @@ "price": 249.99, "inStock": true, "modelNo": "TC075", - "tags": ["Task Chair", "Spacious", "Comfortable", "Generous"], - "sizes": ["M", "L"], + "sizes": [ + "M", + "L" + ], "colors": [ { "name": "Black", @@ -5199,8 +5383,10 @@ "price": 219.99, "inStock": true, "modelNo": "TC076", - "tags": ["Task Chair", "Reliable", "Durable", "Dependable"], - "sizes": ["M", "L"], + "sizes": [ + "M", + "L" + ], "colors": [ { "name": "Black", @@ -5266,8 +5452,11 @@ "price": 899.99, "inStock": true, "modelNo": "MT077", - "tags": ["Meeting Table", "Robust", "Professional", "Durable"], - "sizes": ["M", "L", "XL"], + "sizes": [ + "M", + "L", + "XL" + ], "colors": [ { "name": "White", @@ -5331,8 +5520,11 @@ "price": 799.99, "inStock": true, "modelNo": "MT078", - "tags": ["Meeting Table", "Versatile", "Flexible", "Modular"], - "sizes": ["M", "L", "XL"], + "sizes": [ + "M", + "L", + "XL" + ], "colors": [ { "name": "Brown", @@ -5397,8 +5589,11 @@ "price": 699.99, "inStock": true, "modelNo": "MT079", - "tags": ["Meeting Table", "Dynamic", "Creative", "Unique"], - "sizes": ["M", "L", "XL"], + "sizes": [ + "M", + "L", + "XL" + ], "colors": [ { "name": "Black", @@ -5462,8 +5657,11 @@ "price": 999.99, "inStock": true, "modelNo": "MT080", - "tags": ["Meeting Table", "Modern", "Contemporary", "Sleek"], - "sizes": ["M", "L", "XL"], + "sizes": [ + "M", + "L", + "XL" + ], "colors": [ { "name": "White", @@ -5528,8 +5726,10 @@ "price": 199.99, "inStock": true, "modelNo": "OT081", - "tags": ["Occasional Table", "Laptop", "Versatile", "Adjustable"], - "sizes": ["M", "L"], + "sizes": [ + "M", + "L" + ], "colors": [ { "name": "Black", @@ -5594,8 +5794,10 @@ "price": 299.99, "inStock": true, "modelNo": "OT082", - "tags": ["Occasional Table", "Coffee Table", "Stylish", "Contemporary"], - "sizes": ["M", "L"], + "sizes": [ + "M", + "L" + ], "colors": [ { "name": "Brown", @@ -5660,8 +5862,10 @@ "price": 399.99, "inStock": true, "modelNo": "OT083", - "tags": ["Occasional Table", "Salon", "Elegant", "Technology"], - "sizes": ["M", "L"], + "sizes": [ + "M", + "L" + ], "colors": [ { "name": "White", @@ -5725,8 +5929,10 @@ "price": 249.99, "inStock": true, "modelNo": "OT084", - "tags": ["Occasional Table", "Unique", "Spherical", "Artistic"], - "sizes": ["M", "L"], + "sizes": [ + "M", + "L" + ], "colors": [ { "name": "White", @@ -5788,8 +5994,10 @@ "price": 229.99, "inStock": true, "modelNo": "OT085", - "tags": ["Occasional Table", "Oblong", "Sleek", "Contemporary"], - "sizes": ["M", "L"], + "sizes": [ + "M", + "L" + ], "colors": [ { "name": "Black", @@ -5853,8 +6061,10 @@ "price": 349.99, "inStock": true, "modelNo": "OT086", - "tags": ["Occasional Table", "Elegant", "Sophisticated", "Premium"], - "sizes": ["M", "L"], + "sizes": [ + "M", + "L" + ], "colors": [ { "name": "White", @@ -5921,13 +6131,10 @@ "price": 279.99, "inStock": true, "modelNo": "OT087", - "tags": [ - "Occasional Table", - "Versatile", - "Multi-functional", - "Contemporary" + "sizes": [ + "M", + "L" ], - "sizes": ["M", "L"], "colors": [ { "name": "Brown", @@ -5991,8 +6198,10 @@ "price": 159.99, "inStock": true, "modelNo": "OT088", - "tags": ["Occasional Table", "Tray", "Functional", "Practical"], - "sizes": ["M", "L"], + "sizes": [ + "M", + "L" + ], "colors": [ { "name": "Black", @@ -6130,4 +6339,4 @@ "currentPage": 1, "totalPages": 2 } -} +} \ No newline at end of file diff --git a/product-catalog.html b/product-catalog.html index e8c9974..c8e9091 100644 --- a/product-catalog.html +++ b/product-catalog.html @@ -164,7 +164,7 @@
Product catalog background
- -
- - 1 - -
- + + + diff --git a/scripts/main.js b/scripts/main.js index 5e16c7d..6770421 100644 --- a/scripts/main.js +++ b/scripts/main.js @@ -55,27 +55,6 @@ function initSite() { window.addEventListener("scroll", updateActiveLink); updateActiveLink(); - // Quantity controls on product detail page - (function initQuantityControls() { - const decr = document.getElementById("qty-decr"); - const incr = document.getElementById("qty-incr"); - const valueEl = document.getElementById("qty-value"); - if (!decr || !incr || !valueEl) return; // Not on product detail page - - function parseQty() { - const n = parseInt(valueEl.textContent || "1", 10); - return Number.isFinite(n) && n > 0 ? n : 1; - } - decr.addEventListener("click", () => { - const next = Math.max(1, parseQty() - 1); - valueEl.textContent = String(next); - }); - incr.addEventListener("click", () => { - const next = parseQty() + 1; - valueEl.textContent = String(next); - }); - })(); - // Related products (dynamic) (async function initRelated() { const grid = document.getElementById("related-grid"); @@ -222,56 +201,187 @@ function initSite() { }); }); } +} + +// Image enlargement modal functionality (global) +function addImageEnlargementListeners() { + // Target both main product image AND gallery carousel images + const mainProductImage = document.querySelector( + ".w-full.h-80.md\\:w-\\[500px\\].md\\:h-\\[500px\\] img[data-enlarge-src]" + ); + const galleryImages = document.querySelectorAll( + "#product-gallery-images img[data-enlarge-src]" + ); + const modal = document.getElementById("image-modal"); + const modalImage = document.getElementById("modal-image"); + const modalCloseBtn = document.getElementById("modal-close-btn"); + + console.log("Adding image enlargement listeners..."); + console.log("Found main product image:", !!mainProductImage); + console.log("Found gallery images:", galleryImages.length); + console.log("Modal elements:", { + modal: !!modal, + modalImage: !!modalImage, + modalCloseBtn: !!modalCloseBtn, + }); + + if (!modal || !modalImage || !modalCloseBtn) { + console.log("Modal elements not found, skipping image enlargement setup"); + return; } - // Product detail page functionality + // Add click listener to main product image + if (mainProductImage) { + console.log( + `Adding click listener to main product image:`, + mainProductImage.src + ); + mainProductImage.removeEventListener("click", handleImageClick); + mainProductImage.addEventListener("click", handleImageClick); + } else { + console.log("Main product image not found"); + } + + // Add click listeners to gallery carousel images + galleryImages.forEach((img, index) => { + console.log( + `Adding click listener to gallery image ${index + 1}:`, + img.src + ); + img.removeEventListener("click", handleImageClick); + img.addEventListener("click", handleImageClick); + }); + + function handleImageClick(e) { + console.log("Image clicked!", this.src); + const imageSrc = this.getAttribute("data-enlarge-src"); + const imageAlt = this.getAttribute("alt"); + + console.log("Opening modal with image:", imageSrc); + modalImage.src = imageSrc; + modalImage.alt = imageAlt; + + // Show modal with animation + modal.classList.remove("hidden"); + document.body.style.overflow = "hidden"; // Prevent background scrolling + + // Trigger animation after a brief delay + setTimeout(() => { + modalImage.classList.remove("scale-95"); + modalImage.classList.add("scale-100"); + }, 10); + } + + // Close modal functionality + function closeModal() { + // Animate out + modalImage.classList.remove("scale-100"); + modalImage.classList.add("scale-95"); + + // Hide modal after animation + setTimeout(() => { + modal.classList.add("hidden"); + document.body.style.overflow = ""; // Restore scrolling + }, 300); + } + + modalCloseBtn.addEventListener("click", closeModal); + + // Close modal when clicking outside the image + modal.addEventListener("click", function (e) { + if (e.target === modal) { + closeModal(); + } + }); + + // Close modal with Escape key + document.addEventListener("keydown", function (e) { + if (e.key === "Escape" && !modal.classList.contains("hidden")) { + closeModal(); + } + }); +} + +// Thumbnail click functionality (global) +function addThumbnailClickListeners() { + const thumbnails = document.querySelectorAll("[data-thumbnail-src]"); + const mainImageContainer = document.querySelector( + ".w-full.h-80.md\\:w-\\[500px\\].md\\:h-\\[500px\\]" + ); + + console.log("Adding thumbnail click listeners..."); + console.log("Found thumbnails:", thumbnails.length); + console.log("Main image container:", !!mainImageContainer); + + if (!mainImageContainer) { + console.log("Main image container not found"); + return; + } + + thumbnails.forEach((thumbnail, index) => { + thumbnail.addEventListener("click", function () { + const imageSrc = this.getAttribute("data-thumbnail-src"); + console.log(`Thumbnail ${index + 1} clicked, switching to:`, imageSrc); + + // Update the main product image + const mainImg = mainImageContainer.querySelector("img"); + if (mainImg) { + mainImg.src = imageSrc; + mainImg.setAttribute("data-enlarge-src", imageSrc); + console.log("Main image updated to:", imageSrc); + } + }); + }); +} + +// Product detail page functionality async function initProductDetail() { - console.log("Product detail script running..."); + console.log("Product detail script running..."); console.log("Current URL:", window.location.href); - // Check if we're on the product detail page - const productTitle = document.querySelector("h1"); - if (!productTitle) { - console.log("No h1 found, not on product detail page"); - return; - } + // Check if we're on the product detail page + const productTitle = document.querySelector("h1"); + if (!productTitle) { + console.log("No h1 found, not on product detail page"); + return; + } console.log("Found h1 element:", productTitle); - // Get product ID from URL - const urlParams = new URLSearchParams(window.location.search); - const productId = parseInt(urlParams.get("id")); - console.log("Product ID from URL:", productId); + // Get product ID from URL + const urlParams = new URLSearchParams(window.location.search); + const productId = parseInt(urlParams.get("id")); + console.log("Product ID from URL:", productId); - if (!productId) { - console.log("No product ID found in URL"); + if (!productId) { + console.log("No product ID found in URL"); + return; + } + + try { + // Load product data + const response = await fetch("data/products.json"); + const data = await response.json(); + const product = data.products.find((p) => p.id === productId); + + if (!product) { + console.error("Product not found:", productId); return; } - try { - // Load product data - const response = await fetch("data/products.json"); - const data = await response.json(); - const product = data.products.find((p) => p.id === productId); + console.log("Loading product:", product); - if (!product) { - console.error("Product not found:", productId); - return; - } + // Update page title + document.title = `${product.name} - KHY`; - console.log("Loading product:", product); + // Update the "Product Details" title with the actual product name + const productDetailsTitle = document.getElementById( + "product-details-title" + ); + if (productDetailsTitle) { + productDetailsTitle.textContent = product.name; + } - // Update page title - document.title = `${product.name} - KHY`; - - // Update the "Product Details" title with the actual product name - const productDetailsTitle = document.getElementById( - "product-details-title" - ); - if (productDetailsTitle) { - productDetailsTitle.textContent = product.name; - } - - // Update product title (the main product title, not the breadcrumb) + // Update product title (the main product title, not the breadcrumb) const productTitle = document.getElementById("product-title"); console.log("Product title element:", productTitle); if (productTitle) { @@ -297,10 +407,16 @@ async function initProductDetail() { ${product.alt || product.name} `; console.log("Updated main image to:", product.image); + + // Add image enlargement functionality to the main product image + setTimeout(() => { + addImageEnlargementListeners(); + }, 100); } // Update thumbnail images @@ -313,7 +429,7 @@ async function initProductDetail() { .slice(0, 4) .map( (img, index) => ` -
+
${product.name} ${index + 1} span.textContent === "Model No." + ); + if (modelNoLabel && product.modelNo) { + const modelNoValue = + modelNoLabel.parentElement.querySelector("span:last-child"); + if (modelNoValue) { + modelNoValue.textContent = product.modelNo; } + } - // Update product metadata - find by text content - const allSpans = document.querySelectorAll("span"); - - // Find and update Model No. - const modelNoLabel = Array.from(allSpans).find( - (span) => span.textContent === "Model No." - ); - if (modelNoLabel && product.modelNo) { - const modelNoValue = - modelNoLabel.parentElement.querySelector("span:last-child"); - if (modelNoValue) { - modelNoValue.textContent = product.modelNo; - } - } - - // Find and update Category - const categoryLabel = Array.from(allSpans).find( - (span) => span.textContent === "Category" - ); - if (categoryLabel && product.category) { - const categoryValue = - categoryLabel.parentElement.querySelector("span:last-child"); - if (categoryValue) { - categoryValue.textContent = + // Find and update Category + const categoryLabel = Array.from(allSpans).find( + (span) => span.textContent === "Category" + ); + if (categoryLabel && product.category) { + const categoryValue = + categoryLabel.parentElement.querySelector("span:last-child"); + if (categoryValue) { + categoryValue.textContent = product.category.charAt(0).toUpperCase() + product.category.slice(1); - } } + } - // Find and update Tags - const tagsLabel = Array.from(allSpans).find( - (span) => span.textContent === "Tags" - ); - if (tagsLabel && product.tags) { - const tagsValue = - tagsLabel.parentElement.querySelector("span:last-child"); - if (tagsValue) { - tagsValue.textContent = product.tags.join(", "); - } + + // Find and update Dimensions + const dimensionsLabel = Array.from(allSpans).find( + (span) => span.textContent === "Dimension" + ); + console.log("Dimensions label found:", dimensionsLabel); + console.log("Product dimensions:", product.dimensions); + + if (dimensionsLabel && product.dimensions) { + const dimensionsValue = + dimensionsLabel.parentElement.querySelector("span:last-child"); + console.log("Dimensions value element:", dimensionsValue); + if (dimensionsValue) { + dimensionsValue.textContent = product.dimensions; + console.log("Updated dimensions to:", product.dimensions); } + } - // Find and update Dimensions - const dimensionsLabel = Array.from(allSpans).find( - (span) => span.textContent === "Dimension" - ); - console.log("Dimensions label found:", dimensionsLabel); - console.log("Product dimensions:", product.dimensions); - - if (dimensionsLabel && product.dimensions) { - const dimensionsValue = - dimensionsLabel.parentElement.querySelector("span:last-child"); - console.log("Dimensions value element:", dimensionsValue); - if (dimensionsValue) { - dimensionsValue.textContent = product.dimensions; - console.log("Updated dimensions to:", product.dimensions); - } - } - - // Update description content + // Update description content const descriptionContainer = document.getElementById( "product-description-content" ); @@ -455,15 +563,18 @@ async function initProductDetail() { const galleryBackBtn = document.getElementById("gallery-back-btn"); const galleryNextBtn = document.getElementById("gallery-next-btn"); console.log("Gallery container:", galleryContainer); + console.log("Product galleryPairs:", product.galleryPairs); if (galleryContainer && product.galleryPairs) { // galleryPairs is now a simple array of image paths const allGalleryImages = product.galleryPairs; + console.log("All gallery images:", allGalleryImages); // Store gallery images for carousel window.currentGalleryImages = allGalleryImages; window.currentGalleryIndex = 0; + console.log("About to call renderGalleryCarousel..."); // Render initial gallery view renderGalleryCarousel(); @@ -484,18 +595,35 @@ async function initProductDetail() { } function renderGalleryCarousel() { - if (!window.currentGalleryImages || !galleryContainer) return; + console.log("renderGalleryCarousel called"); + console.log("window.currentGalleryImages:", window.currentGalleryImages); + console.log("galleryContainer:", galleryContainer); + + if (!window.currentGalleryImages || !galleryContainer) { + console.log( + "Early return: missing currentGalleryImages or galleryContainer" + ); + return; + } + + console.log( + "Rendering gallery carousel with", + window.currentGalleryImages.length, + "images" + ); // Handle single image vs multiple images if (window.currentGalleryImages.length === 1) { // Single image - show only one image, hide arrows const image1 = window.currentGalleryImages[0]; + console.log("Rendering single image:", image1); galleryContainer.innerHTML = ` -