Finish admin dashboard and update sql code

This commit is contained in:
estherdev03
2025-04-20 07:48:20 -06:00
parent e97f80aee1
commit 7a2250369e
8 changed files with 193 additions and 20 deletions

View File

@@ -0,0 +1,47 @@
const db = require("../utils/database");
exports.getAllCategoriesWithPagination = async (req, res) => {
const limit = +req.query?.limit;
const page = +req.query?.page;
const offset = (page - 1) * limit;
try {
const [data, _] = await db.execute(
"SELECT * FROM Category C ORDER BY C.CategoryID ASC LIMIT ? OFFSET ?",
[limit.toString(), offset.toString()]
);
const [result] = await db.execute("SELECT COUNT(*) AS count FROM Category");
const { count: total } = result[0];
return res.json({ data, total });
} catch (error) {
res.json({ error: "Cannot fetch categories from database!" });
}
};
exports.addCategory = async (req, res) => {
const { name } = req.body;
try {
const [result] = await db.execute(
"INSERT INTO Category (Name) VALUES (?)",
[name]
);
res.json({ message: "Adding new category successfully!" });
} catch (error) {
res.json({ error: "Cannot add new category!" });
}
};
exports.removeCategory = async (req, res) => {
const { id } = req.params;
try {
const [result] = await db.execute(
`DELETE FROM Category WHERE CategoryID = ?`,
[id]
);
res.json({ message: "Delete category successfully!" });
} catch (error) {
res.json({ error: "Cannot remove category from database!" });
}
};

View File

