Gitlab@Informatics

Skip to content
Snippets Groups Projects
Commit f2d7d7eb authored by First's avatar First
Browse files

Add show Latest Comment to Dashboard.ejs after Login

parent 8e9c55a0
No related branches found
No related tags found
No related merge requests found
server.js 0 → 100644
// โหลดไฟล์ .env เพื่อดึงค่าคอนฟิกต่าง ๆ
require('dotenv').config();
const express = require('express');
const session = require('express-session');
const bodyParser = require('body-parser');
const bcrypt = require('bcryptjs');
const mysql = require('mysql2');
const app = express();
const port = process.env.PORT;
// ตั้งค่า view engine เป็น EJS
app.set('view engine', 'ejs');
app.use(bodyParser.urlencoded({ extended: false }));
app.use(express.static('public'));
// ตั้งค่าระบบ session
app.use(session({
secret: process.env.SESSION_SECRET || 'default_secret_key',
resave: false,
saveUninitialized: false
}));
// เชื่อมต่อฐานข้อมูล MySQL
const connection = mysql.createConnection({
host: process.env.DB_HOST || 'localhost',
user: process.env.DB_USER || 'root',
password: process.env.DB_PASS || '',
database: process.env.DB_NAME || 'cloud_db_threads',
port: process.env.DB_PORT || 3306
});
connection.connect(err => {
if (err) {
console.error('Error connecting to MySQL:', err);
process.exit(1);
}
console.log('Connected to MySQL Successfully');
});
// Middleware ที่ใช้เช็คว่าผู้ใช้ล็อกอินหรือยัง
function isAuthenticated(req, res, next) {
if (req.session.userId) return next();
res.redirect('/login');
}
// หน้าแรก: พาไป dashboard ทันที ( User แบบ Guest สามารถเข้าได้)
app.get('/', (req, res) => {
res.redirect('/dashboard');
});
// หน้า register
app.get('/register', (req, res) => {
res.render('register', { error: null });
});
// ดำเนินการ register ผู้ใช้ใหม่
app.post('/register', async (req, res) => {
const { username, email, password } = req.body;
try {
const hashedPassword = await bcrypt.hash(password, 10);
connection.query(
'INSERT INTO users (username, email, password) VALUES (?, ?, ?)',
[username, email, hashedPassword],
(err) => {
if (err) {
console.error(err);
if (err.code === 'ER_DUP_ENTRY') {
return res.render('register', { error: 'ชื่อผู้ใช้นี้ถูกใช้ไปแล้ว' });
}
return res.render('register', { error: 'เกิดข้อผิดพลาดในการลงทะเบียน' });
}
res.redirect('/login');
}
);
} catch (error) {
console.error(error);
res.render('register', { error: 'เกิดข้อผิดพลาดระหว่างดำเนินการลงทะเบียน' });
}
});
// หน้า login
app.get('/login', (req, res) => {
res.render('login', { error: null });
});
// ดำเนินการ login
app.post('/login', (req, res) => {
const { userInput, password } = req.body;
connection.query(
'SELECT * FROM users WHERE username = ? OR email = ?',
[userInput, userInput],
async (err, results) => {
if (err) return res.render('login', { error: 'เกิดข้อผิดพลาด' });
if (results.length === 0) return res.render('login', { error: 'ไม่พบผู้ใช้งาน' });
const user = results[0];
const match = await bcrypt.compare(password, user.password);
if (match) {
req.session.userId = user.id;
req.session.username = user.username;
res.redirect('/dashboard');
} else {
res.render('login', { error: 'รหัสผ่านไม่ถูกต้อง' });
}
}
);
});
// หน้า dashboard แสดงรายการ threads ทั้งหมด
app.get('/dashboard', (req, res) => {
const searchQuery = req.query.search;
let sql = `
SELECT threads.*, users.username AS ownerName
FROM threads
JOIN users ON threads.user_id = users.id
`;
const params = [];
if (searchQuery) {
sql += `WHERE threads.thread_name LIKE ? OR threads.description LIKE ?`;
params.push(`%${searchQuery}%`, `%${searchQuery}%`);
}
sql += ' ORDER BY threads.id DESC';
connection.query(sql, params, (err, threads) => {
if (err) return res.send('เกิดข้อผิดพลาดในการดึงข้อมูล threads');
res.render('dashboard', {
username: req.session.username,
userId: req.session.userId,
threads,
query: searchQuery || ''
});
});
});
// หน้าเพิ่ม thread ใหม่
app.get('/thread/create', isAuthenticated, (req, res) => {
res.render('thread-create', { username: req.session.username });
});
// บันทึก thread ใหม่ลงฐานข้อมูล
app.post('/thread/create', isAuthenticated, (req, res) => {
const { thread_name, description } = req.body;
connection.query(
'INSERT INTO threads (user_id, thread_name, description) VALUES (?, ?, ?)',
[req.session.userId, thread_name, description],
(err) => {
if (err) return res.send('เกิดข้อผิดพลาดในการสร้าง thread');
res.redirect('/dashboard');
}
);
});
// หน้าแก้ไข thread
app.get('/thread/edit/:id', isAuthenticated, (req, res) => {
const threadId = req.params.id;
connection.query(
'SELECT * FROM threads WHERE id = ? AND user_id = ?',
[threadId, req.session.userId],
(err, results) => {
if (err || results.length === 0) return res.send('ไม่พบ thread ที่ต้องการแก้ไข');
res.render('thread-edit', {
username: req.session.username,
thread: results[0]
});
}
);
});
// อัปเดตข้อมูล thread ที่แก้ไข
app.post('/thread/edit/:id', isAuthenticated, (req, res) => {
const threadId = req.params.id;
const { thread_name, description } = req.body;
connection.query(
'UPDATE threads SET thread_name = ?, description = ? WHERE id = ? AND user_id = ?',
[thread_name, description, threadId, req.session.userId],
(err) => {
if (err) return res.send('เกิดข้อผิดพลาดในการอัปเดต thread');
res.redirect('/dashboard');
}
);
});
// ลบ thread
app.get('/thread/delete/:id', isAuthenticated, (req, res) => {
const threadId = req.params.id;
connection.query(
'DELETE FROM threads WHERE id = ? AND user_id = ?',
[threadId, req.session.userId],
(err) => {
if (err) return res.send('เกิดข้อผิดพลาดในการลบ thread');
res.redirect('/dashboard');
}
);
});
// หน้าแสดง thread พร้อมคอมเมนต์
app.get('/thread/:id', (req, res) => {
const threadId = req.params.id;
connection.query(
`SELECT threads.*, users.username AS ownerName
FROM threads
JOIN users ON threads.user_id = users.id
WHERE threads.id = ?`,
[threadId],
(err, results) => {
if (err || results.length === 0) return res.send('ไม่พบ thread ที่ต้องการ');
const thread = results[0];
connection.query(
`SELECT comments.*, users.username AS commentUser, users.email
FROM comments
JOIN users ON comments.user_id = users.id
WHERE comments.thread_id = ?
ORDER BY comments.comment_id DESC`, // ชื่อคอลัมน์ถูกต้อง
[threadId],
(err2, comments) => {
if (err2) return res.send('เกิดข้อผิดพลาดในการดึงคอมเมนต์');
res.render('thread-view', {
username: req.session.username,
userId: req.session.userId,
thread,
comments
});
}
);
}
);
});
// เพิ่มคอมเมนต์ใหม่
app.post('/thread/:id/comment', isAuthenticated, (req, res) => {
const threadId = req.params.id;
const { comment } = req.body;
connection.query(
'INSERT INTO comments (thread_id, user_id, comment) VALUES (?, ?, ?)',
[threadId, req.session.userId, comment],
(err) => {
if (err) return res.send('เกิดข้อผิดพลาดในการเพิ่มคอมเมนต์');
res.redirect(`/thread/${threadId}`);
}
);
});
// ลบคอมเมนต์
app.get('/comment/delete/:id', isAuthenticated, (req, res) => {
const commentId = req.params.id;
connection.query(
'SELECT * FROM comments WHERE id = ? AND user_id = ?',
[commentId, req.session.userId],
(err, results) => {
if (err || results.length === 0) return res.send('ไม่พบคอมเมนต์ที่ต้องการลบ');
const comment = results[0];
connection.query('DELETE FROM comments WHERE id = ?', [commentId], (err2) => {
if (err2) return res.send('เกิดข้อผิดพลาดในการลบคอมเมนต์');
res.redirect(`/thread/${comment.thread_id}`);
});
}
);
});
// ดึงคอมเมนต์ล่าสุดจากทุกกระทู้
app.get('/api/comments/latest',isAuthenticated, (req, res) => {
const sql = `
SELECT c.comment, u.id AS user_id, u.email, u.username, c.created_at
FROM comments c
JOIN users u ON c.user_id = u.id
ORDER BY c.created_at DESC
LIMIT 10
`;
connection.query(sql, (err, results) => {
if (err) {
console.error('ดึงคอมเมนต์ล่าสุดล้มเหลว:', err);
return res.status(500).json({ error: 'ดึงคอมเมนต์ไม่สำเร็จ' });
}
res.json(results);
});
});
// ออกจากระบบ
app.get('/logout', (req, res) => {
req.session.destroy();
res.redirect('/dashboard');
});
// เริ่มต้นเซิร์ฟเวอร์
app.listen(port, '0.0.0.0', () => {
console.log(`Server เปิดอยู่ที่ http://localhost:${port}`);
});
<%- include('partials/header', { username: username }) %>
<div class="container my-5">
<div class="row">
<!-- LEFT: THREAD LIST -->
<div class="col-md-8" style="background-color: #a86dcff5; color: #333; border-radius: 0px; padding: 30px;">
<div class="d-flex justify-content-between align-items-center mb-4">
<h2 class="mb-0" style="color: #000000; font-size: 30px; font-weight: 600;">THREAD TOPIC</h2>
<a href="/thread/create" class="btn" style="background-color: #000000; color: #fff; font-weight: 600; border-radius: 20px; padding: 10px 20px;">
Create New Thread Topic
</a>
</div>
<div class="list-group">
<% threads.forEach(thread => { %>
<div class="list-group-item mb-4" style="background-color: #FFF; color: #333; border: none; border-radius: 0px; padding: 20px;">
<div class="d-flex justify-content-between">
<h5 class="mb-1" style="font-size: 20px; font-weight: 700;">
<a href="#" onclick="loadComments"(<%= thread.id %>) style="color: #000000; text-decoration: none;">
<%= thread.thread_name %>
</a>
</h5>
<small style="color: #999; font-size: 16px;">
<span style="color: black; font-weight: bold;">Owner: <%= thread.ownerName %></span>
</small>
</div>
<p class="mb-3" style="font-size: 15px; line-height: 1.5;">
<%= thread.description.length > 100
? thread.description.substring(0, 100) + '...'
: thread.description
%>
</p>
<div class="mt-3">
<a href="/thread/<%= thread.id %>" class="btn btn-sm btn-outline-info" style="border-radius: 20px;">View</a>
<% if (thread.user_id === userId) { %>
<a href="/thread/edit/<%= thread.id %>" class="btn btn-sm btn-outline-warning" style="border-radius: 20px;">Edit</a>
<a href="/thread/delete/<%= thread.id %>"
class="btn btn-sm btn-outline-danger" style="border-radius: 20px;"
onclick="return confirm('Are you sure you want to delete this thread?');">
Delete
</a>
<% } %>
</div>
</div>
<% }) %>
</div>
</div>
<style>
.col-md-4 {
display: flex;
}
#comment-box {
width: 300%;
text-align: center;
}
</style>
<!-- RIGHT: COMMENT BOX -->
<div class="col-md-4">
<div id="comment-box" style="background-color: #000000; color: White; padding: 20px; min-height: 700px;">
<h5 class="mb-3">Latest User's Comment</h5>
<div id="comment-list"></div>
</div>
</div>
</div>
</div>
<script>
function loadComments(threadId) {
fetch(`/api/thread/${threadId}/comments`)
.then(res => res.json())
.then(data => {
const list = document.getElementById('comment-list');
list.innerHTML = '';
if (data.length === 0) {
list.innerHTML = '<p>ยังไม่มีความคิดเห็น</p>';
} else {
data.forEach(comment => {
const item = document.createElement('div');
item.innerHTML = `
<p><strong>${comment.username}</strong> (${comment.email}, ID: ${comment.user_id})</p>
<p>${comment.content}</p>
<hr style="border-color: white;">
`;
list.appendChild(item);
});
}
})
.catch(err => {
document.getElementById('comment-list').innerHTML = '<p>เกิดข้อผิดพลาดในการโหลดคอมเมนต์</p>';
console.error(err);
});
}
// โหลดคอมเมนต์ล่าสุดและแสดงแบบมีลำดับ + เวลา
document.addEventListener('DOMContentLoaded', function () {
fetch('/api/comments/latest')
.then(res => res.json())
.then(data => {
const list = document.getElementById('comment-list');
list.innerHTML = '';
if (data.length === 0) {
list.innerHTML = '<p>ยังไม่มีความคิดเห็น</p>';
} else {
data.forEach((comment, index) => {
const item = document.createElement('div');
item.style.textAlign = 'left';
item.style.marginBottom = '15px';
// แปลงวันที่ให้ดูง่ายขึ้น
const createdAt = new Date(comment.created_at).toLocaleString
('th-TH', {
dateStyle: 'medium',
timeStyle: 'short'
});
item.innerHTML = `
<p><strong>--------------------------------------------------------------</strong></p>
<p><strong>#${index + 1}</strong></p>
<p><strong>Username : </strong> ${comment.username}</p>
<p><strong>User Email : </strong> ${comment.email}</p>
<p><strong>User ID : </strong> ${comment.user_id}</p>
<p><strong>Comment : </strong> ${comment.comment}</p>
<p><strong>Comment Since :</strong> ${createdAt}</p>
<p><strong>--------------------------------------------------------------</strong></p>
`;
list.appendChild(item);
});
}
})
.catch(err => {
document.getElementById('comment-list').innerHTML = '<p>โปรดเข้าสู่ระบบก่อนเพื่อดูประวัติการ Comment ล่าสุด</p>';
console.error(err);
});
});
</script>
<%- include('partials/footer') %>
<!-- แสดง Header จาก partial/header.ejs -->
<%- include('partials/header') %>
<!-- Container หลักของหน้า Login -->
<div class="container my-5" style="max-width: 450px;">
<h2 class="text-center mb-4" style="color: #000000; font-weight: bold;">Login</h2>
<!-- แสดงข้อความ error ถ้ามี error ถูกส่งมาจาก backend -->
<% if (error) { %>
<div class="alert alert-danger text-center" role="alert" style="font-size: 16px;">
<%= error %>
</div>
<% } %>
<!-- ฟอร์ม Login ส่งข้อมูลผ่าน POST ไปยัง /login -->
<form action="/login" method="POST" class="shadow p-4 rounded-lg" style="background-color: #F4F7FA;">
<!-- ช่องกรอก Username หรือ Email -->
<div class="form-group">
<label for="userInput" style="font-weight: bold;">Username or Email:</label>
<input type="text" class="form-control" name="userInput" id="userInput" placeholder="Enter Username or Email" required>
</div>
<!-- ช่องกรอก Password -->
<div class="form-group">
<label for="password" style="font-weight: bold;">Password:</label>
<input type="password" class="form-control" name="password" id="password" placeholder="Enter Password" required>
</div>
<!-- ปุ่มกดเข้าสู่ระบบ -->
<button type="submit" class="btn btn-primary btn-block" style="border-radius: 30px; padding: 12px; background-color: #000000; border-color: #000000;">
Login
</button>
</form>
<!-- ลิงก์ไปหน้า Register สำหรับผู้ที่ยังไม่มีบัญชี -->
<p class="text-center mt-3">
Don't have an account yet? <a href="/register" style="color: #000000; font-weight: bold;">Register Your New Account here</a>
</p>
</div>
<!-- แสดง Footer จาก partial/footer.ejs -->
<%- include('partials/footer') %>
</div> <!-- end container -->
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.5.0/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Reddit Forum</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">
<style>
/* ปรับ Navbar ให้เป็นสีส้ม Shopee */
.navbar {
background-color: #5c64f3 !important; /* สีส้ม Shopee */
}
/* ตัวหนังสือบน Navbar ให้เป็นสีขาว */
.navbar-brand, .nav-link {
color: #000000!important;
font-weight: bold;
}
.navbar-brand:hover, .nav-link:hover {
color: #FFD2C3 !important; /* สีส้มอ่อนลงเมื่อ hover */
}
/* ปรับฟอร์มค้นหาให้สวยงาม */
.search-form {
width: 500px;
margin-left: auto;
margin-right: auto;
}
.search-form .form-control {
border-radius: 50px;
padding-left: 20px;
font-size: 16px;
}
.search-form .input-group-append .btn {
background-color: #232428;
color: white;
/* border-radius: 50px; */
border: none;
padding-left: 20px;
padding-right: 20px;
}
.search-form .input-group-append .btn:hover {
background-color: #410445;
}
</style>
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-dark">
<!-- ชื่อ Website -->
<a class="navbar-brand" href="/dashboard">REDDIT-FORUM</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') { %>
<!-- แสดงฟอร์มค้นหาสำหรับผู้ใช้ที่ล็อกอินแล้ว -->
<form action="/dashboard" method="GET" class="search-form d-flex">
<div class="input-group">
<input type="text" name="search" class="form-control" placeholder="Search Your Threds Here"
value="<%= typeof query !== 'undefined' ? query : '' %>">
<div class="input-group-append">
<button class="btn btn-outline-secondary" type="submit">Search</button>
<a href="/dashboard" class="btn btn-outline-secondary ml-2">Reset</a>
</div>
</div>
</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="/logout">Logout</a>
</li>
<% } else { %>
<li class="nav-item">
<a class="nav-link" href="/login">Login</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/register">Register</a>
</li>
<% } %>
</ul>
</div>
</nav>
<div class="container mt-4">
<!-- แสดง Header จาก partial/header.ejs -->
<%- include('partials/header') %>
<!-- Container หลักของหน้าสมัครสมาชิก -->
<div class="container my-5" style="max-width: 450px;">
<h2 class="text-center mb-4" style="color: #000000; font-weight: bold;">Register</h2>
<!-- ถ้ามี error (จาก server) ให้แสดงข้อความแจ้งเตือนในกล่องสีแดง -->
<% if (error) { %>
<div class="alert alert-danger text-center" role="alert" style="font-size: 16px;">
<%= error %>
</div>
<% } %>
<!-- ฟอร์มสมัครสมาชิก ส่งข้อมูลผ่าน POST ไปยัง /register -->
<form action="/register" method="POST" class="shadow p-4 rounded-lg" style="background-color: #F4F7FA;">
<!-- ช่องกรอก Username -->
<div class="form-group">
<label for="username" style="font-weight: bold;">Username:</label>
<input type="text" class="form-control" name="username" id="username" placeholder="Enter Username" required>
</div>
<!-- ช่องกรอก Email -->
<div class="form-group">
<label for="email" style="font-weight: bold;">Email:</label>
<input type="email" class="form-control" name="email" id="email" placeholder="Enter Email" required>
</div>
<!-- ช่องกรอก Password -->
<div class="form-group">
<label for="password" style="font-weight: bold;">Password:</label>
<input type="password" class="form-control" name="password" id="password" placeholder="Enter Password" required>
</div>
<!-- ปุ่มกดสมัครสมาชิก -->
<button type="submit" class="btn btn-primary btn-block" style="border-radius: 30px; padding: 12px; background-color: #000000; border-color: #000000;">
Register
</button>
</form>
<!-- ลิงก์ไปหน้า Login หากผู้ใช้มีบัญชีอยู่แล้ว -->
<p class="text-center mt-3">
Already have an account? <a href="/login" style="color: #000000; font-weight: bold;">Login here</a>
</p>
</div>
<!-- แสดง Footer จาก partial/footer.ejs -->
<%- include('partials/footer') %>
<!-- แสดง Header พร้อมส่งค่า username ไปด้วย -->
<%- include('partials/header', { username: username }) %>
<!-- ส่วนฟอร์มสำหรับสร้างกระทู้ -->
<div class="container my-5" style="max-width: 600px;">
<h2 class="text-center mb-4" style="color: #000000;">Create Thread</h2>
<!-- Card ที่ห่อหุ้มฟอร์ม -->
<div class="card shadow-sm">
<div class="card-body">
<!-- ฟอร์มสร้างกระทู้ใหม่ -->
<form action="/thread/create" method="POST">
<!-- ชื่อกระทู้ -->
<div class="form-group">
<label for="thread_name" style="color: #333;">Thread Name:</label>
<input type="text" class="form-control" name="thread_name" id="thread_name" required>
</div>
<!-- รายละเอียดกระทู้ -->
<div class="form-group">
<label for="description" style="color: #333;">Description:</label>
<textarea class="form-control" name="description" id="description" rows="5"></textarea>
</div>
<!-- ปุ่มสร้างกระทู้ -->
<button type="submit" class="btn btn-block" style="background-color: #000000; color: #fff; border: none;">
Create
</button>
</form>
</div>
</div>
</div>
<!-- แสดง Footer -->
<%- include('partials/footer') %>
<!-- แสดง Header และส่งตัวแปร username ไปยัง partial -->
<%- include('partials/header', { username: username }) %>
<!-- Container หลักที่จำกัดความกว้างไว้ไม่เกิน 600px และมีระยะห่างด้านบน/ล่าง -->
<div class="container my-5" style="max-width: 600px;">
<!-- หัวข้อหน้าแก้ไขกระทู้ -->
<h2 class="text-center mb-4" style="color: #000000;">Edit Thread</h2>
<!-- การ์ดสไตล์ Bootstrap พร้อมเงาเล็กน้อย -->
<div class="card shadow-sm">
<div class="card-body">
<!-- ฟอร์มสำหรับแก้ไขกระทู้ ใช้ method POST และส่งไปยัง path ที่มี id ของกระทู้ -->
<form action="/thread/edit/<%= thread.id %>" method="POST">
<!-- ช่องกรอกชื่อกระทู้ พร้อมเติมค่าปัจจุบันจากตัวแปร thread -->
<div class="form-group">
<label for="thread_name" style="color: #333;">Thread Name:</label>
<input type="text" class="form-control" name="thread_name" id="thread_name" value="<%= thread.thread_name %>" required>
</div>
<!-- ช่องกรอกรายละเอียดกระทู้ พร้อมเติมค่าปัจจุบัน -->
<div class="form-group">
<label for="description" style="color: #333;">Description:</label>
<textarea class="form-control" name="description" id="description" rows="5"><%= thread.description %></textarea>
</div>
<!-- ปุ่มกดยืนยันการอัปเดตกระทู้ -->
<button type="submit" class="btn btn-block" style="background-color: #000000; color: #fff; border: none;">
Update
</button>
</form>
</div>
</div>
</div>
<!-- แสดง Footer จาก partial -->
<%- include('partials/footer') %>
<!-- แสดง Header และส่งตัวแปร username ไปยัง partial -->
<%- include('partials/header', { username: username }) %>
<!-- Container หลักที่จำกัดความกว้างไว้ไม่เกิน 600px พร้อมระยะห่างด้านบน/ล่าง -->
<div class="container my-5" style="max-width: 600px;">
<!-- หัวข้อชื่อกระทู้ (แสดงชื่อกระทู้เป็นหัวข้อใหญ่) -->
<h2 class="text-center mb-4" style="color: #000000;"> <%= thread.thread_name %> </h2>
<!-- การ์ดหลักที่แสดงรายละเอียดกระทู้ -->
<div class="card shadow-sm">
<div class="card-body">
<!-- หัวข้อย่อยของการ์ด -->
<h5 class="card-title" style="color: #000000; font-size: 1.8rem;">
Topic: <%= thread.thread_name %>
</h5>
<!-- คำอธิบายของกระทู้ -->
<p class="card-text">
<strong>Description:</strong> <%= thread.description %>
</p>
<!-- เจ้าของกระทู้ -->
<p class="card-text">
<strong>Owner:</strong> <%= thread.ownerName %>
</p>
<!-- ปุ่มแก้ไขและลบกระทู้ (แสดงเฉพาะเมื่อ user เป็นเจ้าของกระทู้) -->
<% if (thread.user_id === userId) { %>
<a href="/thread/edit/<%= thread.id %>" class="btn btn-sm btn-outline-warning">Edit</a>
<a href="/thread/delete/<%= thread.id %>" class="btn btn-sm btn-outline-danger"
onclick="return confirm('Are you sure you want to delete this thread?');">
Delete
</a>
<% } %>
<!-- ปุ่มย้อนกลับไปหน้า Dashboard -->
<div class="d-flex justify-content-end mt-2">
<a href="/dashboard" class="btn btn-sm btn-outline-info">Back to Dashboard</a>
</div>
</div>
</div>
<!-- ส่วนแสดงคอมเมนต์ทั้งหมด -->
<div class="mt-4">
<h4 style="color: #000000;">Comments</h4>
<!-- ถ้ามีคอมเมนต์ -->
<% if (comments && comments.length > 0) { %>
<ul class="list-group">
<% comments.forEach(c => { %>
<li class="list-group-item mb-2" style="border-radius: 5px;">
<!-- แสดงชื่อผู้คอมเมนต์และข้อความ -->
<strong><%= c.commentUser %>:</strong> <%= c.comment %>
<!-- แสดง Email -->
<span class="text-muted" style="font-size: 0.8em;">
<b>(<%= c.email %>)</b>
</span>
<!-- ปุ่มลบคอมเมนต์ (เฉพาะเจ้าของคอมเมนต์) -->
<% if (c.user_id === userId) { %>
<a href="/comment/delete/<%= c.id %>"
class="btn btn-sm btn-outline-danger float-right"
onclick="return confirm('Delete this comment?');">
Delete
</a>
<% } %>
</li>
<% }) %>
</ul>
<% } else { %>
<!-- ถ้ายังไม่มีคอมเมนต์ -->
<p>No comments yet.</p>
<% } %>
</div>
<!-- แบบฟอร์มเพิ่มคอมเมนต์ใหม่ -->
<div class="card mt-3">
<div class="card-body">
<form action="/thread/<%= thread.id %>/comment" method="POST">
<div class="form-group">
<label for="comment">Add Comment:</label>
<textarea class="form-control" name="comment" id="comment" rows="2" required></textarea>
</div>
<button type="submit" class="btn" style="background-color: #000000; color: #fff;">Comment</button>
</form>
</div>
</div>
</div>
<!-- แสดง Footer -->
<%- include('partials/footer') %>
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment