From e7a6e1dd8b11010a021973bdbe0e6e82abdc2bbe Mon Sep 17 00:00:00 2001 From: Mann Patel <130435633+MannPatel0@users.noreply.github.com> Date: Mon, 24 Mar 2025 23:04:12 -0600 Subject: [PATCH] Bug fix: Products No image --- backend/controllers/product.js | 56 ++++++++++- backend/routes/product.js | 8 +- frontend/src/pages/Home.jsx | 12 +-- frontend/src/pages/ProductDetail.jsx | 145 ++++++++++----------------- recommondation-engine/server1.py | 24 +++++ 5 files changed, 139 insertions(+), 106 deletions(-) create mode 100644 recommondation-engine/server1.py diff --git a/backend/controllers/product.js b/backend/controllers/product.js index 54f640e..bd40907 100644 --- a/backend/controllers/product.js +++ b/backend/controllers/product.js @@ -7,7 +7,7 @@ exports.addToFavorite = async (req, res) => { // Use parameterized query to prevent SQL injection const [result] = await db.execute( "INSERT INTO Favorites (UserID, ProductID) VALUES (?, ?)", - [userID, productsID] + [userID, productsID], ); res.json({ @@ -20,18 +20,22 @@ exports.addToFavorite = async (req, res) => { } }; -//Get all products +// Get all products along with their image URLs exports.getAllProducts = async (req, res) => { try { - const [data, fields] = await db.execute("SELECT * FROM Product"); + const [data, fields] = await db.execute(` + SELECT p.*, i.URL + FROM Product p + LEFT JOIN Image_URL i ON p.ProductID = i.ProductID + `); res.json({ success: true, - message: "Product added to favorites successfully", + message: "Products fetched successfully", data, }); } catch (error) { - console.error("Error finding user:", error); + console.error("Error finding products:", error); return res.status(500).json({ found: false, error: "Database error occurred", @@ -39,6 +43,48 @@ exports.getAllProducts = async (req, res) => { } }; +// Get a single product by ID along with image URLs +exports.getProductById = async (req, res) => { + const { id } = req.params; + console.log(id); + try { + const [data] = await db.execute( + ` + SELECT p.*, i.URL AS image_url + FROM Product p + LEFT JOIN Image_URL i ON p.ProductID = i.ProductID + WHERE p.ProductID = ? + `, + [id], + ); + + if (data.length === 0) { + return res.status(404).json({ + success: false, + message: "Product not found", + }); + } + + // Assuming that `data` contains product information and the image URLs + const product = { + ...data[0], // First product found in the query + images: data.map((image) => image.image_url), // Collect all image URLs into an array + }; + + res.json({ + success: true, + message: "Product fetched successfully", + data: product, + }); + } catch (error) { + console.error("Error fetching product:", error); + return res.status(500).json({ + success: false, + error: "Database error occurred", + }); + } +}; + // db_con.query( // "SELECT ProductID FROM product WHERE ProductID = ?", // [productID], diff --git a/backend/routes/product.js b/backend/routes/product.js index 55d3761..aeea0d9 100644 --- a/backend/routes/product.js +++ b/backend/routes/product.js @@ -1,5 +1,9 @@ const express = require("express"); -const { addToFavorite, getAllProducts } = require("../controllers/product"); +const { + addToFavorite, + getAllProducts, + getProductById, +} = require("../controllers/product"); const router = express.Router(); @@ -7,4 +11,6 @@ router.post("/add_fav_product", addToFavorite); router.get("/get_product", getAllProducts); +router.post("/get_productID", getProductById); + module.exports = router; diff --git a/frontend/src/pages/Home.jsx b/frontend/src/pages/Home.jsx index 300fd9d..4ae5a6e 100644 --- a/frontend/src/pages/Home.jsx +++ b/frontend/src/pages/Home.jsx @@ -11,7 +11,7 @@ const Home = () => { const fetchProducts = async () => { try { const response = await fetch( - "http://localhost:3030/api/product/get_product" + "http://localhost:3030/api/product/get_product", ); if (!response.ok) throw new Error("Failed to fetch products"); @@ -24,12 +24,12 @@ const Home = () => { title: product.Name, price: product.Price, category: product.CategoryID, - image: product.ImageURL, + image: product.URL, condition: "New", // Modify based on actual data - seller: "Unknown", // Modify if seller info is available + seller: product.UserID, // Modify if seller info is available datePosted: "Just now", isFavorite: false, - })) + })), ); } else { throw new Error(data.message || "Error fetching products"); @@ -50,8 +50,8 @@ const Home = () => { prevListings.map((listing) => listing.id === id ? { ...listing, isFavorite: !listing.isFavorite } - : listing - ) + : listing, + ), ); }; diff --git a/frontend/src/pages/ProductDetail.jsx b/frontend/src/pages/ProductDetail.jsx index 6b32e8e..95a5286 100644 --- a/frontend/src/pages/ProductDetail.jsx +++ b/frontend/src/pages/ProductDetail.jsx @@ -1,83 +1,54 @@ -import { useState } from "react"; +import { useState, useEffect } from "react"; import { useParams, Link } from "react-router-dom"; -import { - Heart, - ArrowLeft, - Tag, - User, - Calendar, - Share, - Flag, -} from "lucide-react"; +import { Heart, ArrowLeft, Tag, User, Calendar } from "lucide-react"; const ProductDetail = () => { const { id } = useParams(); + const [product, setProduct] = useState(null); const [isFavorite, setIsFavorite] = useState(false); const [showContactForm, setShowContactForm] = useState(false); const [message, setMessage] = useState(""); const [currentImage, setCurrentImage] = useState(0); - // Sample data for demonstration - const product = [ - { - id: 0, - title: "Dell XPS 13 Laptop - 2023 Model", - price: 850, - shortDescription: - "Dell XPS 13 laptop in excellent condition. Intel Core i7, 16GB RAM, 512GB SSD. Includes charger and original box.", - description: - "Selling my Dell XPS 13 laptop. Only 6 months old and in excellent condition. Intel Core i7 processor, 16GB RAM, 512GB SSD. Battery life is still excellent (around 10 hours of regular use). Comes with original charger and box. Selling because I'm upgrading to a MacBook for design work.\n\nSpecs:\n- Intel Core i7 11th Gen\n- 16GB RAM\n- 512GB NVMe SSD\n- 13.4\" FHD+ Display (1920x1200)\n- Windows 11 Pro\n- Backlit Keyboard\n- Thunderbolt 4 ports", - condition: "Like New", - category: - "Electronics, Electronics, Electronics, Electronics , Electronics , Electronics, Electronicss", - datePosted: "2023-03-02", - images: [ - "/image1.avif", - "/image2.avif", - "/image3.avif", - "/image3.avif", - "/image3.avif", - ], - seller: { - name: "Michael T.", - rating: 4.8, - memberSince: "January 2022", - avatar: "/Profile.jpg", - }, - }, - ]; + // Fetch product details + useEffect(() => { + const fetchProduct = async () => { + try { + const response = await fetch( + `http://localhost:3030/api/product/get_productID/${id}`, + ); + if (!response.ok) throw new Error("Failed to fetch product"); - console.log(product[id]); + const data = await response.json(); + if (data.success) { + setProduct(data.data); // Update the state with product details + } else { + throw new Error(data.message || "Error fetching product"); + } + } catch (error) { + console.error("Error fetching product:", error); + } + }; + fetchProduct(); + }, [id]); + + // Handle favorite toggle const toggleFavorite = () => { setIsFavorite(!isFavorite); }; + // Handle message submission const handleSendMessage = (e) => { e.preventDefault(); - // TODO: this would send the message to the seller + // Handle message logic here (send to seller) console.log("Message sent:", message); setMessage(""); setShowContactForm(false); - // Show confirmation or success message alert("Message sent to seller!"); }; - // Function to split description into paragraphs - const formatDescription = (text) => { - return text.split("\n\n").map((paragraph, index) => ( -
- {paragraph.split("\n").map((line, i) => (
-
- {line}
- {i < paragraph.split("\n").length - 1 &&
}
-
- ))}
-
{product[id].shortDescription}
+{product.shortDescription}
- Member since {product[id].seller.memberSince} + Member since {product.seller.memberSince}