@@ -6,7 +6,7 @@ exports.addProduct = async (req, res) => {
try { try {
const [result] = await db.execute( const [result] = await db.execute(
`INSERT INTO Product (Name, Price, StockQuantity, UserID, Description, CategoryID) VALUES (?, ?, ?, ?, ?, ?)`, `INSERT INTO Product (Name, Price, StockQuantity, UserID, Description, CategoryID) VALUES (?, ?, ?, ?, ?, ?)`,
[name, price, qty, userID, description, category], [name, price, qty, userID, description, category]
); );
const productID = result.insertId; const productID = result.insertId;
@@ -15,7 +15,7 @@ exports.addProduct = async (req, res) => {
db.execute(`INSERT INTO Image_URL (URL, ProductID) VALUES (?, ?)`, [ db.execute(`INSERT INTO Image_URL (URL, ProductID) VALUES (?, ?)`, [
imagePath, imagePath,
productID, productID,
]), ])
); );
await Promise.all(imageInsertPromises); //perallel await Promise.all(imageInsertPromises); //perallel
@@ -39,7 +39,7 @@ exports.addFavorite = async (req, res) => {
// Use parameterized query to prevent SQL injection // Use parameterized query to prevent SQL injection
const [result] = await db.execute( const [result] = await db.execute(
`INSERT INTO Favorites (UserID, ProductID) VALUES (?, ?)`, `INSERT INTO Favorites (UserID, ProductID) VALUES (?, ?)`,
[userID, productID], [userID, productID]
); );
res.json({ res.json({
@@ -59,7 +59,7 @@ exports.removeFavorite = async (req, res) => {
// Use parameterized query to prevent SQL injection // Use parameterized query to prevent SQL injection
const [result] = await db.execute( const [result] = await db.execute(
`DELETE FROM Favorites WHERE UserID = ? AND ProductID = ?`, `DELETE FROM Favorites WHERE UserID = ? AND ProductID = ?`,
[userID, productID], [userID, productID]
); );
res.json({ res.json({
@@ -103,7 +103,7 @@ exports.getFavorites = async (req, res) => {
p.Date, p.Date,
u.Name; u.Name;
`, `,
[userID], [userID]
); );
res.json({ res.json({
@@ -168,7 +168,7 @@ exports.getProductById = async (req, res) => {
JOIN User U ON p.UserID = U.UserID JOIN User U ON p.UserID = U.UserID
WHERE p.ProductID = ? WHERE p.ProductID = ?
`, `,
[id], [id]
); );
// Log raw data for debugging // Log raw data for debugging
@@ -211,6 +211,65 @@ exports.getProductById = async (req, res) => {
} }
}; };
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!" });
}
};
// db_con.query( // db_con.query(
// "SELECT ProductID FROM product WHERE ProductID = ?", // "SELECT ProductID FROM product WHERE ProductID = ?",
// [productID], // [productID],

View File

@@ -13,13 +13,13 @@ exports.sendVerificationCode = async (req, res) => {
// Generate a random 6-digit code // Generate a random 6-digit code
const verificationCode = crypto.randomInt(100000, 999999).toString(); const verificationCode = crypto.randomInt(100000, 999999).toString();
console.log( console.log(
`Generated verification code for ${email}: ${verificationCode}`, `Generated verification code for ${email}: ${verificationCode}`
); );
// Check if email already exists in verification table // Check if email already exists in verification table
const [results, fields] = await db.execute( const [results, fields] = await db.execute(
"SELECT * FROM AuthVerification WHERE Email = ?", "SELECT * FROM AuthVerification WHERE Email = ?",
[email], [email]
); );
if (results.length > 0) { if (results.length > 0) {
@@ -27,7 +27,7 @@ exports.sendVerificationCode = async (req, res) => {
const [result] = await db.execute( const [result] = await db.execute(
`UPDATE AuthVerification SET VerificationCode = ?, Authenticated = FALSE, Date = CURRENT_TIMESTAMP `UPDATE AuthVerification SET VerificationCode = ?, Authenticated = FALSE, Date = CURRENT_TIMESTAMP
WHERE Email = ?`, WHERE Email = ?`,
[verificationCode, email], [verificationCode, email]
); );
// Send email and respond // Send email and respond
@@ -37,7 +37,7 @@ exports.sendVerificationCode = async (req, res) => {
// Insert new record // Insert new record
const [result] = await db.execute( const [result] = await db.execute(
"INSERT INTO AuthVerification (Email, VerificationCode, Authenticated) VALUES (?, ?, FALSE)", "INSERT INTO AuthVerification (Email, VerificationCode, Authenticated) VALUES (?, ?, FALSE)",
[email, verificationCode], [email, verificationCode]
); );
// Send email and respond // Send email and respond
await sendVerificationEmail(email, verificationCode); await sendVerificationEmail(email, verificationCode);
@@ -62,7 +62,7 @@ exports.verifyCode = async (req, res) => {
// Check verification code // Check verification code
const [results, fields] = await db.execute( const [results, fields] = await db.execute(
"SELECT * FROM AuthVerification WHERE Email = ? AND VerificationCode = ? AND Authenticated = 0 AND Date > DATE_SUB(NOW(), INTERVAL 15 MINUTE)", "SELECT * FROM AuthVerification WHERE Email = ? AND VerificationCode = ? AND Authenticated = 0 AND Date > DATE_SUB(NOW(), INTERVAL 15 MINUTE)",
[email, code], [email, code]
); );
if (results.length === 0) { if (results.length === 0) {
console.log(`Invalid or expired verification code for email ${email}`); console.log(`Invalid or expired verification code for email ${email}`);
@@ -76,7 +76,7 @@ exports.verifyCode = async (req, res) => {
// Mark as authenticated // Mark as authenticated
const [result] = await db.execute( const [result] = await db.execute(
"UPDATE AuthVerification SET Authenticated = TRUE WHERE Email = ?", "UPDATE AuthVerification SET Authenticated = TRUE WHERE Email = ?",
[email], [email]
); );
res.json({ res.json({
success: true, success: true,
@@ -95,7 +95,7 @@ exports.completeSignUp = async (req, res) => {
try { try {
const [results, fields] = await db.execute( const [results, fields] = await db.execute(
`SELECT * FROM AuthVerification WHERE Email = ? AND Authenticated = 1;`, `SELECT * FROM AuthVerification WHERE Email = ? AND Authenticated = 1;`,
[data.email], [data.email]
); );
if (results.length === 0) { if (results.length === 0) {
@@ -105,20 +105,20 @@ exports.completeSignUp = async (req, res) => {
// Create the user // Create the user
const [createResult] = await db.execute( const [createResult] = await db.execute(
`INSERT INTO User (Name, Email, UCID, Password, Phone, Address) `INSERT INTO User (Name, Email, UCID, Password, Phone, Address)
VALUES ('${data.name}', '${data.email}', '${data.UCID}', '${data.password}', '${data.phone}', '${data.address}')`, VALUES ('${data.name}', '${data.email}', '${data.UCID}', '${data.password}', '${data.phone}', '${data.address}')`
); );
// Insert role using the user's ID // Insert role using the user's ID
const [insertResult] = await db.execute( const [insertResult] = await db.execute(
`INSERT INTO UserRole (UserID, Client, Admin) `INSERT INTO UserRole (UserID, Client, Admin)
VALUES (LAST_INSERT_ID(), ${data.client || true}, ${ VALUES (LAST_INSERT_ID(), ${data.client || true}, ${
data.admin || false data.admin || false
})`, })`
); );
// Delete verification record // Delete verification record
const [deleteResult] = await db.execute( const [deleteResult] = await db.execute(
`DELETE FROM AuthVerification WHERE Email = '${data.email}'`, `DELETE FROM AuthVerification WHERE Email = '${data.email}'`
); );
res.json({ res.json({
@@ -310,7 +310,7 @@ exports.deleteUser = async (req, res) => {
// Delete from UserRole first (assuming foreign key constraint) // Delete from UserRole first (assuming foreign key constraint)
const [result1] = await db.execute( const [result1] = await db.execute(
"DELETE FROM UserRole WHERE UserID = ?", "DELETE FROM UserRole WHERE UserID = ?",
[userId], [userId]
); );
// Then delete from User table // Then delete from User table
@@ -328,3 +328,38 @@ exports.deleteUser = async (req, res) => {
return res.status(500).json({ error: "Could not delete user!" }); return res.status(500).json({ error: "Could not delete user!" });
} }
}; };
exports.getUsersWithPagination = async (req, res) => {
const limit = +req.query.limit;
const page = +req.query.page;
const offset = (page - 1) * limit;
try {
const [users, fields] = await db.execute(
"SELECT * FROM User LIMIT ? OFFSET ?",
[limit.toString(), offset.toString()]
);
const [result] = await db.execute("SELECT COUNT(*) AS count FROM User");
const { count: total } = result[0];
res.json({ users, total });
} catch (error) {
console.error("Errors: ", error);
return res.status(500).json({ error: "\nCould not fetch users!" });
}
};
exports.isAdmin = async (req, res) => {
const { id } = req.params;
try {
const [result] = await db.execute(
"SELECT R.Admin FROM marketplace.userrole R WHERE R.UserID = ?",
[id]
);
const { Admin } = result[0];
res.json({ isAdmin: Admin });
} catch (error) {
res.json({ error: "Cannot verify admin status!" });
}
};

View File

@@ -9,6 +9,7 @@ const searchRouter = require("./routes/search");
const recommendedRouter = require("./routes/recommendation"); const recommendedRouter = require("./routes/recommendation");
const history = require("./routes/history"); const history = require("./routes/history");
const review = require("./routes/review"); const review = require("./routes/review");
const categoryRouter = require("./routes/category");
const { generateEmailTransporter } = require("./utils/mail"); const { generateEmailTransporter } = require("./utils/mail");
const { const {
@@ -42,10 +43,10 @@ app.use("/api/search", searchRouter);
app.use("/api/engine", recommendedRouter); app.use("/api/engine", recommendedRouter);
app.use("/api/history", history); app.use("/api/history", history);
app.use("/api/review", review); app.use("/api/review", review);
app.use("/api/category", categoryRouter);
// Set up a scheduler to run cleanup every hour // Set up a scheduler to run cleanup every hour
clean_up_time = 30*60*1000; clean_up_time = 30 * 60 * 1000;
setInterval(cleanupExpiredCodes, clean_up_time); setInterval(cleanupExpiredCodes, clean_up_time);
app.listen(3030, () => { app.listen(3030, () => {

View File

@@ -0,0 +1,14 @@
const express = require("express");
const {
getAllCategoriesWithPagination,
addCategory,
removeCategory,
} = require("../controllers/category");
const router = express.Router();
router.get("/getCategories", getAllCategoriesWithPagination);
router.post("/addCategory", addCategory);
router.delete("/:id", removeCategory);
module.exports = router;

View File

@@ -7,6 +7,8 @@ const {
getAllProducts, getAllProducts,
getProductById, getProductById,
addProduct, addProduct,
removeProduct,
getProductWithPagination,
} = require("../controllers/product"); } = require("../controllers/product");
const router = express.Router(); const router = express.Router();
@@ -22,6 +24,12 @@ router.post("/delFavorite", removeFavorite);
router.post("/addProduct", addProduct); router.post("/addProduct", addProduct);
router.get("/getProduct", getAllProducts); router.get("/getProduct", getAllProducts);
//Remove product
router.delete("/:id", removeProduct);
//Get products with pagination
router.get("/getProductWithPagination", getProductWithPagination);
router.get("/:id", getProductById); // Simplified route router.get("/:id", getProductById); // Simplified route
module.exports = router; module.exports = router;

View File

@@ -8,6 +8,8 @@ const {
updateUser, updateUser,
deleteUser, deleteUser,
doLogin, doLogin,
isAdmin,
getUsersWithPagination,
} = require("../controllers/user"); } = require("../controllers/user");
const router = express.Router(); const router = express.Router();
@@ -36,4 +38,10 @@ router.post("/update", updateUser);
//Delete A uses Data: //Delete A uses Data:
router.post("/delete", deleteUser); router.post("/delete", deleteUser);
//Check admin status
router.get("/isAdmin/:id", isAdmin);
//Fetch user with pagination
router.get("/getUserWithPagination", getUsersWithPagination);
module.exports = router; module.exports = router;

View File

@@ -4,6 +4,7 @@ const pool = mysql.createPool({
host: "localhost", host: "localhost",
user: "root", user: "root",
database: "Marketplace", database: "Marketplace",
password: "12345678",
}); });
module.exports = pool.promise(); module.exports = pool.promise();