2025-03-19 02:09:30 -06:00
|
|
|
const db = require("../utils/database");
|
|
|
|
|
|
2025-04-18 20:25:02 -06:00
|
|
|
exports.addProduct = async (req, res) => {
|
|
|
|
|
const { userID, name, price, qty, description, category, images } = req.body;
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
const [result] = await db.execute(
|
|
|
|
|
`INSERT INTO Product (Name, Price, StockQuantity, UserID, Description, CategoryID) VALUES (?, ?, ?, ?, ?, ?)`,
|
2025-04-20 07:48:20 -06:00
|
|
|
[name, price, qty, userID, description, category]
|
2025-04-18 20:25:02 -06:00
|
|
|
);
|
|
|
|
|
|
|
|
|
|
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,
|
2025-04-20 07:48:20 -06:00
|
|
|
])
|
2025-04-18 20:25:02 -06:00
|
|
|
);
|
|
|
|
|
|
|
|
|
|
await Promise.all(imageInsertPromises); //perallel
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
res.json({
|
|
|
|
|
success: true,
|
|
|
|
|
message: "Product and images added successfully",
|
|
|
|
|
});
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error("Error adding product or images:", error);
|
|
|
|
|
console.log(error);
|
|
|
|
|
return res.json({ error: "Could not add product or images" });
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2025-04-12 13:10:17 -06:00
|
|
|
exports.addFavorite = async (req, res) => {
|
2025-04-12 18:33:13 -06:00
|
|
|
const { userID, productID } = req.body;
|
|
|
|
|
console.log(userID);
|
2025-03-19 04:10:41 -06:00
|
|
|
try {
|
|
|
|
|
// Use parameterized query to prevent SQL injection
|
|
|
|
|
const [result] = await db.execute(
|
2025-04-12 18:33:13 -06:00
|
|
|
`INSERT INTO Favorites (UserID, ProductID) VALUES (?, ?)`,
|
2025-04-20 07:48:20 -06:00
|
|
|
[userID, productID]
|
2025-03-19 04:10:41 -06:00
|
|
|
);
|
|
|
|
|
|
|
|
|
|
res.json({
|
|
|
|
|
success: true,
|
|
|
|
|
message: "Product added to favorites successfully",
|
|
|
|
|
});
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error("Error adding favorite product:", error);
|
|
|
|
|
return res.json({ error: "Could not add favorite product" });
|
|
|
|
|
}
|
2025-03-19 02:09:30 -06:00
|
|
|
};
|
|
|
|
|
|
2025-04-13 12:52:21 -06:00
|
|
|
exports.removeFavorite = async (req, res) => {
|
|
|
|
|
const { userID, productID } = req.body;
|
|
|
|
|
console.log(userID);
|
|
|
|
|
try {
|
|
|
|
|
// Use parameterized query to prevent SQL injection
|
|
|
|
|
const [result] = await db.execute(
|
|
|
|
|
`DELETE FROM Favorites WHERE UserID = ? AND ProductID = ?`,
|
2025-04-20 07:48:20 -06:00
|
|
|
[userID, productID]
|
2025-04-13 12:52:21 -06:00
|
|
|
);
|
|
|
|
|
|
|
|
|
|
res.json({
|
|
|
|
|
success: true,
|
|
|
|
|
message: "Product removed from favorites successfully",
|
|
|
|
|
});
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error("Error removing favorite product:", error);
|
|
|
|
|
return res.json({ error: "Could not remove favorite product" });
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2025-04-12 13:10:17 -06:00
|
|
|
exports.getFavorites = async (req, res) => {
|
|
|
|
|
const { userID } = req.body;
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
const [favorites] = await db.execute(
|
|
|
|
|
`
|
|
|
|
|
SELECT
|
2025-04-15 00:18:19 -06:00
|
|
|
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 Favorites f
|
|
|
|
|
JOIN Product p ON f.ProductID = p.ProductID
|
|
|
|
|
JOIN User u ON p.UserID = u.UserID
|
|
|
|
|
LEFT JOIN Image_URL i ON p.ProductID = i.ProductID
|
|
|
|
|
WHERE f.UserID = ?
|
|
|
|
|
GROUP BY
|
|
|
|
|
p.ProductID,
|
|
|
|
|
p.Name,
|
|
|
|
|
p.Description,
|
|
|
|
|
p.Price,
|
|
|
|
|
p.CategoryID,
|
|
|
|
|
p.UserID,
|
|
|
|
|
p.Date,
|
|
|
|
|
u.Name;
|
2025-04-12 13:10:17 -06:00
|
|
|
`,
|
2025-04-20 07:48:20 -06:00
|
|
|
[userID]
|
2025-04-12 13:10:17 -06:00
|
|
|
);
|
|
|
|
|
|
|
|
|
|
res.json({
|
|
|
|
|
success: true,
|
|
|
|
|
favorites: favorites,
|
|
|
|
|
});
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error("Error retrieving favorites:", error);
|
|
|
|
|
res.status(500).json({ error: "Could not retrieve favorite products" });
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2025-03-24 23:04:12 -06:00
|
|
|
// Get all products along with their image URLs
|
2025-03-19 04:10:41 -06:00
|
|
|
exports.getAllProducts = async (req, res) => {
|
|
|
|
|
try {
|
2025-03-24 23:04:12 -06:00
|
|
|
const [data, fields] = await db.execute(`
|
2025-03-25 14:47:54 -06:00
|
|
|
SELECT
|
2025-04-15 00:18:19 -06:00
|
|
|
P.ProductID,
|
|
|
|
|
P.Name AS ProductName,
|
|
|
|
|
P.Price,
|
|
|
|
|
P.Date AS DateUploaded,
|
|
|
|
|
U.Name AS SellerName,
|
|
|
|
|
MIN(I.URL) AS ProductImage,
|
|
|
|
|
C.Name AS Category
|
|
|
|
|
FROM Product P
|
|
|
|
|
JOIN Image_URL I ON P.ProductID = I.ProductID
|
|
|
|
|
JOIN User U ON P.UserID = U.UserID
|
|
|
|
|
JOIN Category C ON P.CategoryID = C.CategoryID
|
|
|
|
|
GROUP BY
|
|
|
|
|
P.ProductID,
|
|
|
|
|
P.Name,
|
|
|
|
|
P.Price,
|
|
|
|
|
P.Date,
|
|
|
|
|
U.Name,
|
|
|
|
|
C.Name;
|
2025-03-24 23:04:12 -06:00
|
|
|
`);
|
2025-03-19 04:10:41 -06:00
|
|
|
|
2025-03-19 02:09:30 -06:00
|
|
|
res.json({
|
|
|
|
|
success: true,
|
2025-03-24 23:04:12 -06:00
|
|
|
message: "Products fetched successfully",
|
2025-03-19 02:09:30 -06:00
|
|
|
data,
|
|
|
|
|
});
|
2025-03-19 04:10:41 -06:00
|
|
|
} catch (error) {
|
2025-03-24 23:04:12 -06:00
|
|
|
console.error("Error finding products:", error);
|
2025-03-19 04:10:41 -06:00
|
|
|
return res.status(500).json({
|
|
|
|
|
found: false,
|
|
|
|
|
error: "Database error occurred",
|
|
|
|
|
});
|
|
|
|
|
}
|
2025-03-19 02:09:30 -06:00
|
|
|
};
|
|
|
|
|
|
2025-03-24 23:04:12 -06:00
|
|
|
exports.getProductById = async (req, res) => {
|
|
|
|
|
const { id } = req.params;
|
2025-03-25 14:47:54 -06:00
|
|
|
console.log("Received Product ID:", id);
|
|
|
|
|
|
2025-03-24 23:04:12 -06:00
|
|
|
try {
|
|
|
|
|
const [data] = await db.execute(
|
|
|
|
|
`
|
2025-04-12 13:10:17 -06:00
|
|
|
SELECT p.*,U.Name AS SellerName,U.Email as SellerEmail,U.Phone as SellerPhone, i.URL AS image_url
|
2025-03-24 23:04:12 -06:00
|
|
|
FROM Product p
|
|
|
|
|
LEFT JOIN Image_URL i ON p.ProductID = i.ProductID
|
2025-04-03 18:56:39 -06:00
|
|
|
JOIN User U ON p.UserID = U.UserID
|
2025-03-24 23:04:12 -06:00
|
|
|
WHERE p.ProductID = ?
|
|
|
|
|
`,
|
2025-04-20 07:48:20 -06:00
|
|
|
[id]
|
2025-03-24 23:04:12 -06:00
|
|
|
);
|
|
|
|
|
|
2025-03-25 14:47:54 -06:00
|
|
|
// Log raw data for debugging
|
|
|
|
|
console.log("Raw Database Result:", data);
|
|
|
|
|
|
2025-03-24 23:04:12 -06:00
|
|
|
if (data.length === 0) {
|
2025-03-25 14:47:54 -06:00
|
|
|
console.log("No product found with ID:", id);
|
2025-03-24 23:04:12 -06:00
|
|
|
return res.status(404).json({
|
|
|
|
|
success: false,
|
|
|
|
|
message: "Product not found",
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2025-03-25 14:47:54 -06:00
|
|
|
// Collect all image URLs
|
|
|
|
|
const images = data
|
|
|
|
|
.map((row) => row.image_url)
|
|
|
|
|
.filter((url) => url !== null);
|
|
|
|
|
|
|
|
|
|
// Create product object with all details from first row and collected images
|
2025-03-24 23:04:12 -06:00
|
|
|
const product = {
|
2025-03-25 14:47:54 -06:00
|
|
|
...data[0], // Base product details
|
|
|
|
|
images: images, // Collected image URLs
|
2025-03-24 23:04:12 -06:00
|
|
|
};
|
|
|
|
|
|
2025-03-25 14:47:54 -06:00
|
|
|
// Log processed product for debugging
|
|
|
|
|
console.log("Processed Product:", product);
|
|
|
|
|
|
2025-03-24 23:04:12 -06:00
|
|
|
res.json({
|
|
|
|
|
success: true,
|
|
|
|
|
message: "Product fetched successfully",
|
|
|
|
|
data: product,
|
|
|
|
|
});
|
|
|
|
|
} catch (error) {
|
2025-03-25 14:47:54 -06:00
|
|
|
console.error("Full Error Details:", error);
|
2025-03-24 23:04:12 -06:00
|
|
|
return res.status(500).json({
|
|
|
|
|
success: false,
|
2025-03-25 14:47:54 -06:00
|
|
|
message: "Database error occurred",
|
|
|
|
|
error: error.message,
|
2025-03-24 23:04:12 -06:00
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2025-04-20 07:48:20 -06:00
|
|
|
exports.getProductWithPagination = async (req, res) => {
|
|
|
|
|
const limit = +req.query.limit;
|
|
|
|
|
const page = +req.query.page;
|
|
|
|
|
|
|
|
|
|
const offset = (page - 1) * limit;
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
const [data, fields] = await db.execute(
|
|
|
|
|
`
|
|
|
|
|
SELECT
|
|
|
|
|
P.ProductID,
|
|
|
|
|
P.Name AS ProductName,
|
|
|
|
|
P.Price,
|
|
|
|
|
P.Date AS DateUploaded,
|
|
|
|
|
U.Name AS SellerName,
|
|
|
|
|
MIN(I.URL) AS ProductImage,
|
|
|
|
|
C.Name AS Category
|
|
|
|
|
FROM Product P
|
|
|
|
|
LEFT JOIN Image_URL I ON P.ProductID = I.ProductID
|
|
|
|
|
LEFT JOIN User U ON P.UserID = U.UserID
|
|
|
|
|
LEFT JOIN Category C ON P.CategoryID = C.CategoryID
|
|
|
|
|
GROUP BY
|
|
|
|
|
P.ProductID,
|
|
|
|
|
P.Name,
|
|
|
|
|
P.Price,
|
|
|
|
|
P.Date,
|
|
|
|
|
U.Name,
|
|
|
|
|
C.Name
|
|
|
|
|
ORDER BY P.ProductID ASC
|
|
|
|
|
LIMIT ? OFFSET ?
|
|
|
|
|
`,
|
|
|
|
|
[limit.toString(), offset.toString()]
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
const [result] = await db.execute(
|
|
|
|
|
`SELECT COUNT(*) AS totalProd FROM Product`
|
|
|
|
|
);
|
|
|
|
|
const { totalProd } = result[0];
|
|
|
|
|
|
|
|
|
|
return res.json({ totalProd, products: data });
|
|
|
|
|
} catch (error) {
|
|
|
|
|
res.json({ error: "Error fetching products!" });
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
exports.removeProduct = async (req, res) => {
|
|
|
|
|
const { id } = req.params;
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
const [result] = await db.execute(
|
|
|
|
|
`DELETE FROM Product WHERE ProductID = ?`,
|
|
|
|
|
[id]
|
|
|
|
|
);
|
|
|
|
|
res.json({ message: "Delete product successfully!" });
|
|
|
|
|
} catch (error) {
|
|
|
|
|
res.json({ error: "Cannot remove product from database!" });
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2025-03-19 02:09:30 -06:00
|
|
|
// db_con.query(
|
|
|
|
|
// "SELECT ProductID FROM product WHERE ProductID = ?",
|
|
|
|
|
// [productID],
|
|
|
|
|
// (err, results) => {
|
|
|
|
|
// if (err) {
|
|
|
|
|
// console.error("Error checking product:", err);
|
|
|
|
|
// return res.json({ error: "Database error" });
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
// if (results.length === 0) {
|
|
|
|
|
// return res.json({ error: "Product does not exist" });
|
|
|
|
|
// }
|
|
|
|
|
// },
|
|
|
|
|
// );
|
|
|
|
|
|
|
|
|
|
// db_con.query(
|
|
|
|
|
// "INSERT INTO Favorites (UserID, ProductID) VALUES (?, ?)",
|
|
|
|
|
// [userID, productID],
|
|
|
|
|
// (err, result) => {
|
|
|
|
|
// if (err) {
|
|
|
|
|
// console.error("Error adding favorite product:", err);
|
|
|
|
|
// return res.json({ error: "Could not add favorite product" });
|
|
|
|
|
// }
|
|
|
|
|
// res.json({
|
|
|
|
|
// success: true,
|
|
|
|
|
// message: "Product added to favorites successfully",
|
|
|
|
|
// });
|
|
|
|
|
// },
|
|
|
|
|
// );
|