diff --git a/controllers/cartController.js b/controllers/cartController.js new file mode 100644 index 0000000000000000000000000000000000000000..fc226f55e0cb919ec0c1944280e0ed3e4a72bd63 --- /dev/null +++ b/controllers/cartController.js @@ -0,0 +1,86 @@ +const pool = require('../db'); + +exports.addToCart = (req, res) => { + const { product_id, price } = req.body; + const quantity = parseInt(req.body.quantity) || 1; + + if (!req.session.cart) { + req.session.cart = []; + } + + const existingProduct = req.session.cart.find(item => item.product_id === product_id); + if (existingProduct) { + existingProduct.quantity += quantity; + } else { + req.session.cart.push({ product_id, quantity, price }); + } + + res.redirect('/cart'); +}; + +exports.viewCart = async (req, res) => { + const cart = req.session.cart || []; + + if (cart.length === 0) { + return res.render('cart', { cart: [], products: [] }); + } + + const productIds = cart.map(item => item.product_id); + try { + const [products] = await pool.query('SELECT * FROM products WHERE product_id IN (?)', [productIds]); + + // ผูกข้อมูลสินค้าเข้ากับตะกร้า + const cartWithDetails = cart.map(item => { + const product = products.find(p => p.product_id == item.product_id); + return { ...item, product_name: product.product_name, image: product.image }; + }); + + res.render('cart', { cart: cartWithDetails }); + } catch (err) { + res.status(500).send('เกิดข้อผิดพลาดในการโหลดตะกร้าสินค้า: ' + err.message); + } +}; + +exports.removeFromCart = (req, res) => { + const product_id = req.params.id; + req.session.cart = req.session.cart.filter(item => item.product_id !== product_id); + res.redirect('/cart'); +}; + +exports.checkout = async (req, res) => { + if (!req.session.userIdEmail) { + return res.status(401).send('กรุณาเข้าสู่ระบบก่อนทำการสั่งซื้อ'); + } + + const cart = req.session.cart || []; + if (cart.length === 0) { + return res.redirect('/cart'); + } + + try { + const totalAmount = cart.reduce((sum, item) => sum + item.price * item.quantity, 0); + const userEmail = req.session.userIdEmail; + + // ดึง user_id จาก email + const [user] = await pool.query('SELECT id FROM users WHERE email = ?', [userEmail]); + if (user.length === 0) { + return res.status(404).send('ไม่พบผู้ใช้งาน'); + } + const userId = user[0].id; + + // สร้างคำสั่งซื้อใน Orders + const [orderResult] = await pool.query('INSERT INTO orders (user_id, total_amount) VALUES (?, ?)', [userId, totalAmount]); + const orderId = orderResult.insertId; + + // เพิ่มรายการสินค้าลงใน Order_Items + const orderItems = cart.map(item => [orderId, item.product_id, item.quantity, item.price]); + await pool.query('INSERT INTO order_items (order_id, book_id, quantity, price) VALUES ?', [orderItems]); + + // ล้างตะกร้าหลังจาก Checkout สำเร็จ + req.session.cart = []; + + res.redirect('/orderConfirmation'); + } catch (err) { + res.status(500).send('เกิดข้อผิดพลาดในการสั่งซื้อ: ' + err.message); + } +}; \ No newline at end of file diff --git a/controllers/productController.js b/controllers/productController.js index e202f1c7861662bceabe5722f66cb3b43e8515d0..eb0b38e75f5749c0d30ec9baa86757472aca45c9 100644 --- a/controllers/productController.js +++ b/controllers/productController.js @@ -16,6 +16,44 @@ exports.createProduct = async (req, res) => { } }; + +exports.showUpdateProductForm = async (req, res) => { + const productId = req.params.id; + try { + const [rows] = await pool.query('SELECT * FROM products WHERE product_id = ?', [productId]); + if (rows.length === 0) { + return res.status(404).send('ไม่พบสินค้านี้'); + } + res.render('editProduct', { product: rows[0] }); + } catch (err) { + res.status(500).send('เกิดข้อผิดพลาดในการโหลดข้อมูลสินค้า: ' + err.message); + } +}; + + exports.updateProduct = async (req, res) => { + const productId = req.params.id; + const { product_name, price, image, description } = req.body; + const currentUserEmail = req.session.userIdEmail; + + try { + const [rows] = await pool.query('SELECT * FROM products WHERE product_id = ?', [productId]); + if (rows.length === 0) { + return res.status(404).send('ไม่พบสินค้านี้'); + } + const product = rows[0]; + if (product.owner !== currentUserEmail) { + return res.status(403).send('คุณไม่มีสิทธิ์แก้ไขสินค้านี้'); + } + + const sql = 'UPDATE products SET product_name = ?, price = ?, image = ?, description = ? WHERE product_id = ?'; + await pool.query(sql, [product_name, price, image, description, productId]); + + res.redirect('/'); + } catch (err) { + res.status(500).send('เกิดข้อผิดพลาดในการอัปเดตสินค้า: ' + err.message); + } +}; + exports.deleteProduct = async (req, res) => { const productId = req.params.id; const currentUserEmail = req.session.userIdEmail; @@ -37,4 +75,57 @@ exports.createProduct = async (req, res) => { res.status(500).send('Database error: ' + err.message); } }; + + exports.searchProducts = async (req, res) => { + const searchQuery = req.query.q; // รับค่าค้นหาจาก query parameter + try { + const sql = 'SELECT * FROM products WHERE product_name LIKE ?'; + const [rows] = await pool.query(sql, [`%${searchQuery}%`]); // ค้นหาชื่อสินค้าที่คล้ายกัน + + res.render('searchResults', { products: rows, searchQuery }); // ส่งผลลัพธ์ไปยังหน้า searchResults.ejs + } catch (err) { + res.status(500).send('เกิดข้อผิดพลาดในการค้นหา: ' + err.message); + } +}; + +exports.orderHistory = async (req, res) => { + if (!req.session.userIdEmail) { + return res.status(401).send('กรุณาเข้าสู่ระบบเพื่อดูประวัติการสั่งซื้อ'); + } + + try { + const userEmail = req.session.userIdEmail; + + // ดึง user_id จาก email + const [user] = await pool.query('SELECT id FROM users WHERE email = ?', [userEmail]); + if (user.length === 0) { + return res.status(404).send('ไม่พบผู้ใช้งาน'); + } + const userId = user[0].id; + + // ดึงคำสั่งซื้อทั้งหมดของผู้ใช้ + const [orders] = await pool.query( + 'SELECT * FROM orders WHERE user_id = ? ORDER BY created_at DESC', + [userId] + ); + + // ดึงรายการสินค้าสำหรับแต่ละคำสั่งซื้อ + for (let order of orders) { + const [items] = await pool.query( + `SELECT oi.*, p.product_name, p.image + FROM order_items oi + JOIN products p ON oi.book_id = p.product_id + WHERE oi.order_id = ?`, + [order.order_id] + ); + order.items = items; + } + + res.render('orderHistory', { orders }); + } catch (err) { + res.status(500).send('เกิดข้อผิดพลาดในการดึงประวัติการสั่งซื้อ: ' + err.message); + } +}; + + \ No newline at end of file diff --git a/index.js b/index.js index 2e4a8e83d9576504e46c371c37ad69a93ec979ce..04b21591e84f81f441d3e7bcdf8e86b27b3a0b0a 100644 --- a/index.js +++ b/index.js @@ -26,6 +26,7 @@ const loginController = require('./controllers/loginController'); const registerController = require('./controllers/registerController'); const logoutController = require('./controllers/logoutController'); const productController = require('./controllers/productController'); +const cartController = require('./controllers/cartController'); app.get('/', indexController.getProducts); app.get('/login', loginController.showLoginPage); @@ -38,6 +39,17 @@ app.get('/product/:id', indexController.getProductDetail); app.get('/addProduct', productController.showAddProductForm); app.post('/addProduct', productController.createProduct); app.post('/delete_product/:id', productController.deleteProduct); +app.get('/products/:id/edit', productController.showUpdateProductForm); +app.post('/products/:id/update', productController.updateProduct); +app.get('/search', productController.searchProducts); +app.post('/cart/add', cartController.addToCart); +app.get('/cart', cartController.viewCart); +app.post('/cart/remove/:id', cartController.removeFromCart); +app.post('/checkout', cartController.checkout); +app.get('/orderConfirmation', (req,res) => { + res.render('orderConfirmation'); +}); +app.get('/orderHistory', productController.orderHistory); const port = process.env.PORT || 3000; app.listen(port, () => { diff --git a/views/cart.ejs b/views/cart.ejs new file mode 100644 index 0000000000000000000000000000000000000000..3bba7f04666f9a1e8182fe7a9b2a1132b09e1db3 --- /dev/null +++ b/views/cart.ejs @@ -0,0 +1,38 @@ +<h2>ตะกร้าสินค้าของคุณ</h2> + +<% if (cart.length > 0) { %> + <table border="1"> + <tr> + <th>รูปสินค้า</th> + <th>ชื่อสินค้า</th> + <th>จำนวน</th> + <th>ราคา</th> + <th>รวม</th> + <th>ลบ</th> + </tr> + <% cart.forEach(item => { %> + <tr> + <td><img src="<%= item.image %>" width="50"></td> + <td><%= item.product_name %></td> + <td><%= item.quantity %></td> + <td><%= item.price %> บาท</td> + <td><%= (item.price * item.quantity).toFixed(2) %> บาท</td> + <td> + <form action="/cart/remove/<%= item.product_id %>" method="POST"> + <button type="submit">ลบ</button> + </form> + </td> + </tr> + <% }) %> + </table> + + <h3>ยอดรวม: <%= cart.reduce((sum, item) => sum + item.price * item.quantity, 0).toFixed(2) %> บาท</h3> + + <form action="/checkout" method="POST"> + <button type="submit">ยืนยันคำสั่งซื้อ</button> + </form> +<% } else { %> + <p>ไม่มีสินค้าในตะกร้า</p> +<% } %> + +<a href="/">กลับไปซื้อสินค้า</a> diff --git a/views/editProduct.ejs b/views/editProduct.ejs new file mode 100644 index 0000000000000000000000000000000000000000..e303b0a5ebb25d9537838f5d9d463b1a9902d9bd --- /dev/null +++ b/views/editProduct.ejs @@ -0,0 +1,27 @@ +<!DOCTYPE html> +<html lang="en"> +<head> + <meta charset="UTF-8"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <title>เพิ่มสินค้าใหม่</title> +</head> +<body> + <h1>เพิ่มสินค้าใหม่</h1> + <form action="/products/<%= product.product_id %>/update" method="POST"> + <label>ชื่อสินค้า:</label> + <input type="text" name="product_name" value="<%= product.product_name %>" required> + + <label>ราคา:</label> + <input type="number" name="price" value="<%= product.price %>" required> + + <label>ลิงก์รูปภาพ:</label> + <input type="text" name="image" value="<%= product.image %>"> + + <label>รายละเอียด:</label> + <textarea name="description" required><%= product.description %></textarea> + + <button type="submit">บันทึกการแก้ไข</button> +</form> + <a href="/">กลับหน้าหลัก</a> +</body> +</html> \ No newline at end of file diff --git a/views/index.ejs b/views/index.ejs index 0d1212e2ef092937169b11f8ddbbdaebd5932a53..acdc57e8b74e2c85b6c1fae0654e312f935f1702 100644 --- a/views/index.ejs +++ b/views/index.ejs @@ -45,13 +45,13 @@ <li class="nav-item active"> <a class="nav-link" href="/">Home</a> </li> + <% if (loggedIn) { %> <li class="nav-item"> - <a class="nav-link" href="about.html">About Us</a> + <a class="nav-link" href="/orderHistory">History</a> </li> <li class="nav-item"> - <a class="nav-link" href="gallery.html">Gallery</a> - </li> - <% if (loggedIn) { %> + <a class="nav-link" href="/cart">cart</a> + </li> <li class="nav-item"> <a class="nav-link" href="/addProduct">create</a> </li> @@ -76,6 +76,13 @@ </div> </div> <!--header section end --> + <!--header search start --> + <form action="/search" method="GET"> + <input type="text" name="q" placeholder="ค้นหาสินค้า..." required> + <button type="submit">ค้นหา</button> + </form> + <!--header search end --> + <!-- gallery section start --> <div class="gallery_section layout_padding"> <div class="container"> diff --git a/views/orderConfirmation.ejs b/views/orderConfirmation.ejs new file mode 100644 index 0000000000000000000000000000000000000000..71599d7691f8427ba9b0a839a2f970a3eb47e7af --- /dev/null +++ b/views/orderConfirmation.ejs @@ -0,0 +1,3 @@ +<h2>สั่งซื้อสำเร็จ!</h2> +<p>ขอบคุณที่สั่งซื้อสินค้ากับเรา</p> +<a href="/">กลับไปหน้าหลัก</a> diff --git a/views/orderHistory.ejs b/views/orderHistory.ejs new file mode 100644 index 0000000000000000000000000000000000000000..58dd7aff0e3d4f465f903b805ca820f8c2774980 --- /dev/null +++ b/views/orderHistory.ejs @@ -0,0 +1,27 @@ +<h2>ประวัติการสั่งซื้อ</h2> + +<% if (orders.length > 0) { %> + <% orders.forEach(order => { %> + <div style="border: 1px solid #ddd; padding: 10px; margin: 10px;"> + <h3>คำสั่งซื้อหมายเลข: <%= order.order_id %></h3> + <p>วันที่สั่งซื้อ: <%= order.created_at %></p> + <p>ยอดรวม: <%= order.total_amount %> บาท</p> + + <h4>รายการสินค้า:</h4> + <ul> + <% order.items.forEach(item => { %> + <li> + <img src="<%= item.image %>" width="50"> + <b><%= item.product_name %></b> - + จำนวน: <%= item.quantity %> - + ราคา: <%= item.price %> บาท + </li> + <% }) %> + </ul> + </div> + <% }) %> +<% } else { %> + <p>คุณยังไม่มีประวัติการสั่งซื้อ</p> +<% } %> + +<a href="/">กลับไปหน้าหลัก</a> diff --git a/views/product.ejs b/views/product.ejs index 80b8ca139277096d65a0228ef579f9572ea0086b..90c5b1cb5ba24c38189fba5812e18116426fe432 100644 --- a/views/product.ejs +++ b/views/product.ejs @@ -23,8 +23,19 @@ <form action="/delete_product/<%= product.product_id %>" method="POST" onsubmit="return confirm('ยืนยันการลบสินค้านี้?');"> <button type="submit" style="color: red;">ลบสินค้า</button> </form> + <form action="/products/<%= product.product_id %>/edit" method="GET"> + <button type="submit" style="color: yellow;">เเก้ไขสินค้า</button> + </form> + <form action="/cart/add" method="POST"> + <input type="hidden" name="product_id" value="<%= product.product_id %>"> + <input type="hidden" name="price" value="<%= product.price %>"> + <label>จำนวน: </label> + <input type="number" name="quantity" value="1" min="1"> + <button type="submit">เพิ่มลงตะกร้า</button> + </form> <% } %> + <a href="/">กลับหน้าหลัก</a> </body> diff --git a/views/searchResults.ejs b/views/searchResults.ejs new file mode 100644 index 0000000000000000000000000000000000000000..f6fdc95fca6cc39357e3babed7a856dcd9234911 --- /dev/null +++ b/views/searchResults.ejs @@ -0,0 +1,16 @@ +<h2>ผลลัพธ์การค้นหา "<%= searchQuery %>"</h2> + +<% if (products.length > 0) { %> + <ul> + <% products.forEach(product => { %> + <li> + <h3><%= product.product_name %></h3> + <p>ราคา: <%= product.price %> บาท</p> + <p><%= product.description %></p> + <img src="<%= product.image %>" alt="<%= product.product_name %>" width="100"> + </li> + <% }) %> + </ul> +<% } else { %> + <p>ไม่พบสินค้าที่ตรงกับคำค้นหา</p> +<% } %> \ No newline at end of file