diff --git a/.env b/.env index ca53c779a819b8097b12bdf39e36bb6ef5c29f2c..fa3a4258bc10bb79d029a93377d6846e533e2886 100644 --- a/.env +++ b/.env @@ -1,32 +1,18 @@ -# PORT=3000 -# DB_HOST=localhost -# DB_USER=root -# DB_PASS= -# DB_NAME=cloud_project_db -# SESSION_SECRET=default_secret_key +PORT=3000 -# DB_HOST=10.104.6.131 -# DB_PORT=11734 -# DB_USER=root -# DB_PASS=LCXndt18044 -# DB_NAME=cloud_project_db -# SESSION_SECRET=default_secret_key +DB_HOST=localhost +DB_USER=root +DB_PASS= +DB_NAME=cloud_project_db +SESSION_SECRET=default_secret_key -# PORT=3000 -# DB_HOST=10.104.6.131 -# DB_USER=root -# DB_PASS=DRQqan69450 -# DB_NAME=cloud_project_db -# DB_PORT=3306 -# SESSION_SECRET=default_secret_key -PORT=3000 +# PORT=3000 -# Database connection settings -DB_HOST=10.104.6.131 # IP ที่ถูกต้องของฐานข้อมูล MySQL -DB_PORT=11734 # Public port สำหรับเชื่อมต่อ MySQL -DB_USER=root # ชื่อผู้ใช้สำหรับ MySQL -DB_PASS=LCXndt18044 # รหัสผ่านของ MySQL -DB_NAME=cloud_project_db # ชื่อฐานข้อมูลที่ใช้ -SESSION_SECRET=default_secret_key # กำหนดคีย์สำหรับ session +# DB_HOST=10.104.6.131 # IP ที่ถูกต้องของฐานข้อมูล MySQL +# DB_PORT=11734 # Public port สำหรับเชื่อมต่อ MySQL +# DB_USER=root # ชื่อผู้ใช้สำหรับ MySQL +# DB_PASS=LCXndt18044 # รหัสผ่านของ MySQL +# DB_NAME=cloud_project_db # ชื่อฐานข้อมูลที่ใช้ +# SESSION_SECRET=default_secret_key # กำหนดคีย์สำหรับ session diff --git a/server.js b/server.js index 66426140fdf8afa638d5a727b325a585d67492b6..3f2dece14a73b400e996cb95c08d314914f7788e 100644 --- a/server.js +++ b/server.js @@ -1,5 +1,4 @@ -// server.js -require('dotenv').config(); // โหลดค่าตัวแปรจาก .env +require('dotenv').config(); const express = require('express'); const session = require('express-session'); const bodyParser = require('body-parser'); @@ -9,7 +8,6 @@ const mysql = require('mysql2'); const app = express(); // อ่านค่า PORT จาก .env ถ้าไม่มีให้ใช้ 3000 -// const port = process.env.PORT || 3000; const port = process.env.PORT; // ตั้งค่า view engine เป็น EJS @@ -30,7 +28,7 @@ app.use(session({ // สร้างการเชื่อมต่อกับฐานข้อมูล MySQL โดยอ่านค่าจาก .env const connection = mysql.createConnection({ - host: process.env.DB_HOST || 'localhost', // ถ้าไม่มีค่าใน DB_HOST จะใช้ 'localhost' + host: process.env.DB_HOST || 'localhost', user: process.env.DB_USER || 'root', password: process.env.DB_PASS || '', database: process.env.DB_NAME || 'cloud_project_db', @@ -45,7 +43,7 @@ connection.connect(err => { console.log('Connected to MySQL'); }); -// Middleware ตรวจสอบการเข้าสู่ระบบ +// Middleware ตรวจสอบการเข้าสู่ระบบ (ใช้สำหรับหน้าที่ต้องการให้ login) function isAuthenticated(req, res, next) { if (req.session.userId) { return next(); @@ -57,11 +55,8 @@ function isAuthenticated(req, res, next) { // หน้าแรก // -------------------- app.get('/', (req, res) => { - if (req.session.userId) { - res.redirect('/dashboard'); - } else { - res.redirect('/login'); - } + // ไม่ว่าจะล็อกอินหรือไม่ ให้ redirect ไปที่ '/dashboard' เสมอ + res.redirect('/dashboard'); }); // -------------------- @@ -132,46 +127,53 @@ app.post('/login', (req, res) => { }); // -------------------- -// Dashboard (แสดง Project พร้อม Search) +// Dashboard (อนุญาตให้ Guest เข้าดูได้) // -------------------- -app.get('/dashboard', isAuthenticated, (req, res) => { +app.get('/dashboard', (req, res) => { // รับค่าค้นหาจาก query string ?q= const searchQuery = req.query.q; let sql = ` SELECT projects.*, users.username AS ownerName FROM projects JOIN users ON projects.user_id = users.id + ORDER BY projects.id DESC `; - const params = []; // ถ้ามีค่า searchQuery ให้เพิ่มเงื่อนไข WHERE เพื่อค้นหาตาม project_name หรือ description + const params = []; if (searchQuery) { - sql += ` + sql = ` + SELECT projects.*, users.username AS ownerName + FROM projects + JOIN users ON projects.user_id = users.id WHERE projects.project_name LIKE ? OR projects.description LIKE ? + ORDER BY projects.id DESC `; params.push(`%${searchQuery}%`, `%${searchQuery}%`); } - - sql += ' ORDER BY projects.id DESC'; - + connection.query(sql, params, (err, projects) => { if (err) { console.error(err); return res.send('Error fetching projects'); } + // ถ้ายังไม่ได้ login ให้แสดงชื่อ Guest + const username = req.session.username || 'Guest'; + const userId = req.session.userId || null; + res.render('dashboard', { - username: req.session.username, - userId: req.session.userId, + username, + userId, projects, - query: searchQuery || '' + query: searchQuery || '', + currentPage: 'dashboard' }); }); }); // ----------------------------------------------------- -// 1) CREATE Project -// ----------------------------------------------------- +// 1) CREATE Project (ต้อง login) app.get('/project/create', isAuthenticated, (req, res) => { res.render('project-create', { username: req.session.username }); }); @@ -192,8 +194,7 @@ app.post('/project/create', isAuthenticated, (req, res) => { }); // ----------------------------------------------------- -// 2) EDIT Project -// ----------------------------------------------------- +// 2) EDIT Project (ต้อง login) app.get('/project/edit/:id', isAuthenticated, (req, res) => { const projectId = req.params.id; connection.query( @@ -232,8 +233,7 @@ app.post('/project/edit/:id', isAuthenticated, (req, res) => { }); // ----------------------------------------------------- -// 3) DELETE Project -// ----------------------------------------------------- +// 3) DELETE Project (ต้อง login) app.get('/project/delete/:id', isAuthenticated, (req, res) => { const projectId = req.params.id; connection.query( @@ -250,11 +250,9 @@ app.get('/project/delete/:id', isAuthenticated, (req, res) => { }); // ----------------------------------------------------- -// 4) VIEW Project + Comments -// ----------------------------------------------------- +// 4) VIEW Project + Comments (ต้อง login) app.get('/project/:id', isAuthenticated, (req, res) => { const projectId = req.params.id; - // ดึงข้อมูล Project connection.query( `SELECT projects.*, users.username AS ownerName FROM projects @@ -271,7 +269,6 @@ app.get('/project/:id', isAuthenticated, (req, res) => { } const project = results[0]; - // ดึง Comments ของ Project นี้ connection.query( `SELECT comments.*, users.username AS commentUser FROM comments @@ -297,8 +294,7 @@ app.get('/project/:id', isAuthenticated, (req, res) => { }); // ----------------------------------------------------- -// 5) CREATE Comment -// ----------------------------------------------------- +// 5) CREATE Comment (ต้อง login) app.post('/project/:id/comment', isAuthenticated, (req, res) => { const projectId = req.params.id; const { comment } = req.body; @@ -316,8 +312,7 @@ app.post('/project/:id/comment', isAuthenticated, (req, res) => { }); // ----------------------------------------------------- -// 6) DELETE Comment (เฉพาะเจ้าของ comment) -// ----------------------------------------------------- +// 6) DELETE Comment (เฉพาะเจ้าของ comment, ต้อง login) app.get('/comment/delete/:id', isAuthenticated, (req, res) => { const commentId = req.params.id; const sql = ` @@ -349,7 +344,7 @@ app.get('/comment/delete/:id', isAuthenticated, (req, res) => { // -------------------- app.get('/logout', (req, res) => { req.session.destroy(); - res.redirect('/login'); + res.redirect('/dashboard'); }); // เริ่มเซิร์ฟเวอร์ diff --git a/views/dashboard.ejs b/views/dashboard.ejs index 180162728e29f75d97bd39c436ae3386b13643b4..6ae317ba18ddd0c08d27446b6cd1e48de73924c8 100644 --- a/views/dashboard.ejs +++ b/views/dashboard.ejs @@ -5,9 +5,14 @@ <!-- Header with Title --> <div class="d-flex justify-content-between align-items-center mb-4"> <h2 class="mb-0" style="color: #EE4D2D; font-size: 30px; font-weight: 600;">TOPIC</h2> - <a href="/project/create" class="btn" style="background-color: #EE4D2D; color: #fff; font-weight: 600; border-radius: 20px; padding: 10px 20px;"> - Create New Topic - </a> + + <!-- ซ่อนปุ่ม Create New Topic ถ้า userId ไม่มีค่า (ยังไม่ล็อกอิน) --> + <% if (userId) { %> + <a href="/project/create" class="btn" + style="background-color: #EE4D2D; color: #fff; font-weight: 600; border-radius: 20px; padding: 10px 20px;"> + Create New Topic + </a> + <% } %> </div> <!-- List Group of Topics --> @@ -36,7 +41,11 @@ <!-- Action Buttons (View/Edit/Delete) --> <div class="mt-3"> + <!-- ปุ่ม View ให้แสดงได้ทุกคน + (แต่หาก route /project/:id ใช้ isAuthenticated, Guest จะถูก redirect ไป login เอง) --> <a href="/project/<%= project.id %>" class="btn btn-sm btn-outline-info" style="border-radius: 20px;">View</a> + + <!-- แสดงปุ่ม Edit/Delete เฉพาะเจ้าของโปรเจกต์ (userId ตรงกับ project.user_id) --> <% if (project.user_id === userId) { %> <a href="/project/edit/<%= project.id %>" class="btn btn-sm btn-outline-warning" style="border-radius: 20px;">Edit</a> <a href="/project/delete/<%= project.id %>" diff --git a/views/partials/header.ejs b/views/partials/header.ejs index 55096799eb0012e6f16a04e17320cb86b0c58670..41e792f7cde26cb38dcef3cf1cf5d32b43a21e9d 100644 --- a/views/partials/header.ejs +++ b/views/partials/header.ejs @@ -4,23 +4,12 @@ <meta charset="UTF-8"> <title>PURIPAT</title> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css"> - <!-- เพิ่ม Favicon --> - <link rel="icon" href="path/to/your/favicon.ico" type="image/x-icon"> - + <link rel="icon" href="/favicon.ico" type="image/x-icon"> + <style> - /* ปรับ Navbar ให้เป็นสีส้ม Shopee */ - .navbar { - background-color: #EE4D2D !important; /* สีส้ม Shopee */ - } - /* ตัวหนังสือบน Navbar ให้เป็นสีขาว */ - .navbar-brand, .nav-link { - color: #fff !important; - } - .navbar-brand:hover, .nav-link:hover { - color: #FFD2C3 !important; /* สีส้มอ่อนลงเมื่อ hover */ - } - - /* ปรับฟอร์มค้นหาให้สวยงาม */ + .navbar { background-color: #EE4D2D !important; } + .navbar-brand, .nav-link { color: #fff !important; } + .navbar-brand:hover, .nav-link:hover { color: #FFD2C3 !important; } .search-form { width: 500px; margin-left: auto; @@ -34,7 +23,6 @@ .search-form .input-group-append .btn { background-color: #FF7043; color: white; - /* border-radius: 50px; */ border: none; padding-left: 20px; padding-right: 20px; @@ -45,23 +33,28 @@ </style> </head> <body> +<% + // ถ้าไม่มีการส่ง username เข้ามา ให้เป็น 'Guest' + var localUsername = (typeof username !== 'undefined' && username) ? username : 'Guest'; + // ถ้าไม่มี query ส่งเข้ามา ให้เป็นค่าว่าง + var localQuery = (typeof query !== 'undefined') ? query : ''; + // ถ้าไม่มี currentPage ส่งเข้ามา ให้กำหนดเป็น '' + var currentPageVal = (typeof currentPage !== 'undefined') ? currentPage : ''; +%> <nav class="navbar navbar-expand-lg navbar-dark"> - <!-- ชื่อโปรเจกต์ --> <a class="navbar-brand" href="/dashboard">TONGBARN</a> - <!-- ปุ่ม toggle สำหรับ mobile --> <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarContent" aria-controls="navbarContent" aria-expanded="false" aria-label="Toggle navigation"> <span class="navbar-toggler-icon"></span> </button> - <!-- ฟอร์ม Search จะปรากฏเฉพาะเมื่อผู้ใช้เข้าสู่ระบบ --> <div class="collapse navbar-collapse" id="navbarContent"> - <% if (typeof username !== 'undefined') { %> - <!-- แสดงฟอร์มค้นหาสำหรับผู้ใช้ที่ล็อกอินแล้ว --> + <!-- แสดงฟอร์มค้นหาเฉพาะเมื่อ currentPage === 'dashboard' --> + <% if (currentPageVal === 'dashboard') { %> <form action="/dashboard" method="GET" class="search-form d-flex"> <div class="input-group"> <input type="text" name="q" class="form-control" placeholder="Search for threads now..." - value="<%= typeof query !== 'undefined' ? query : '' %>"> + value="<%= localQuery %>"> <div class="input-group-append"> <button class="btn btn-outline-secondary" type="submit">Search</button> </div> @@ -69,12 +62,11 @@ </form> <% } %> - <!-- เมนู Navbar --> <ul class="navbar-nav ml-auto"> - <% if (typeof username !== 'undefined') { %> - <li class="nav-item"> - <a class="nav-link" href="#">Welcome, <%= username %></a> - </li> + <li class="nav-item"> + <a class="nav-link" href="#">Welcome, <%= localUsername %></a> + </li> + <% if (localUsername !== 'Guest') { %> <li class="nav-item"> <a class="nav-link" href="/logout">Logout</a> </li>