diff --git a/config/database.js b/config/database.js index 861c9bd6b67a2363592909c45ee4089706a45119..242954d649f85b43cb5149577de5478f63895816 100644 --- a/config/database.js +++ b/config/database.js @@ -11,7 +11,6 @@ const pool = mysql.createPool({ queueLimit: 0 }); -// ๐”น เธ—เธ”เธชเธญเธเธเธฒเธฃเน€เธเธทเนเธญเธกเธ•เนเธญเธเธฒเธเธเนเธญเธกเธนเธฅ (async () => { try { const connection = await pool.getConnection(); diff --git a/server.js b/server.js index 6341394ffd81d8b42462072b9e13c2b365f57bcb..26ff7e53ecee951128f17d871a319fc5ce792e95 100644 --- a/server.js +++ b/server.js @@ -113,7 +113,7 @@ app.post("/login", async (req, res) => { req.session.user = { id: user.id, email: user.email }; - req.session.save(err => { //เธเธฑเธเธ—เธถเธ Session เธเนเธญเธ Redirect + req.session.save(err => { if (err) { console.error("Session save error:", err); return res.send("Session save failed."); @@ -143,7 +143,7 @@ app.get("/search", async (req, res) => { app.get("/cart", isLoggedIn, async (req, res) => { try { - // เธ”เธถเธเธฃเธฒเธขเธเธฒเธฃเธชเธดเธเธเนเธฒเนเธเธ•เธฐเธเธฃเนเธฒเธเธฒเธเธเธฒเธเธเนเธญเธกเธนเธฅ + const [cartItems] = await pool.execute(` SELECT c.id, p.name, p.price, c.quantity, p.stock, p.image FROM cart_items c @@ -151,7 +151,7 @@ app.get("/cart", isLoggedIn, async (req, res) => { WHERE c.user_id = ? `, [req.session.user.id]); - // เธเธณเธเธงเธ“เธขเธญเธ”เธฃเธงเธก + const total = cartItems.reduce((sum, item) => sum + item.price * item.quantity, 0); res.render("cart", { cartItems, total }); @@ -170,20 +170,20 @@ app.post("/cart/add", async (req, res) => { const userId = req.session.user.id; try { - // เน€เธเนเธเธงเนเธฒเธชเธดเธเธเนเธฒเธกเธตเธญเธขเธนเนเนเธเธ•เธฐเธเธฃเนเธฒเธซเธฃเธทเธญเธขเธฑเธ + const [existingCart] = await pool.execute( "SELECT * FROM cart_items WHERE user_id = ? AND product_id = ?", [userId, productId] ); if (existingCart.length > 0) { - // เธ–เนเธฒเธกเธตเธชเธดเธเธเนเธฒเธญเธขเธนเนเนเธฅเนเธง เนเธซเนเน€เธเธดเนเธกเธเธณเธเธงเธ + await pool.execute( "UPDATE cart_items SET quantity = quantity + ? WHERE user_id = ? AND product_id = ?", [quantity, userId, productId] ); } else { - // เธ–เนเธฒเนเธกเนเธกเธตเธชเธดเธเธเนเธฒ เนเธซเนเน€เธเธดเนเธกเนเธซเธกเน + await pool.execute( "INSERT INTO cart_items (user_id, product_id, quantity) VALUES (?, ?, ?)", [userId, productId, quantity] @@ -222,7 +222,7 @@ app.get('/order/checkout', isLoggedIn, (req, res) => { app.get("/logout", (req, res) => { req.session.destroy(err => { if (err) return res.status(500).json({ message: "Logout failed." }); - res.clearCookie('connect.sid', { path: '/' }); // เน€เธเธฅเธตเธขเธฃเน Cookie เธญเธขเนเธฒเธเธ–เธนเธเธ•เนเธญเธ + res.clearCookie('connect.sid', { path: '/' }); res.redirect("/login"); }); }); diff --git a/shop-routes/auth.js b/shop-routes/auth.js index 0dc181c10eaa939c54db38f4666d1142a9b06016..4221530ba7b894013d9cc0e42f6c9d04d245c28a 100644 --- a/shop-routes/auth.js +++ b/shop-routes/auth.js @@ -10,7 +10,7 @@ async function checkUser(email, password) { const [rows] = await pool.query('SELECT * FROM users WHERE email = ?', [email]); if (rows.length > 0) { const user = rows[0]; - const match = await bcrypt.compare(password, user.password); // เธ•เธฃเธงเธเธชเธญเธเธฃเธซเธฑเธชเธเนเธฒเธ + const match = await bcrypt.compare(password, user.password); return match ? user : null; } return null; @@ -18,7 +18,7 @@ async function checkUser(email, password) { // Route เธชเธณเธซเธฃเธฑเธเนเธชเธ”เธเธซเธเนเธฒ Login (GET) router.get('/login', (req, res) => { - res.render('login'); // เธ•เนเธญเธเธกเธตเนเธเธฅเน login.ejs เนเธเนเธเธฅเน€เธ”เธญเธฃเน views + res.render('login'); }); // Route เธชเธณเธซเธฃเธฑเธ Login (POST) @@ -28,8 +28,7 @@ router.post('/login', async (req, res) => { if (user) { req.session.user = { id: user.id, email: user.email }; - req.session.session_id = req.sessionID; // เธเธฑเธเธ—เธถเธ session_id - + req.session.session_id = req.sessionID; req.session.save(err => { if (err) { console.error("Session save error:", err); diff --git a/shop-routes/cart.js b/shop-routes/cart.js index 8fc009d586f7a554757a536b25ed8ae73973daef..12dedc388c50bfcdcc39fd096cfc551f7ba3c584 100644 --- a/shop-routes/cart.js +++ b/shop-routes/cart.js @@ -49,14 +49,13 @@ router.post('/add', async (req, res) => { return res.status(400).send('เธชเธดเธเธเนเธฒเธกเธตเธเธณเธเธงเธเนเธกเนเน€เธเธตเธขเธเธเธญ'); } - // เธ•เธฃเธงเธเธชเธญเธเธงเนเธฒเธชเธดเธเธเนเธฒเธเธตเนเธกเธตเธญเธขเธนเนเนเธเธ•เธฐเธเธฃเนเธฒเธซเธฃเธทเธญเธขเธฑเธ const [[existingItem]] = await pool.query( 'SELECT id, quantity FROM cart_items WHERE session_id = ? AND product_id = ?', [req.session.id, productId] ); if (existingItem) { - // เธญเธฑเธเน€เธ”เธ•เธเธณเธเธงเธเธชเธดเธเธเนเธฒ + const newQuantity = existingItem.quantity + parseInt(quantity); if (newQuantity > product.stock) { return res.status(400).send('เธชเธดเธเธเนเธฒเธกเธตเธเธณเธเธงเธเนเธกเนเน€เธเธตเธขเธเธเธญ'); @@ -66,7 +65,7 @@ router.post('/add', async (req, res) => { [newQuantity, existingItem.id] ); } else { - // เน€เธเธดเนเธกเธชเธดเธเธเนเธฒเนเธซเธกเน + await pool.query( 'INSERT INTO cart_items (session_id, product_id, quantity) VALUES (?, ?, ?)', [req.session.id, productId, parseInt(quantity)] @@ -130,7 +129,7 @@ router.post('/remove', async (req, res) => { router.get('/cart', (req, res) => { const cartItems = req.session.cart || []; - const editingItemId = req.session.editingItemId || null; // เธ–เนเธฒเนเธกเนเธกเธตเธเธฒเธฃเนเธเนเนเธเธเนเน€เธเนเธ null + const editingItemId = req.session.editingItemId || null; res.render('cart', { cartItems, total: calculateTotal(cartItems), editingItemId }); }); diff --git a/shop-routes/index.js b/shop-routes/index.js index 89da7722f6104d7f8fbaa553fa7e419fad7538fa..6cf1cdeca3db87f18ce6f0825a0778c56e86ff44 100644 --- a/shop-routes/index.js +++ b/shop-routes/index.js @@ -34,10 +34,10 @@ router.post('/add-to-cart', async (req, res) => { if (req.session.editingItemId) { console.log("Replacing Item ID:", req.session.editingItemId); - // เธฅเธเธชเธดเธเธเนเธฒเธ—เธตเนเธ•เนเธญเธเธเธฒเธฃเน€เธเธฅเธตเนเธขเธเธญเธญเธ + req.session.cart = req.session.cart.filter(item => item.id !== req.session.editingItemId); - // เน€เธเธดเนเธกเธชเธดเธเธเนเธฒเธ•เธฑเธงเนเธซเธกเนเน€เธเนเธฒเนเธ + req.session.cart.push({ id: product.id, name: product.name, @@ -48,11 +48,11 @@ router.post('/add-to-cart', async (req, res) => { console.log("After Editing:", req.session.cart); - req.session.editingItemId = null; // เธฅเนเธฒเธเธเนเธฒเธซเธฅเธฑเธเน€เธเธฅเธตเนเธขเธเธชเธดเธเธเนเธฒเน€เธชเธฃเนเธ + req.session.editingItemId = null; } else { console.log("Adding New Item"); - // เน€เธเธดเนเธกเธชเธดเธเธเนเธฒเธ•เธฒเธกเธเธเธ•เธด + req.session.cart.push({ id: product.id, name: product.name, @@ -63,7 +63,7 @@ router.post('/add-to-cart', async (req, res) => { } console.log("Final Cart:", req.session.cart); - res.redirect('/cart'); // เธเธฅเธฑเธเนเธเธซเธเนเธฒเธ•เธฐเธเธฃเนเธฒ + res.redirect('/cart'); } catch (error) { console.error(error); res.status(500).send('Error adding product to cart'); diff --git a/shop-routes/product.js b/shop-routes/product.js index 05112684c70e02c5ca4e61371183221c3309338b..91ed28a2cfc372448a427cb6d6309aafec47f222 100644 --- a/shop-routes/product.js +++ b/shop-routes/product.js @@ -19,12 +19,12 @@ const storage = multer.diskStorage({ cb(null, uploadDir); }, filename: (req, file, cb) => { - cb(null, Date.now() + path.extname(file.originalname)); // เธ•เธฑเนเธเธเธทเนเธญเนเธเธฅเนเน€เธเนเธ timestamp + cb(null, Date.now() + path.extname(file.originalname)); } }); const upload = multer({ storage: storage }); -// เธ”เธถเธเธชเธดเธเธเนเธฒเธ—เธฑเนเธเธซเธกเธ” + router.get("/", async (req, res) => { try { const [products] = await pool.execute("SELECT * FROM products"); @@ -35,12 +35,12 @@ router.get("/", async (req, res) => { } }); -// เนเธชเธ”เธเธเธญเธฃเนเธกเน€เธเธดเนเธกเธชเธดเธเธเนเธฒ + router.get("/add", (req, res) => { res.render("product_add", { product: {}, message: "" }); }); -// เน€เธเธดเนเธกเธชเธดเธเธเนเธฒเนเธซเธกเนเธเธฃเนเธญเธกเธฃเธนเธ + router.post("/add", upload.single("image"), async (req, res) => { try { console.log("Debugging Data:", req.body); @@ -65,7 +65,7 @@ router.post("/add", upload.single("image"), async (req, res) => { }); -// เธ”เธถเธเธเนเธญเธกเธนเธฅเธชเธดเธเธเนเธฒเธ•เธฒเธก ID เนเธฅเธฐเนเธชเธ”เธเธซเธเนเธฒเนเธเนเนเธ + router.get("/edit/:id", async (req, res) => { try { const [rows] = await pool.execute("SELECT * FROM products WHERE id = ?", [req.params.id]); @@ -79,13 +79,13 @@ router.get("/edit/:id", async (req, res) => { } }); -// เธญเธฑเธเน€เธ”เธ•เธเนเธญเธกเธนเธฅเธชเธดเธเธเนเธฒ + router.post("/edit/:id", upload.single("image"), async (req, res) => { try { const { name, price, stock, description } = req.body; - let imagePath = req.body.oldImage; // เนเธเนเธฃเธนเธเน€เธ”เธดเธกเธ–เนเธฒเนเธกเนเธกเธตเธเธฒเธฃเธญเธฑเธเนเธซเธฅเธ”เนเธซเธกเน + let imagePath = req.body.oldImage; - // เธ–เนเธฒเธกเธตเธเธฒเธฃเธญเธฑเธเนเธซเธฅเธ”เธฃเธนเธเนเธซเธกเน เนเธซเนเนเธเนเนเธเธฅเนเนเธซเธกเน + if (req.file) { imagePath = "/uploads/" + req.file.filename; } @@ -104,23 +104,23 @@ router.post("/edit/:id", upload.single("image"), async (req, res) => { ] ); - res.redirect("/products"); // เธเธฅเธฑเธเนเธเธขเธฑเธเธซเธเนเธฒเธฃเธฒเธขเธเธฒเธฃเธชเธดเธเธเนเธฒ + res.redirect("/products"); } catch (error) { console.error("Error updating product:", error); res.status(500).send("Error updating product."); } }); -// เธฅเธเธชเธดเธเธเนเธฒ + router.post("/delete/:id", async (req, res) => { try { const productId = req.params.id; - // เธฅเธเธชเธดเธเธเนเธฒเธญเธญเธเธเธฒเธเธเธฒเธเธเนเธญเธกเธนเธฅ + await pool.execute("DELETE FROM products WHERE id = ?", [productId]); console.log("Product deleted successfully!"); - res.redirect("/products"); // เธเธฅเธฑเธเนเธเธขเธฑเธเธซเธเนเธฒเธฃเธฒเธขเธเธฒเธฃเธชเธดเธเธเนเธฒ + res.redirect("/products"); } catch (error) { console.error("Error deleting product:", error); res.status(500).send("Error deleting product."); diff --git a/views/cart.ejs b/views/cart.ejs index 1ea6221297b0817cb8c6da789f874cab3b0cbb86..95366a3e208fa6f9dc46d652c14b42c29b5f3439 100644 --- a/views/cart.ejs +++ b/views/cart.ejs @@ -35,7 +35,7 @@ </button> </form> - <!-- เธเธธเนเธก Remove (เนเธชเธ”เธเธ•เธฅเธญเธ”) --> + <form action="/cart/remove" method="POST"> <input type="hidden" name="cartItemId" value="<%= item.id %>"> <button type="submit" class="back-btn" style="margin: 0; padding: 0.5rem 1rem; background-color: red;"> @@ -60,7 +60,7 @@ <script> document.querySelectorAll(".update-btn").forEach(button => { button.addEventListener("click", async (event) => { - event.stopPropagation(); // เธเนเธญเธเธเธฑเธเธเธฒเธฃเธฃเธเธเธงเธเธเธฑเธเธเธธเนเธกเธญเธทเนเธ + event.stopPropagation(); //เธเนเธญเธเธเธฑเธเธเธฒเธฃเธฃเธเธเธงเธเธเธฑเธเธเธธเนเธกเธญเธทเนเธ const cartItem = event.target.closest(".cart-item"); const cartItemId = cartItem.dataset.id; const quantity = cartItem.querySelector("input[name='quantity']").value; @@ -72,7 +72,7 @@ }); if (response.ok) { - window.location.reload(); // เธฃเธตเน€เธเธฃเธเธซเธเนเธฒเธซเธฅเธฑเธเธญเธฑเธเน€เธ”เธ• + window.location.reload(); //เธฃเธตเน€เธเธฃเธเธซเธเนเธฒเธซเธฅเธฑเธเธญเธฑเธเน€เธ”เธ• } else { alert("Failed to update cart."); } diff --git a/views/login.ejs b/views/login.ejs index 5f6b531138e4a756337b1244f5463f697fa21ada..5f3e1dda6f819471ae6d6fad936db5b2400f42a9 100644 --- a/views/login.ejs +++ b/views/login.ejs @@ -4,7 +4,7 @@ <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Login</title> - <link rel="stylesheet" href="/css/style.css"> <!-- เน€เธเธทเนเธญเธกเธ•เนเธญ CSS --> + <link rel="stylesheet" href="/css/style.css"> </head> <body> <div class="auth-container"> diff --git a/views/partials/header.ejs b/views/partials/header.ejs index 25772c7a489f85f3f19b4d9ee5f9919de7757788..346dbc2631e4fbfbe712674ddd8f6c025fc020ad 100644 --- a/views/partials/header.ejs +++ b/views/partials/header.ejs @@ -7,7 +7,6 @@ <nav> <div class="container"> <a href="/" class="logo">E-commerce FishStore</a> - <!-- เน€เธเธดเนเธกเนเธ–เธเธเนเธเธซเธฒ --> <form action="/search" method="GET" class="search-form"> <input type="text" name="query" placeholder="Search for fish..." required> <button type="submit">Search</button>