Capstone project. I'm ngl it's vibe-coded and it's only here so I can mess around with it
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge pull request #5 from chriskalos/feature/shop-images

Add images to the THREAD store

authored by

Chris and committed by
GitHub
414b1177 15bb3169

+58 -29
testable-apps/shop-app/images/black-evening-dress.png

This is a binary file and will not be displayed.

testable-apps/shop-app/images/black-tshirt.png

This is a binary file and will not be displayed.

testable-apps/shop-app/images/blue-denim-jacket.png

This is a binary file and will not be displayed.

testable-apps/shop-app/images/blue-tshirt.png

This is a binary file and will not be displayed.

testable-apps/shop-app/images/blue-vneck-tshirt.png

This is a binary file and will not be displayed.

testable-apps/shop-app/images/brown-leather-jacket.png

This is a binary file and will not be displayed.

testable-apps/shop-app/images/floral-dress.png

This is a binary file and will not be displayed.

testable-apps/shop-app/images/green-graphic-tshirt.png

This is a binary file and will not be displayed.

testable-apps/shop-app/images/red-tshirt.png

This is a binary file and will not be displayed.

testable-apps/shop-app/images/relaxed-jeans.png

This is a binary file and will not be displayed.

testable-apps/shop-app/images/slim-jeans.png

This is a binary file and will not be displayed.

testable-apps/shop-app/images/white-tshirt.png

This is a binary file and will not be displayed.

