ANIVIETDB / comment.html
nguyenkhainguyen0909
Up1.2.2
8ed650e
Raw
History Blame Contribute Delete
7.17 kB
<!DOCTYPE html>
<html lang="vi">
<head>
<meta charset="UTF-8">
<title>Bình luận - ANIDBREMAX</title>
<link rel="stylesheet" href="style.css">
<style>
.comment-form {
max-width: 600px;
margin: 30px auto;
background: #1f1f1f;
padding: 25px;
border-radius: 8px;
}
.comment-form label {
display: block;
margin-top: 15px;
font-weight: bold;
}
.comment-form select,
.comment-form input,
.comment-form textarea {
width: 100%;
padding: 10px;
margin-top: 5px;
border: 1px solid #333;
border-radius: 5px;
background: #2a2a2a;
color: #eee;
font-size: 14px;
box-sizing: border-box;
}
.comment-form textarea {
resize: vertical;
min-height: 80px;
}
.comment-form button {
margin-top: 15px;
padding: 10px 20px;
background: #e74c3c;
color: #fff;
border: none;
border-radius: 5px;
cursor: pointer;
font-size: 15px;
width: 100%;
}
.comment-form button:hover {
background: #c0392b;
}
.comment-list {
max-width: 600px;
margin: 20px auto;
}
.comment-item {
background: #1f1f1f;
padding: 15px;
border-radius: 8px;
margin-bottom: 10px;
}
.comment-item .meta {
display: flex;
justify-content: space-between;
font-size: 13px;
color: #888;
margin-bottom: 5px;
}
.comment-item .name {
color: #e74c3c;
font-weight: bold;
}
.comment-item .message {
font-size: 14px;
line-height: 1.5;
}
.filter-bar {
max-width: 600px;
margin: 20px auto;
display: flex;
gap: 10px;
align-items: center;
}
.filter-bar select {
flex: 1;
padding: 10px;
border: 1px solid #333;
border-radius: 5px;
background: #2a2a2a;
color: #eee;
font-size: 14px;
}
#statusMsg {
text-align: center;
margin-top: 10px;
font-size: 14px;
}
</style>
</head>
<body>
<header>ANIDBREMAX - Bình luận</header>
<nav>
<a href="index.html">Trang chủ</a>
<a href="comment.html">Bình luận</a>
</nav>
<div class="container">
<div class="filter-bar">
<select id="animeSelect" onchange="loadComments()">
<option value="">-- Chọn anime --</option>
</select>
</div>
<div class="comment-form" id="commentForm">
<h3 style="margin-top:0">Gửi bình luận</h3>
<label for="cmtName">Tên của bạn</label>
<input type="text" id="cmtName" placeholder="Nhập tên..." maxlength="50">
<label for="cmtMessage">Nội dung</label>
<textarea id="cmtMessage" placeholder="Nhập bình luận..." maxlength="1000"></textarea>
<button onclick="submitComment()">Gửi bình luận</button>
<div id="statusMsg"></div>
</div>
<div class="comment-list" id="commentList"></div>
</div>
<footer style="text-align:center;padding:20px;color:#666;font-size:13px">
&copy; 2026 ANIDBREMAX
</footer>
<script>
const animeList = [
{ key: 'eminence1', name: 'The Eminence in Shadow (P1)' },
{ key: 'eminence2', name: 'The Eminence in Shadow (P2)' },
{ key: 'naruto', name: 'Naruto' },
{ key: 'doraemon1', name: 'Doraemon: Nobita Thám Hiểm Vùng Đất Mới' },
{ key: 'doraemon2', name: 'Doraemon: Nobita và Viện Bảo Tàng Bảo Bối' },
{ key: 'doraemon3', name: 'Doraemon: Nobita và Những Hiệp Sĩ Không Gian' },
{ key: 'conan21', name: 'Detective Conan Movie 21: The Crimson Love Letter' },
{ key: 'conan26', name: 'Detective Conan Movie 26: Black Iron Submarine' },
{ key: 'conan27', name: 'Detective Conan Movie 27: The Million Dollar Pentagram' }
];
const API = window.location.origin;
function populateAnimeSelect(selectId) {
const sel = document.getElementById(selectId);
animeList.forEach(a => {
const opt = document.createElement('option');
opt.value = a.key;
opt.textContent = a.name;
sel.appendChild(opt);
});
}
populateAnimeSelect('animeSelect');
async function loadComments() {
const anime = document.getElementById('animeSelect').value;
const list = document.getElementById('commentList');
const form = document.getElementById('commentForm');
if (!anime) {
list.innerHTML = '<p style="text-align:center;color:#666">Vui lòng chọn anime để xem bình luận</p>';
form.style.display = 'none';
return;
}
form.style.display = 'block';
list.innerHTML = '<p style="text-align:center;color:#666">Đang tải...</p>';
try {
const res = await fetch(`${API}/api/comments?anime=${encodeURIComponent(anime)}`);
const data = await res.json();
if (data.length === 0) {
list.innerHTML = '<p style="text-align:center;color:#666">Chưa có bình luận nào</p>';
return;
}
list.innerHTML = data.map(c => {
const time = new Date(c.created_at).toLocaleString('vi-VN');
return `<div class="comment-item">
<div class="meta">
<span class="name">${escapeHtml(c.name)}</span>
<span>${time}</span>
</div>
<div class="message">${escapeHtml(c.message)}</div>
</div>`;
}).join('');
} catch (e) {
list.innerHTML = '<p style="text-align:center;color:#e74c3c">Lỗi tải bình luận. Server chưa chạy?</p>';
}
}
function escapeHtml(text) {
const d = document.createElement('div');
d.textContent = text;
return d.innerHTML;
}
async function submitComment() {
const anime = document.getElementById('animeSelect').value;
const name = document.getElementById('cmtName').value.trim();
const message = document.getElementById('cmtMessage').value.trim();
const status = document.getElementById('statusMsg');
if (!anime) { status.textContent = 'Vui lòng chọn anime'; return; }
if (!name) { status.textContent = 'Vui lòng nhập tên'; return; }
if (!message) { status.textContent = 'Vui lòng nhập nội dung'; return; }
status.textContent = 'Đang gửi...';
try {
const res = await fetch(`${API}/api/comments`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ anime, name, message })
});
const data = await res.json();
if (data.success) {
status.textContent = 'Đã gửi bình luận!';
status.style.color = '#2ecc71';
document.getElementById('cmtMessage').value = '';
loadComments();
} else {
status.textContent = 'Lỗi: ' + (data.error || 'Không xác định');
status.style.color = '#e74c3c';
}
} catch (e) {
status.textContent = 'Lỗi kết nối server. Vui lòng chạy: node server.js';
status.style.color = '#e74c3c';
}
}
</script>
</body>
</html>