From d169c9ba587d5d389e002b963ba3ec2e3eac10e0 Mon Sep 17 00:00:00 2001 From: Mann Patel <130435633+MannPatel0@users.noreply.github.com> Date: Sat, 19 Apr 2025 10:22:16 -0600 Subject: [PATCH] update --- backend/controllers/product.js | 71 +++++--- backend/routes/product.js | 2 + frontend/src/App.jsx | 4 - frontend/src/components/ProductForm.jsx | 169 +++++++++--------- frontend/src/index.css | 2 +- frontend/src/pages/Selling.jsx | 14 -- .../__pycache__/app.cpython-313.pyc | Bin 5730 -> 5724 bytes 7 files changed, 135 insertions(+), 127 deletions(-) diff --git a/backend/controllers/product.js b/backend/controllers/product.js index 569e4c6..9684513 100644 --- a/backend/controllers/product.js +++ b/backend/controllers/product.js @@ -1,34 +1,22 @@ const db = require("../utils/database"); exports.addProduct = async (req, res) => { - const { userID, name, price, qty, description, category, images } = req.body; - + const { userID, name, price, stockQty, Description } = req.body; + console.log(userID); try { + // Use parameterized query to prevent SQL injection const [result] = await db.execute( - `INSERT INTO Product (Name, Price, StockQuantity, UserID, Description, CategoryID) VALUES (?, ?, ?, ?, ?, ?)`, - [name, price, qty, userID, description, category], + `INSERT INTO Favorites (UserID, ProductID) VALUES (?, ?)`, + [userID, productID], ); - const productID = result.insertId; - if (images && images.length > 0) { - const imageInsertPromises = images.map((imagePath) => - db.execute(`INSERT INTO Image_URL (URL, ProductID) VALUES (?, ?)`, [ - imagePath, - productID, - ]), - ); - - await Promise.all(imageInsertPromises); //perallel - } - res.json({ success: true, - message: "Product and images added successfully", + message: "Product added to favorites successfully", }); } catch (error) { - console.error("Error adding product or images:", error); - console.log(error); - return res.json({ error: "Could not add product or images" }); + console.error("Error adding favorite product:", error); + return res.json({ error: "Could not add favorite product" }); } }; @@ -72,6 +60,49 @@ exports.removeFavorite = async (req, res) => { } }; +exports.myProduct = async (req, res) => { + const { userID } = req.body; + + try { + const [favorites] = await db.execute( + ` + SELECT + p.ProductID, + p.Name, + p.Description, + p.Price, + p.CategoryID, + p.UserID, + p.Date, + u.Name AS SellerName, + MIN(i.URL) AS image_url + FROM Product p + JOIN User u ON p.UserID = u.UserID + LEFT JOIN Image_URL i ON p.ProductID = i.ProductID + WHERE p.UserID = ? + GROUP BY + p.ProductID, + p.Name, + p.Description, + p.Price, + p.CategoryID, + p.UserID, + p.Date, + u.Name; + `, + [userID], + ); + + res.json({ + success: true, + favorites: favorites, + }); + } catch (error) { + console.error("Error retrieving favorites:", error); + res.status(500).json({ error: "Could not retrieve favorite products" }); + } +}; + exports.getFavorites = async (req, res) => { const { userID } = req.body; diff --git a/backend/routes/product.js b/backend/routes/product.js index 944e63b..8343405 100644 --- a/backend/routes/product.js +++ b/backend/routes/product.js @@ -7,6 +7,7 @@ const { getAllProducts, getProductById, addProduct, + myProduct, } = require("../controllers/product"); const router = express.Router(); @@ -20,6 +21,7 @@ router.post("/addFavorite", addFavorite); router.post("/getFavorites", getFavorites); router.post("/delFavorite", removeFavorite); +router.post("/myProduct", myProduct); router.post("/addProduct", addProduct); router.get("/getProduct", getAllProducts); router.get("/:id", getProductById); // Simplified route diff --git a/frontend/src/App.jsx b/frontend/src/App.jsx index 4b88b70..5524aac 100644 --- a/frontend/src/App.jsx +++ b/frontend/src/App.jsx @@ -30,8 +30,6 @@ function App() { const [error, setError] = useState(""); const [isLoading, setIsLoading] = useState(false); - const [userId, setUserId] = useState(null); - // New verification states const [verificationStep, setVerificationStep] = useState("initial"); // 'initial', 'code-sent', 'verifying' const [tempUserData, setTempUserData] = useState(null); @@ -384,8 +382,6 @@ function App() { isAuthenticated, }; - console.log("Sending user data to the server:", requestData); - // Send data to Python server (replace with your actual server URL) const response = await fetch("http://0.0.0.0:5000/api/user/session", { method: "POST", diff --git a/frontend/src/components/ProductForm.jsx b/frontend/src/components/ProductForm.jsx index 32ed01b..1461c1b 100644 --- a/frontend/src/components/ProductForm.jsx +++ b/frontend/src/components/ProductForm.jsx @@ -1,5 +1,5 @@ -import React, { useState } from "react"; -import { X, ChevronLeft, Plus, Trash2, Check } from "lucide-react"; +import React, { useState, useEffect } from "react"; +import { X, ChevronLeft, Plus, Trash2 } from "lucide-react"; const ProductForm = ({ editingProduct, @@ -8,46 +8,42 @@ const ProductForm = ({ onCancel, }) => { const [selectedCategory, setSelectedCategory] = useState(""); + const [categories, setCategories] = useState([]); + const [categoryMapping, setCategoryMapping] = useState({}); const storedUser = JSON.parse(sessionStorage.getItem("user")); - const categories = [ - "Electronics", - "Clothing", - "Home & Garden", - "Toys & Games", - "Books", - "Sports & Outdoors", - "Automotive", - "Beauty & Personal Care", - "Health & Wellness", - "Jewelry", - "Art & Collectibles", - "Food & Beverages", - "Office Supplies", - "Pet Supplies", - "Music & Instruments", - "Other", - ]; + // Fetch categories from API + useEffect(() => { + const fetchCategories = async () => { + try { + const response = await fetch("http://localhost:3030/api/category"); + if (!response.ok) throw new Error("Failed to fetch categories"); - // Map category names to their respective IDs - const categoryMapping = { - Electronics: 1, - Clothing: 2, - "Home & Garden": 3, - "Toys & Games": 4, - Books: 5, - "Sports & Outdoors": 6, - Automotive: 7, - "Beauty & Personal Care": 8, - "Health & Wellness": 9, - Jewelry: 10, - "Art & Collectibles": 11, - "Food & Beverages": 12, - "Office Supplies": 13, - "Pet Supplies": 14, - "Music & Instruments": 15, - Other: 16, - }; + const responseJson = await response.json(); + const data = responseJson.data; + + // Create an array of category names for the dropdown + // Transform the object into an array of category names + const categoryNames = []; + const mapping = {}; + + // Process the data properly to avoid rendering objects + Object.entries(data).forEach(([id, name]) => { + // Make sure each category name is a string + const categoryName = String(name); + categoryNames.push(categoryName); + mapping[categoryName] = parseInt(id); + }); + + setCategories(categoryNames); + setCategoryMapping(mapping); + } catch (error) { + console.error("Error fetching categories:", error); + } + }; + + fetchCategories(); + }, []); const handleSave = async () => { // Check if the user has selected at least one category @@ -61,13 +57,9 @@ const ProductForm = ({ const imagePaths = []; // If we have files to upload, we'd handle the image upload here - // This is a placeholder for where you'd implement image uploads - // For now, we'll simulate the API expecting paths: if (editingProduct.images && editingProduct.images.length > 0) { // Simulating image paths for demo purposes - // In a real implementation, you would upload these files first - // and then use the returned paths - editingProduct.images.forEach((file, index) => { + editingProduct.images.forEach((file) => { const simulatedPath = `/public/uploads/${file.name}`; imagePaths.push(simulatedPath); }); @@ -75,13 +67,13 @@ const ProductForm = ({ // Get the category ID from the first selected category const categoryName = (editingProduct.categories || [])[0]; - const categoryID = categoryMapping[categoryName] || 3; // Default to 3 if not found + const categoryID = categoryMapping[categoryName] || 1; // Default to 3 if not found // Prepare payload according to API expectations const payload = { name: editingProduct.name || "", price: parseFloat(editingProduct.price) || 0, - qty: 1, // Hardcoded as per your requirement + qty: 1, userID: storedUser.ID, description: editingProduct.description || "", category: categoryID, @@ -115,6 +107,24 @@ const ProductForm = ({ } }; + const markAsSold = async () => { + // This would call an API to move the product to the transaction table + try { + // API call would go here + console.log("Moving product to transaction table:", editingProduct.id); + + // Toggle the sold status in the UI + setEditingProduct((prev) => ({ + ...prev, + isSold: !prev.isSold, + })); + + // You would add your API call here to update the backend + } catch (error) { + console.error("Error marking product as sold:", error); + } + }; + const addCategory = () => { if ( selectedCategory && @@ -137,13 +147,6 @@ const ProductForm = ({ })); }; - const toggleSoldStatus = () => { - setEditingProduct((prev) => ({ - ...prev, - isSold: !prev.isSold, - })); - }; - return (
{/* Back Button */} @@ -196,18 +199,8 @@ const ProductForm = ({ {/* Sold Status */}
- - {editingProduct.isSold && ( - + Sold )} @@ -232,8 +225,8 @@ const ProductForm = ({ .filter( (cat) => !(editingProduct.categories || []).includes(cat), ) - .map((category) => ( - ))} @@ -252,9 +245,9 @@ const ProductForm = ({ {/* Selected Categories */} {(editingProduct.categories || []).length > 0 ? (
- {(editingProduct.categories || []).map((category) => ( + {(editingProduct.categories || []).map((category, index) => ( {category} @@ -375,33 +368,33 @@ const ProductForm = ({
{/* Actions */} -
+
-
+ {editingProduct.id && ( - -
+ )} + +
); diff --git a/frontend/src/index.css b/frontend/src/index.css index e065eb9..9fd180c 100644 --- a/frontend/src/index.css +++ b/frontend/src/index.css @@ -1,4 +1,4 @@ @import "tailwindcss"; @tailwind base; @tailwind components; -@tailwind utilities; \ No newline at end of file +@tailwind utilities; diff --git a/frontend/src/pages/Selling.jsx b/frontend/src/pages/Selling.jsx index 99de591..e8a87d8 100644 --- a/frontend/src/pages/Selling.jsx +++ b/frontend/src/pages/Selling.jsx @@ -12,7 +12,6 @@ const Selling = () => { price: "", description: "", categories: [], - status: "Unsold", images: [], }); @@ -28,7 +27,6 @@ const Selling = () => { price: "299.99", description: "A beautiful vintage film camera in excellent condition", categories: ["Electronics", "Art & Collectibles"], - status: "Unsold", images: ["/public/Pictures/Dell1.jpg"], }, { @@ -37,7 +35,6 @@ const Selling = () => { price: "149.50", description: "Genuine leather jacket, worn only a few times", categories: ["Clothing"], - status: "Unsold", images: [], }, ]; @@ -71,7 +68,6 @@ const Selling = () => { price: "", description: "", categories: [], - status: "Unsold", images: [], }); }; @@ -99,7 +95,6 @@ const Selling = () => { price: "", description: "", categories: [], - status: "Unsold", images: [], }); setShowForm(true); @@ -164,15 +159,6 @@ const Selling = () => {

{product.name}

- - {product.status} -

diff --git a/recommondation-engine/__pycache__/app.cpython-313.pyc b/recommondation-engine/__pycache__/app.cpython-313.pyc index 373cb2686da6709f2f82ff2345857432f34cf2aa..f5efd97bfd14a014c6683a8edf8f01535a1d88e2 100644 GIT binary patch delta 37 rcmaE)b4Q2!GcPX}0}w>4VBE;v#K`TUpOK%Ns-K&fm$!Ky;}H=6(b)^5 delta 43 xcmcbk^GJvLGcPX}0}ym_GH>K=Vife!4=qkDD%Q_U%*!iCEJ@ATJcIFw2mlnr4ZHvV