+58 -29
testable-apps/shop-app/index.html
··· 321 321 display: flex; 322 322 align-items: center; 323 323 justify-content: center; 324 - font-size: 1.1rem; 325 - font-weight: 600; 326 - color: var(--text-muted); 324 + background: var(--surface-muted); 327 325 position: relative; 328 326 overflow: hidden; 327 + } 328 + 329 + .product-image img { 330 + width: 100%; 331 + height: 100%; 332 + object-fit: contain; 333 + padding: 16px; 334 + display: block; 329 335 } 330 336 331 337 .product-image .product-swatch { ··· 474 480 margin-bottom: 24px; 475 481 position: relative; 476 482 overflow: hidden; 483 + background: var(--surface-muted); 484 + } 485 + 486 + .modal-product-image img { 487 + width: 100%; 488 + height: 100%; 489 + object-fit: contain; 490 + padding: 18px; 491 + display: block; 477 492 } 478 493 479 494 .modal-product-image .product-swatch { ··· 683 698 flex-shrink: 0; 684 699 position: relative; 685 700 overflow: hidden; 701 + background: var(--surface-muted); 702 + } 703 + 704 + .cart-item-image img { 705 + width: 100%; 706 + height: 100%; 707 + object-fit: contain; 708 + padding: 6px; 709 + display: block; 686 710 } 687 711 688 712 .cart-item-image .product-swatch { ··· 1002 1026 }; 1003 1027 1004 1028 const products = [ 1005 - { id: 1, name: 'Classic T-Shirt', color: 'Blue', price: 29.99, category: 't-shirts', rating: 4.5 }, 1006 - { id: 2, name: 'Classic T-Shirt', color: 'Red', price: 29.99, category: 't-shirts', rating: 4.3 }, 1007 - { id: 3, name: 'Classic T-Shirt', color: 'Black', price: 29.99, category: 't-shirts', rating: 4.8 }, 1008 - { id: 4, name: 'Premium T-Shirt', color: 'White', price: 39.99, category: 't-shirts', rating: 4.6 }, 1009 - { id: 5, name: 'Slim Fit Jeans', color: 'Dark Blue', price: 59.99, category: 'jeans', rating: 4.4 }, 1010 - { id: 6, name: 'Relaxed Jeans', color: 'Light Blue', price: 54.99, category: 'jeans', rating: 4.2 }, 1011 - { id: 7, name: 'Summer Dress', color: 'Floral', price: 49.99, category: 'dresses', rating: 4.7 }, 1012 - { id: 8, name: 'Evening Dress', color: 'Black', price: 79.99, category: 'dresses', rating: 4.9 }, 1013 - { id: 9, name: 'Denim Jacket', color: 'Blue', price: 89.99, category: 'jackets', rating: 4.5 }, 1014 - { id: 10, name: 'Leather Jacket', color: 'Brown', price: 149.99, category: 'jackets', rating: 4.8 }, 1015 - { id: 11, name: 'Graphic T-Shirt', color: 'Green', price: 34.99, category: 't-shirts', rating: 4.1 }, 1016 - { id: 12, name: 'V-Neck T-Shirt', color: 'Navy', price: 32.99, category: 't-shirts', rating: 4.4 }, 1029 + { id: 1, name: 'Classic T-Shirt', color: 'Blue', price: 29.99, category: 't-shirts', rating: 4.5, image: 'images/blue-tshirt.png' }, 1030 + { id: 2, name: 'Classic T-Shirt', color: 'Red', price: 29.99, category: 't-shirts', rating: 4.3, image: 'images/red-tshirt.png' }, 1031 + { id: 3, name: 'Classic T-Shirt', color: 'Black', price: 29.99, category: 't-shirts', rating: 4.8, image: 'images/black-tshirt.png' }, 1032 + { id: 4, name: 'Premium T-Shirt', color: 'White', price: 39.99, category: 't-shirts', rating: 4.6, image: 'images/white-tshirt.png' }, 1033 + { id: 5, name: 'Slim Fit Jeans', color: 'Dark Blue', price: 59.99, category: 'jeans', rating: 4.4, image: 'images/slim-jeans.png' }, 1034 + { id: 6, name: 'Relaxed Jeans', color: 'Light Blue', price: 54.99, category: 'jeans', rating: 4.2, image: 'images/relaxed-jeans.png' }, 1035 + { id: 7, name: 'Summer Dress', color: 'Floral', price: 49.99, category: 'dresses', rating: 4.7, image: 'images/floral-dress.png' }, 1036 + { id: 8, name: 'Evening Dress', color: 'Black', price: 79.99, category: 'dresses', rating: 4.9, image: 'images/black-evening-dress.png' }, 1037 + { id: 9, name: 'Denim Jacket', color: 'Blue', price: 89.99, category: 'jackets', rating: 4.5, image: 'images/blue-denim-jacket.png' }, 1038 + { id: 10, name: 'Leather Jacket', color: 'Brown', price: 149.99, category: 'jackets', rating: 4.8, image: 'images/brown-leather-jacket.png' }, 1039 + { id: 11, name: 'Graphic T-Shirt', color: 'Green', price: 34.99, category: 't-shirts', rating: 4.1, image: 'images/green-graphic-tshirt.png' }, 1040 + { id: 12, name: 'V-Neck T-Shirt', color: 'Navy', price: 32.99, category: 't-shirts', rating: 4.4, image: 'images/blue-vneck-tshirt.png' }, 1017 1041 ]; 1018 1042 1019 1043 let cart = []; ··· 1035 1059 return swatch; 1036 1060 } 1037 1061 1062 + function renderProductImage(product, className = '') { 1063 + const swatch = getSwatchStyle(product.color); 1064 + const label = categoryLabels[product.category] || product.category; 1065 + const imageClass = className ? ` class="${className}"` : ''; 1066 + 1067 + if (product.image) { 1068 + return `<img${imageClass} src="${product.image}" alt="${product.color} ${product.name}" loading="lazy">`; 1069 + } 1070 + 1071 + return ` 1072 + <div class="product-swatch" style="background:${swatch.bg}"></div> 1073 + <span class="product-label">${label}</span> 1074 + `; 1075 + } 1076 + 1038 1077 function renderProducts(filter = 'all') { 1039 1078 const filtered = filter === 'all' 1040 1079 ? products 1041 1080 : products.filter(p => p.category === filter); 1042 1081 1043 1082 productGrid.innerHTML = filtered.map(product => { 1044 - const swatch = getSwatchStyle(product.color); 1045 - const label = categoryLabels[product.category] || product.category; 1046 1083 const fullStars = Math.floor(product.rating); 1047 1084 const stars = '★'.repeat(fullStars) + '☆'.repeat(5 - fullStars); 1048 1085 return ` 1049 1086 <div class="product-card" data-id="${product.id}"> 1050 1087 <div class="product-image"> 1051 - <div class="product-swatch" style="background:${swatch.bg}"></div> 1052 - <span class="product-label">${label}</span> 1088 + ${renderProductImage(product)} 1053 1089 </div> 1054 1090 <div class="product-info"> 1055 1091 <div class="product-name">${product.name}</div> ··· 1075 1111 selectedProduct = products.find(p => p.id === productId); 1076 1112 if (!selectedProduct) return; 1077 1113 1078 - const swatch = getSwatchStyle(selectedProduct.color); 1079 - const label = categoryLabels[selectedProduct.category] || selectedProduct.category; 1080 1114 const modalImage = document.getElementById('modal-image'); 1081 - modalImage.innerHTML = ` 1082 - <div class="product-swatch" style="background:${swatch.bg}"></div> 1083 - <span class="product-label">${label}</span> 1084 - `; 1115 + modalImage.innerHTML = renderProductImage(selectedProduct); 1085 1116 document.getElementById('modal-name').textContent = selectedProduct.name; 1086 1117 document.getElementById('modal-color').textContent = selectedProduct.color; 1087 1118 document.getElementById('modal-price').textContent = `$${selectedProduct.price.toFixed(2)}`; ··· 1137 1168 cartItems.innerHTML = '<div class="cart-empty">Your bag is empty</div>'; 1138 1169 } else { 1139 1170 cartItems.innerHTML = cart.map((item, index) => { 1140 - const swatch = getSwatchStyle(item.product.color); 1141 1171 return ` 1142 1172 <div class="cart-item"> 1143 1173 <div class="cart-item-image"> 1144 - <div class="product-swatch" style="background:${swatch.bg}"></div> 1145 - <span>${(categoryLabels[item.product.category] || '').substring(0, 3)}</span> 1174 + ${renderProductImage(item.product)} 1146 1175 </div> 1147 1176 <div class="cart-item-info"> 1148 1177 <div class="cart-item-name">${item.product.name}</div> ··· 1208 1237 </script> 1209 1238 </body> 1210 1239 1211 - </html> 1240 + </html>