Merge branch 'main' into mannBranch
This commit is contained in:
@@ -22,4 +22,8 @@
|
|||||||
```
|
```
|
||||||
|
|
||||||
### Database
|
### Database
|
||||||
|
1. To Create the DB use the command bellow
|
||||||
|
```Bash
|
||||||
|
python3 ./SQL_code/init-db.py
|
||||||
|
```
|
||||||
- MySql Version 9.2.0
|
- MySql Version 9.2.0
|
||||||
|
|||||||
@@ -36,7 +36,6 @@ CREATE TABLE Product (
|
|||||||
StockQuantity INT,
|
StockQuantity INT,
|
||||||
UserID INT,
|
UserID INT,
|
||||||
Description TEXT,
|
Description TEXT,
|
||||||
Timestamp DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
CategoryID INT NOT NULL,
|
CategoryID INT NOT NULL,
|
||||||
Date DATETIME DEFAULT CURRENT_TIMESTAMP,
|
Date DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||||
FOREIGN KEY (UserID) REFERENCES User (UserID),
|
FOREIGN KEY (UserID) REFERENCES User (UserID),
|
||||||
@@ -122,303 +121,276 @@ CREATE TABLE AuthVerification (
|
|||||||
Date DATETIME DEFAULT CURRENT_TIMESTAMP
|
Date DATETIME DEFAULT CURRENT_TIMESTAMP
|
||||||
);
|
);
|
||||||
|
|
||||||
-- Insert sample categories
|
-- -- Insert sample categories
|
||||||
INSERT INTO
|
-- INSERT INTO
|
||||||
Category (CategoryID, Name)
|
-- Category (CategoryID, Name)
|
||||||
VALUES
|
-- VALUES
|
||||||
(1, 'Electronics'),
|
-- (1, 'Electronics'),
|
||||||
(2, 'Clothing'),
|
-- (2, 'Clothing'),
|
||||||
(3, 'Books'),
|
-- (3, 'Books'),
|
||||||
(4, 'Home & Garden'),
|
-- (4, 'Home & Garden'),
|
||||||
(5, 'Sports & Outdoors');
|
-- (5, 'Sports & Outdoors');
|
||||||
|
-- -- -- USER CRUD OPERATIONS
|
||||||
-- USER CRUD OPERATIONS
|
-- -- -- Create User (INSERT)
|
||||||
-- Create User (INSERT)
|
-- -- INSERT INTO
|
||||||
INSERT INTO
|
-- -- User (Name, Email, UCID, Password, Phone, Address)
|
||||||
User (Name, Email, UCID, Password, Phone, Address)
|
-- -- VALUES
|
||||||
VALUES
|
-- -- (
|
||||||
(
|
-- -- 'John Doe',
|
||||||
'John Doe',
|
-- -- 'john@example.com',
|
||||||
'john@example.com',
|
-- -- 'UC123456',
|
||||||
'UC123456',
|
-- -- 'hashed_password_here',
|
||||||
'hashed_password_here',
|
-- -- '555-123-4567',
|
||||||
'555-123-4567',
|
-- -- '123 Main St'
|
||||||
'123 Main St'
|
-- -- );
|
||||||
);
|
-- -- -- Set user role
|
||||||
|
-- -- INSERT INTO
|
||||||
-- Set user role
|
-- -- UserRole (UserID, Client, Admin)
|
||||||
INSERT INTO
|
-- -- VALUES
|
||||||
UserRole (UserID, Client, Admin)
|
-- -- (LAST_INSERT_ID (), TRUE, FALSE);
|
||||||
VALUES
|
-- -- -- Read User (SELECT)
|
||||||
(LAST_INSERT_ID (), TRUE, FALSE);
|
-- -- SELECT
|
||||||
|
-- -- u.*,
|
||||||
-- Read User (SELECT)
|
-- -- ur.Client,
|
||||||
SELECT
|
-- -- ur.Admin
|
||||||
u.*,
|
-- -- FROM
|
||||||
ur.Client,
|
-- -- User u
|
||||||
ur.Admin
|
-- -- JOIN UserRole ur ON u.UserID = ur.UserID
|
||||||
FROM
|
-- -- WHERE
|
||||||
User u
|
-- -- u.UserID = 1;
|
||||||
JOIN UserRole ur ON u.UserID = ur.UserID
|
-- -- -- Update User (UPDATE)
|
||||||
WHERE
|
-- -- UPDATE User
|
||||||
u.UserID = 1;
|
-- -- SET
|
||||||
|
-- -- Name = 'John Smith',
|
||||||
-- Update User (UPDATE)
|
-- -- Phone = '555-987-6543',
|
||||||
UPDATE User
|
-- -- Address = '456 Elm St'
|
||||||
SET
|
-- -- WHERE
|
||||||
Name = 'John Smith',
|
-- -- UserID = 1;
|
||||||
Phone = '555-987-6543',
|
-- -- -- Update User Role
|
||||||
Address = '456 Elm St'
|
-- -- UPDATE UserRole
|
||||||
WHERE
|
-- -- SET
|
||||||
UserID = 1;
|
-- -- Admin = TRUE
|
||||||
|
-- -- WHERE
|
||||||
-- Update User Role
|
-- -- UserID = 1;
|
||||||
UPDATE UserRole
|
-- -- -- PRODUCT CRUD OPERATIONS
|
||||||
SET
|
-- -- -- Create Product (INSERT)
|
||||||
Admin = TRUE
|
-- -- INSERT INTO
|
||||||
WHERE
|
-- -- Product (
|
||||||
UserID = 1;
|
-- -- ProductID,
|
||||||
|
-- -- Name,
|
||||||
-- PRODUCT CRUD OPERATIONS
|
-- -- Price,
|
||||||
-- Create Product (INSERT)
|
-- -- StockQuantity,
|
||||||
INSERT INTO
|
-- -- UserID,
|
||||||
Product (
|
-- -- Description,
|
||||||
ProductID,
|
-- -- CategoryID
|
||||||
Name,
|
-- -- )
|
||||||
Price,
|
-- -- VALUES
|
||||||
StockQuantity,
|
-- -- (
|
||||||
UserID,
|
-- -- 1,
|
||||||
Description,
|
-- -- 'Smartphone',
|
||||||
CategoryID
|
-- -- 599.99,
|
||||||
)
|
-- -- 50,
|
||||||
VALUES
|
-- -- 1,
|
||||||
(
|
-- -- 'Latest model smartphone with amazing features',
|
||||||
1,
|
-- -- 1
|
||||||
'Smartphone',
|
-- -- );
|
||||||
599.99,
|
-- -- -- Add product images with the placeholder URL
|
||||||
50,
|
-- -- INSERT INTO
|
||||||
1,
|
-- -- Image_URL (URL, ProductID)
|
||||||
'Latest model smartphone with amazing features',
|
-- -- VALUES
|
||||||
1
|
-- -- ('https://picsum.photos/id/237/200/300', 1),
|
||||||
);
|
-- -- ('https://picsum.photos/id/237/200/300', 1);
|
||||||
|
-- -- -- Create another product for recommendations
|
||||||
-- Add product images with the placeholder URL
|
-- -- INSERT INTO
|
||||||
INSERT INTO
|
-- -- Product (
|
||||||
Image_URL (URL, ProductID)
|
-- -- ProductID,
|
||||||
VALUES
|
-- -- Name,
|
||||||
('https://picsum.photos/id/237/200/300', 1),
|
-- -- Price,
|
||||||
('https://picsum.photos/id/237/200/300', 1);
|
-- -- StockQuantity,
|
||||||
|
-- -- UserID,
|
||||||
-- Create another product for recommendations
|
-- -- Description,
|
||||||
INSERT INTO
|
-- -- CategoryID
|
||||||
Product (
|
-- -- )
|
||||||
ProductID,
|
-- -- VALUES
|
||||||
Name,
|
-- -- (
|
||||||
Price,
|
-- -- 2,
|
||||||
StockQuantity,
|
-- -- 'Tablet',
|
||||||
UserID,
|
-- -- 799.99,
|
||||||
Description,
|
-- -- 30,
|
||||||
CategoryID
|
-- -- 1,
|
||||||
)
|
-- -- 'High-performance tablet',
|
||||||
VALUES
|
-- -- 1
|
||||||
(
|
-- -- );
|
||||||
2,
|
-- -- -- Add placeholder images for the second product
|
||||||
'Tablet',
|
-- -- INSERT INTO
|
||||||
799.99,
|
-- -- Image_URL (URL, ProductID)
|
||||||
30,
|
-- -- VALUES
|
||||||
1,
|
-- -- ('https://picsum.photos/id/237/200/300', 2),
|
||||||
'High-performance tablet',
|
-- -- ('https://picsum.photos/id/237/200/300', 2);
|
||||||
1
|
-- -- -- Read Product (SELECT)
|
||||||
);
|
-- -- SELECT
|
||||||
|
-- -- p.*,
|
||||||
-- Add placeholder images for the second product
|
-- -- c.Name as CategoryName,
|
||||||
INSERT INTO
|
-- -- u.Name as SellerName,
|
||||||
Image_URL (URL, ProductID)
|
-- -- i.URL as ImageURL
|
||||||
VALUES
|
-- -- FROM
|
||||||
('https://picsum.photos/id/237/200/300', 2),
|
-- -- Product p
|
||||||
('https://picsum.photos/id/237/200/300', 2);
|
-- -- JOIN Category c ON p.CategoryID = c.CategoryID
|
||||||
|
-- -- JOIN User u ON p.UserID = u.UserID
|
||||||
-- Read Product (SELECT)
|
-- -- LEFT JOIN Image_URL i ON p.ProductID = i.ProductID
|
||||||
SELECT
|
-- -- WHERE
|
||||||
p.*,
|
-- -- p.ProductID = 1;
|
||||||
c.Name as CategoryName,
|
-- -- -- Update Product (UPDATE)
|
||||||
u.Name as SellerName,
|
-- -- UPDATE Product
|
||||||
i.URL as ImageURL
|
-- -- SET
|
||||||
FROM
|
-- -- Name = 'Premium Smartphone',
|
||||||
Product p
|
-- -- Price = 649.99,
|
||||||
JOIN Category c ON p.CategoryID = c.CategoryID
|
-- -- StockQuantity = 45,
|
||||||
JOIN User u ON p.UserID = u.UserID
|
-- -- Description = 'Updated description with new features'
|
||||||
LEFT JOIN Image_URL i ON p.ProductID = i.ProductID
|
-- -- WHERE
|
||||||
WHERE
|
-- -- ProductID = 1;
|
||||||
p.ProductID = 1;
|
-- -- -- CATEGORY CRUD OPERATIONS
|
||||||
|
-- -- -- Create Category (INSERT)
|
||||||
-- Update Product (UPDATE)
|
-- -- INSERT INTO
|
||||||
UPDATE Product
|
-- -- Category (CategoryID, Name)
|
||||||
SET
|
-- -- VALUES
|
||||||
Name = 'Premium Smartphone',
|
-- -- (6, 'Toys & Games');
|
||||||
Price = 649.99,
|
-- -- -- Read Category (SELECT)
|
||||||
StockQuantity = 45,
|
-- -- SELECT
|
||||||
Description = 'Updated description with new features'
|
-- -- *
|
||||||
WHERE
|
-- -- FROM
|
||||||
ProductID = 1;
|
-- -- Category
|
||||||
|
-- -- WHERE
|
||||||
-- CATEGORY CRUD OPERATIONS
|
-- -- CategoryID = 6;
|
||||||
-- Create Category (INSERT)
|
-- -- -- Update Category (UPDATE)
|
||||||
INSERT INTO
|
-- -- UPDATE Category
|
||||||
Category (CategoryID, Name)
|
-- -- SET
|
||||||
VALUES
|
-- -- Name = 'Toys & Children''s Games'
|
||||||
(6, 'Toys & Games');
|
-- -- WHERE
|
||||||
|
-- -- CategoryID = 6;
|
||||||
-- Read Category (SELECT)
|
-- -- -- REVIEW OPERATIONS
|
||||||
SELECT
|
-- -- INSERT INTO
|
||||||
*
|
-- -- Review (ReviewID, UserID, ProductID, Comment, Rating)
|
||||||
FROM
|
-- -- VALUES
|
||||||
Category
|
-- -- (
|
||||||
WHERE
|
-- -- 1,
|
||||||
CategoryID = 6;
|
-- -- 1,
|
||||||
|
-- -- 1,
|
||||||
-- Update Category (UPDATE)
|
-- -- 'Great product, very satisfied with the purchase!',
|
||||||
UPDATE Category
|
-- -- 5
|
||||||
SET
|
-- -- );
|
||||||
Name = 'Toys & Children''s Games'
|
-- -- -- TRANSACTION OPERATIONS
|
||||||
WHERE
|
-- -- INSERT INTO
|
||||||
CategoryID = 6;
|
-- -- Transaction (TransactionID, UserID, ProductID, PaymentStatus)
|
||||||
|
-- -- VALUES
|
||||||
-- REVIEW OPERATIONS
|
-- -- (1, 1, 1, 'Completed');
|
||||||
INSERT INTO
|
-- -- -- HISTORY OPERATIONS
|
||||||
Review (ReviewID, UserID, ProductID, Comment, Rating)
|
-- -- INSERT INTO
|
||||||
VALUES
|
-- -- History (HistoryID, UserID, ProductID)
|
||||||
(
|
-- -- VALUES
|
||||||
1,
|
-- -- (1, 1, 1);
|
||||||
1,
|
-- -- -- Read History (SELECT)
|
||||||
1,
|
-- -- SELECT
|
||||||
'Great product, very satisfied with the purchase!',
|
-- -- h.*,
|
||||||
5
|
-- -- p.Name as ProductName
|
||||||
);
|
-- -- FROM
|
||||||
|
-- -- History h
|
||||||
-- TRANSACTION OPERATIONS
|
-- -- JOIN Product p ON h.ProductID = p.ProductID
|
||||||
INSERT INTO
|
-- -- WHERE
|
||||||
Transaction (TransactionID, UserID, ProductID, PaymentStatus)
|
-- -- h.UserID = 1
|
||||||
VALUES
|
-- -- ORDER BY
|
||||||
(1, 1, 1, 'Completed');
|
-- -- h.Date DESC;
|
||||||
|
-- -- -- FAVORITES OPERATIONS
|
||||||
-- HISTORY OPERATIONS
|
-- -- INSERT INTO
|
||||||
INSERT INTO
|
-- -- Favorites (UserID, ProductID)
|
||||||
History (HistoryID, UserID, ProductID)
|
-- -- VALUES
|
||||||
VALUES
|
-- -- (1, 1);
|
||||||
(1, 1, 1);
|
-- -- -- Read Favorites (SELECT)
|
||||||
|
-- -- SELECT
|
||||||
-- Read History (SELECT)
|
-- -- f.*,
|
||||||
SELECT
|
-- -- p.Name as ProductName,
|
||||||
h.*,
|
-- -- p.Price
|
||||||
p.Name as ProductName
|
-- -- FROM
|
||||||
FROM
|
-- -- Favorites f
|
||||||
History h
|
-- -- JOIN Product p ON f.ProductID = p.ProductID
|
||||||
JOIN Product p ON h.ProductID = p.ProductID
|
-- -- WHERE
|
||||||
WHERE
|
-- -- f.UserID = 1;
|
||||||
h.UserID = 1
|
-- -- -- RECOMMENDATION OPERATIONS
|
||||||
ORDER BY
|
-- -- INSERT INTO
|
||||||
h.Date DESC;
|
-- -- Recommendation (RecommendationID_PK, UserID, RecommendedProductID)
|
||||||
|
-- -- VALUES
|
||||||
-- FAVORITES OPERATIONS
|
-- -- (1, 1, 2);
|
||||||
INSERT INTO
|
-- -- -- Read Recommendations (SELECT)
|
||||||
Favorites (UserID, ProductID)
|
-- -- SELECT
|
||||||
VALUES
|
-- -- r.*,
|
||||||
(1, 1);
|
-- -- p.Name as RecommendedProductName,
|
||||||
|
-- -- p.Price,
|
||||||
-- Read Favorites (SELECT)
|
-- -- p.Description
|
||||||
SELECT
|
-- -- FROM
|
||||||
f.*,
|
-- -- Recommendation r
|
||||||
p.Name as ProductName,
|
-- -- JOIN Product p ON r.RecommendedProductID = p.ProductID
|
||||||
p.Price
|
-- -- WHERE
|
||||||
FROM
|
-- -- r.UserID = 1;
|
||||||
Favorites f
|
-- -- -- Authentication Operations
|
||||||
JOIN Product p ON f.ProductID = p.ProductID
|
-- -- -- Create verification code
|
||||||
WHERE
|
-- -- INSERT INTO
|
||||||
f.UserID = 1;
|
-- -- AuthVerification (Email, VerificationCode)
|
||||||
|
-- -- VALUES
|
||||||
-- RECOMMENDATION OPERATIONS
|
-- -- ('new_user@example.com', '123456');
|
||||||
INSERT INTO
|
-- -- -- Update authentication status
|
||||||
Recommendation (RecommendationID_PK, UserID, RecommendedProductID)
|
-- -- UPDATE AuthVerification
|
||||||
VALUES
|
-- -- SET
|
||||||
(1, 1, 2);
|
-- -- Authenticated = TRUE
|
||||||
|
-- -- WHERE
|
||||||
-- Read Recommendations (SELECT)
|
-- -- Email = 'new_user@example.com'
|
||||||
SELECT
|
-- -- AND VerificationCode = '123456';
|
||||||
r.*,
|
-- -- -- Get top-selling products
|
||||||
p.Name as RecommendedProductName,
|
-- -- SELECT
|
||||||
p.Price,
|
-- -- p.ProductID,
|
||||||
p.Description
|
-- -- p.Name,
|
||||||
FROM
|
-- -- COUNT(t.TransactionID) as SalesCount,
|
||||||
Recommendation r
|
-- -- SUM(p.Price) as TotalRevenue
|
||||||
JOIN Product p ON r.RecommendedProductID = p.ProductID
|
-- -- FROM
|
||||||
WHERE
|
-- -- Product p
|
||||||
r.UserID = 1;
|
-- -- JOIN Transaction t ON p.ProductID = t.ProductID
|
||||||
|
-- -- WHERE
|
||||||
-- Authentication Operations
|
-- -- t.PaymentStatus = 'Completed'
|
||||||
-- Create verification code
|
-- -- GROUP BY
|
||||||
INSERT INTO
|
-- -- p.ProductID,
|
||||||
AuthVerification (Email, VerificationCode)
|
-- -- p.Name
|
||||||
VALUES
|
-- -- ORDER BY
|
||||||
('new_user@example.com', '123456');
|
-- -- SalesCount DESC
|
||||||
|
-- -- LIMIT
|
||||||
-- Update authentication status
|
-- -- 10;
|
||||||
UPDATE AuthVerification
|
-- -- -- Get highest-rated products
|
||||||
SET
|
-- -- SELECT
|
||||||
Authenticated = TRUE
|
-- -- p.ProductID,
|
||||||
WHERE
|
-- -- p.Name,
|
||||||
Email = 'new_user@example.com'
|
-- -- AVG(r.Rating) as AverageRating,
|
||||||
AND VerificationCode = '123456';
|
-- -- COUNT(r.ReviewID) as ReviewCount
|
||||||
|
-- -- FROM
|
||||||
-- Get top-selling products
|
-- -- Product p
|
||||||
SELECT
|
-- -- JOIN Review r ON p.ProductID = r.ProductID
|
||||||
p.ProductID,
|
-- -- GROUP BY
|
||||||
p.Name,
|
-- -- p.ProductID,
|
||||||
COUNT(t.TransactionID) as SalesCount,
|
-- -- p.Name
|
||||||
SUM(p.Price) as TotalRevenue
|
-- -- HAVING
|
||||||
FROM
|
-- -- ReviewCount >= 5
|
||||||
Product p
|
-- -- ORDER BY
|
||||||
JOIN Transaction t ON p.ProductID = t.ProductID
|
-- -- AverageRating DESC
|
||||||
WHERE
|
-- -- LIMIT
|
||||||
t.PaymentStatus = 'Completed'
|
-- -- 10;
|
||||||
GROUP BY
|
-- -- -- Get user purchase history with product details
|
||||||
p.ProductID,
|
-- -- SELECT
|
||||||
p.Name
|
-- -- t.TransactionID,
|
||||||
ORDER BY
|
-- -- t.Date,
|
||||||
SalesCount DESC
|
-- -- p.Name,
|
||||||
LIMIT
|
-- -- p.Price,
|
||||||
10;
|
-- -- t.PaymentStatus
|
||||||
|
-- -- FROM
|
||||||
-- Get highest-rated products
|
-- -- Transaction t
|
||||||
SELECT
|
-- -- JOIN Product p ON t.ProductID = p.ProductID
|
||||||
p.ProductID,
|
-- -- WHERE
|
||||||
p.Name,
|
-- -- t.UserID = 1
|
||||||
AVG(r.Rating) as AverageRating,
|
-- -- ORDER BY
|
||||||
COUNT(r.ReviewID) as ReviewCount
|
-- -- t.Date DESC;
|
||||||
FROM
|
|
||||||
Product p
|
|
||||||
JOIN Review r ON p.ProductID = r.ProductID
|
|
||||||
GROUP BY
|
|
||||||
p.ProductID,
|
|
||||||
p.Name
|
|
||||||
HAVING
|
|
||||||
ReviewCount >= 5
|
|
||||||
ORDER BY
|
|
||||||
AverageRating DESC
|
|
||||||
LIMIT
|
|
||||||
10;
|
|
||||||
|
|
||||||
-- Get user purchase history with product details
|
|
||||||
SELECT
|
|
||||||
t.TransactionID,
|
|
||||||
t.Date,
|
|
||||||
p.Name,
|
|
||||||
p.Price,
|
|
||||||
t.PaymentStatus
|
|
||||||
FROM
|
|
||||||
Transaction t
|
|
||||||
JOIN Product p ON t.ProductID = p.ProductID
|
|
||||||
WHERE
|
|
||||||
t.UserID = 1
|
|
||||||
ORDER BY
|
|
||||||
t.Date DESC;
|
|
||||||
|
|||||||
3
SQL_code/init-db.py
Normal file
3
SQL_code/init-db.py
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
import subprocess
|
||||||
|
if (subprocess.run("mysql -u root mysql < SQL_code/Schema.sql", shell=True, check=True)):
|
||||||
|
print("successfully created the Marketplace databse")
|
||||||
@@ -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({
|
||||||
@@ -194,37 +194,47 @@ exports.findUserByEmail = async (req, res) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
exports.updateUser = async (req, res) => {
|
exports.updateUser = async (req, res) => {
|
||||||
const { userId, ...updateData } = req.body;
|
try {
|
||||||
|
const userId = req.body?.userId;
|
||||||
|
const name = req.body?.name;
|
||||||
|
const email = req.body?.email;
|
||||||
|
const phone = req.body?.phone;
|
||||||
|
const UCID = req.body?.UCID;
|
||||||
|
const address = req.body?.address;
|
||||||
|
|
||||||
if (!userId) {
|
if (!userId) {
|
||||||
return res.status(400).json({ error: "User ID is required" });
|
return res.status(400).json({ error: "User ID is required" });
|
||||||
}
|
}
|
||||||
|
|
||||||
//query dynamically based on provided fields
|
// Build updateData manually
|
||||||
const updateFields = [];
|
const updateData = {};
|
||||||
const values = [];
|
if (name) updateData.name = name;
|
||||||
|
if (email) updateData.email = email;
|
||||||
|
if (phone) updateData.phone = phone;
|
||||||
|
if (UCID) updateData.UCID = UCID;
|
||||||
|
if (address) updateData.address = address;
|
||||||
|
|
||||||
Object.entries(updateData).forEach(([key, value]) => {
|
if (Object.keys(updateData).length === 0) {
|
||||||
// Only include fields that are actually in the User table
|
return res.status(400).json({ error: "No valid fields to update" });
|
||||||
if (["Name", "Email", "Password", "Phone", "UCID"].includes(key)) {
|
}
|
||||||
|
|
||||||
|
const updateFields = [];
|
||||||
|
const values = [];
|
||||||
|
|
||||||
|
Object.entries(updateData).forEach(([key, value]) => {
|
||||||
updateFields.push(`${key} = ?`);
|
updateFields.push(`${key} = ?`);
|
||||||
values.push(value);
|
values.push(value);
|
||||||
}
|
});
|
||||||
});
|
|
||||||
|
|
||||||
if (updateFields.length === 0) {
|
values.push(userId);
|
||||||
return res.status(400).json({ error: "No valid fields to update" });
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add userId to values array
|
const query = `UPDATE User SET ${updateFields.join(", ")} WHERE userId = ?`;
|
||||||
values.push(userId);
|
|
||||||
|
|
||||||
try {
|
|
||||||
const query = `UPDATE User SET ${updateFields.join(", ")} WHERE UserID = ?`;
|
|
||||||
const [updateResult] = await db.execute(query, values);
|
const [updateResult] = await db.execute(query, values);
|
||||||
|
|
||||||
if (updateResult.affectedRows === 0) {
|
if (updateResult.affectedRows === 0) {
|
||||||
return res.status(404).json({ error: "User not found" });
|
return res.status(404).json({ error: "User not found" });
|
||||||
}
|
}
|
||||||
|
|
||||||
res.json({ success: true, message: "User updated successfully" });
|
res.json({ success: true, message: "User updated successfully" });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error updating user:", error);
|
console.error("Error updating user:", error);
|
||||||
@@ -243,7 +253,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
|
||||||
|
|||||||
@@ -2,11 +2,10 @@ const mysql = require("mysql2");
|
|||||||
|
|
||||||
//Create a pool of connections to allow multiple query happen at the same time
|
//Create a pool of connections to allow multiple query happen at the same time
|
||||||
const pool = mysql.createPool({
|
const pool = mysql.createPool({
|
||||||
host: "marketplace-db.cpkkqmq065sx.ca-central-1.rds.amazonaws.com",
|
host: "localhost",
|
||||||
user: "admin",
|
user: "root",
|
||||||
password: "qizsYh-movpub-wuhdo2",
|
database: "marketplace",
|
||||||
database: "Marketplace",
|
password: "12345678",
|
||||||
port: "3306",
|
|
||||||
});
|
});
|
||||||
|
|
||||||
//Export a promise for promise-based query
|
//Export a promise for promise-based query
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ const Settings = () => {
|
|||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
email: storedUser.email,
|
email: storedUser.email,
|
||||||
}),
|
}),
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
const data = await response.json();
|
const data = await response.json();
|
||||||
@@ -53,7 +53,7 @@ const Settings = () => {
|
|||||||
// Update state with fetched data
|
// Update state with fetched data
|
||||||
setUserData((prevData) => ({
|
setUserData((prevData) => ({
|
||||||
...prevData,
|
...prevData,
|
||||||
userId: data.userId || storedUser.id || "", // Try both sources
|
userId: storedUser.ID, // Try both sources
|
||||||
name: data.name || storedUser.name || "",
|
name: data.name || storedUser.name || "",
|
||||||
email: data.email || storedUser.email || "",
|
email: data.email || storedUser.email || "",
|
||||||
UCID: data.UCID || storedUser.UCID || "",
|
UCID: data.UCID || storedUser.UCID || "",
|
||||||
@@ -70,7 +70,7 @@ const Settings = () => {
|
|||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error fetching user data:", error);
|
console.error("Error fetching user data:", error);
|
||||||
setError(
|
setError(
|
||||||
error.message || "An error occurred while loading your profile"
|
error.message || "An error occurred while loading your profile",
|
||||||
);
|
);
|
||||||
} finally {
|
} finally {
|
||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
@@ -88,27 +88,39 @@ const Settings = () => {
|
|||||||
}));
|
}));
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleProfileUpdate = async (e) => {
|
const handleUpdateProfile = async () => {
|
||||||
e.preventDefault();
|
|
||||||
try {
|
try {
|
||||||
// TODO: Implement the actual update API call
|
// Ensure userId is present
|
||||||
console.log("Profile updated:", userData);
|
if (!userData.userId) {
|
||||||
|
throw new Error("User ID is missing. Unable to update profile.");
|
||||||
|
}
|
||||||
|
|
||||||
// Update localStorage with new user data
|
setIsLoading(true);
|
||||||
const storedUser = JSON.parse(localStorage.getItem("user"));
|
setError(null);
|
||||||
const updatedUser = {
|
|
||||||
...storedUser,
|
|
||||||
name: userData.name,
|
|
||||||
phone: userData.phone,
|
|
||||||
UCID: userData.UCID,
|
|
||||||
address: userData.address,
|
|
||||||
};
|
|
||||||
localStorage.setItem("user", JSON.stringify(updatedUser));
|
|
||||||
|
|
||||||
|
const response = await fetch("http://localhost:3030/api/user/update", {
|
||||||
|
method: "POST", // or "PUT" if your backend supports it
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
},
|
||||||
|
body: JSON.stringify(userData),
|
||||||
|
});
|
||||||
|
|
||||||
|
const result = await response.json();
|
||||||
|
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error(result.error || "Failed to update profile");
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log("Profile updated successfully:", result);
|
||||||
alert("Profile updated successfully!");
|
alert("Profile updated successfully!");
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error updating profile:", error);
|
console.error("Error updating profile:", error);
|
||||||
alert("Failed to update profile: " + error.message);
|
setError(
|
||||||
|
error.message || "An error occurred while updating your profile.",
|
||||||
|
);
|
||||||
|
} finally {
|
||||||
|
setIsLoading(false);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -156,7 +168,7 @@ const Settings = () => {
|
|||||||
const handleDeleteAccount = async () => {
|
const handleDeleteAccount = async () => {
|
||||||
if (
|
if (
|
||||||
window.confirm(
|
window.confirm(
|
||||||
"Are you sure you want to delete your account? This action cannot be undone."
|
"Are you sure you want to delete your account? This action cannot be undone.",
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
try {
|
try {
|
||||||
@@ -232,7 +244,7 @@ const Settings = () => {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="p-4">
|
<div className="p-4">
|
||||||
<form onSubmit={handleProfileUpdate}>
|
<form onSubmit={handleUpdateProfile}>
|
||||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-4 mb-4">
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-4 mb-4">
|
||||||
<div>
|
<div>
|
||||||
<label
|
<label
|
||||||
|
|||||||
Reference in New Issue
Block a user