diff --git a/.gitignore b/.gitignore index 459cf4c..b347d25 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,4 @@ node_modules npm-debug.log yarn-error.log .DS_Store -uploads/* \ No newline at end of file +public/uploads/* \ No newline at end of file diff --git a/backend/src/routes/cart.js b/backend/src/routes/cart.js index 1b76eca..4011487 100644 --- a/backend/src/routes/cart.js +++ b/backend/src/routes/cart.js @@ -36,25 +36,51 @@ module.exports = (pool, query, authMiddleware) => { const cartItemsResult = await query( `SELECT ci.id, ci.quantity, ci.added_at, p.id AS product_id, p.name, p.description, p.price, - p.category_id, pc.name AS category_name + p.category_id, pc.name AS category_name, + ( + SELECT json_agg( + json_build_object( + 'id', pi.id, + 'path', pi.image_path, + 'isPrimary', pi.is_primary, + 'displayOrder', pi.display_order + ) ORDER BY pi.display_order + ) + FROM product_images pi + WHERE pi.product_id = p.id + ) AS images FROM cart_items ci JOIN products p ON ci.product_id = p.id JOIN product_categories pc ON p.category_id = pc.id - WHERE ci.cart_id = $1`, + WHERE ci.cart_id = $1 + GROUP BY ci.id, ci.quantity, ci.added_at, p.id, p.name, p.description, p.price, p.category_id, pc.name`, [cartId] ); - // Calculate total - const total = cartItemsResult.rows.reduce((sum, item) => { + // Process images to add primary_image field + const processedItems = cartItemsResult.rows.map(item => { + // Add primary_image field derived from images array + let primaryImage = null; + if (item.images && item.images.length > 0) { + primaryImage = item.images.find(img => img.isPrimary === true) || item.images[0]; + } + return { + ...item, + primary_image: primaryImage + }; + }); + + // Calculate total + const total = processedItems.reduce((sum, item) => { return sum + (parseFloat(item.price) * item.quantity); }, 0); res.json({ id: cartId, userId, - items: cartItemsResult.rows, - itemCount: cartItemsResult.rows.length, + items: processedItems, + itemCount: processedItems.length, total }); } catch (error) { @@ -69,7 +95,7 @@ module.exports = (pool, query, authMiddleware) => { if (req.user.id !== userId) { return res.status(403).json({ error: true, - message: 'You can only modify your own cart' + req.user.id + " "+ userId + message: 'You can only modify your own cart' }); } // Check if product exists @@ -126,24 +152,51 @@ module.exports = (pool, query, authMiddleware) => { const updatedCartItems = await query( `SELECT ci.id, ci.quantity, ci.added_at, p.id AS product_id, p.name, p.description, p.price, - p.category_id, pc.name AS category_name + p.category_id, pc.name AS category_name, + ( + SELECT json_agg( + json_build_object( + 'id', pi.id, + 'path', pi.image_path, + 'isPrimary', pi.is_primary, + 'displayOrder', pi.display_order + ) ORDER BY pi.display_order + ) + FROM product_images pi + WHERE pi.product_id = p.id + ) AS images FROM cart_items ci JOIN products p ON ci.product_id = p.id JOIN product_categories pc ON p.category_id = pc.id - WHERE ci.cart_id = $1`, + WHERE ci.cart_id = $1 + GROUP BY ci.id, ci.quantity, ci.added_at, p.id, p.name, p.description, p.price, p.category_id, pc.name`, [cartId] ); + // Process images to add primary_image field + const processedItems = updatedCartItems.rows.map(item => { + // Add primary_image field derived from images array + let primaryImage = null; + if (item.images && item.images.length > 0) { + primaryImage = item.images.find(img => img.isPrimary === true) || item.images[0]; + } + + return { + ...item, + primary_image: primaryImage + }; + }); + // Calculate total - const total = updatedCartItems.rows.reduce((sum, item) => { + const total = processedItems.reduce((sum, item) => { return sum + (parseFloat(item.price) * item.quantity); }, 0); res.json({ id: cartId, userId, - items: updatedCartItems.rows, - itemCount: updatedCartItems.rows.length, + items: processedItems, + itemCount: processedItems.length, total }); } catch (error) { @@ -158,7 +211,7 @@ module.exports = (pool, query, authMiddleware) => { if (req.user.id !== userId) { return res.status(403).json({ error: true, - message: 'You can only modify your own cart' + req.user.id + " "+ userId + message: 'You can only modify your own cart' }); } // Get cart @@ -194,24 +247,51 @@ module.exports = (pool, query, authMiddleware) => { const updatedCartItems = await query( `SELECT ci.id, ci.quantity, ci.added_at, p.id AS product_id, p.name, p.description, p.price, - p.category_id, pc.name AS category_name + p.category_id, pc.name AS category_name, + ( + SELECT json_agg( + json_build_object( + 'id', pi.id, + 'path', pi.image_path, + 'isPrimary', pi.is_primary, + 'displayOrder', pi.display_order + ) ORDER BY pi.display_order + ) + FROM product_images pi + WHERE pi.product_id = p.id + ) AS images FROM cart_items ci JOIN products p ON ci.product_id = p.id JOIN product_categories pc ON p.category_id = pc.id - WHERE ci.cart_id = $1`, + WHERE ci.cart_id = $1 + GROUP BY ci.id, ci.quantity, ci.added_at, p.id, p.name, p.description, p.price, p.category_id, pc.name`, [cartId] ); + // Process images to add primary_image field + const processedItems = updatedCartItems.rows.map(item => { + // Add primary_image field derived from images array + let primaryImage = null; + if (item.images && item.images.length > 0) { + primaryImage = item.images.find(img => img.isPrimary === true) || item.images[0]; + } + + return { + ...item, + primary_image: primaryImage + }; + }); + // Calculate total - const total = updatedCartItems.rows.reduce((sum, item) => { + const total = processedItems.reduce((sum, item) => { return sum + (parseFloat(item.price) * item.quantity); }, 0); res.json({ id: cartId, userId, - items: updatedCartItems.rows, - itemCount: updatedCartItems.rows.length, + items: processedItems, + itemCount: processedItems.length, total }); } catch (error) { @@ -226,7 +306,7 @@ module.exports = (pool, query, authMiddleware) => { if (req.user.id !== userId) { return res.status(403).json({ error: true, - message: 'You can only modify your own cart' + req.user.id + " "+ userId + message: 'You can only modify your own cart' }); } // Get cart diff --git a/docker-compose.yml b/docker-compose.yml index e891df0..873692d 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -7,7 +7,7 @@ services: context: ./frontend dockerfile: Dockerfile ports: - - "3000:80" + - "3000:3000" volumes: - ./frontend:/app - /app/node_modules diff --git a/frontend/src/pages/CartPage.jsx b/frontend/src/pages/CartPage.jsx index b310d7d..2eb9bc0 100644 --- a/frontend/src/pages/CartPage.jsx +++ b/frontend/src/pages/CartPage.jsx @@ -153,7 +153,6 @@ const CartPage = () => { - {cart.items.map((item) => ( @@ -163,7 +162,7 @@ const CartPage = () => {