Sử dụng antigravity cli để sửa lỗi người dùng public không nhìn thấy tour chia sẻ
This commit is contained in:
+53
-10
@@ -954,6 +954,7 @@ async function loadScenes(urlToken = null) {
|
||||
if (!response.ok) throw new Error('Failed to load scenes');
|
||||
const scenes = await response.json();
|
||||
|
||||
console.log(`[Frontend] loadScenes received ${scenes.length} scenes. User role: ${localStorage.getItem('role') || 'Guest'}`);
|
||||
console.log(`[Data] Nhận được ${scenes.length} scenes từ server`);
|
||||
if (!Array.isArray(scenes)) return;
|
||||
|
||||
@@ -971,13 +972,16 @@ async function loadScenes(urlToken = null) {
|
||||
const lngNum = Number(scene.gps?.lng ?? scene.lng);
|
||||
|
||||
if (isNaN(latNum) || isNaN(lngNum)) {
|
||||
console.error(`Bỏ qua Scene "${scene.name || scene.title}" do tọa độ lỗi:`, scene);
|
||||
console.warn(`[Frontend] Bỏ qua Scene "${scene.name || scene.title}" (ID: ${scene._id}) do tọa độ lỗi:`, scene);
|
||||
return;
|
||||
}
|
||||
|
||||
// 2. Logic lọc Ảnh mẹ: Sửa lỗi typo coordKey (dùng latNum 2 lần)
|
||||
const coordKey = `${latNum.toFixed(6)},${lngNum.toFixed(6)}`;
|
||||
if (seenCoordinates.has(coordKey)) return;
|
||||
if (seenCoordinates.has(coordKey)) {
|
||||
console.log(`[Frontend] Bỏ qua Scene "${scene.name || scene.title}" (ID: ${scene._id}) do trùng tọa độ (hotspot con).`);
|
||||
return;
|
||||
}
|
||||
seenCoordinates.add(coordKey);
|
||||
|
||||
// 3. Truy cập Asset an toàn
|
||||
@@ -985,6 +989,7 @@ async function loadScenes(urlToken = null) {
|
||||
if (!assetId) return; // Bỏ qua nếu không có ảnh liên kết
|
||||
|
||||
const sceneName = scene.name || scene.title || "Untitled Scene";
|
||||
console.log(`[Frontend] Đang thêm marker cho Scene: ${sceneName} (ID: ${scene._id}, Privacy: ${scene.privacy})`);
|
||||
|
||||
const isProcessing = scene.status === 'processing';
|
||||
if (isProcessing) foundProcessing++;
|
||||
@@ -1053,7 +1058,7 @@ async function loadScenes(urlToken = null) {
|
||||
const ownerId = scene.createdBy?._id || scene.createdBy || scene.owner?._id || scene.owner;
|
||||
|
||||
// Phân quyền: Admin hoặc Chủ sở hữu Scene
|
||||
const isAdmin = userRole === 'admin' || userRole === 'Chủ sở hữu';
|
||||
const isAdmin = userRole === 'admin' || userRole === 'Chủ sở hữu' || userRole === 'moderator';
|
||||
const isOwner = currentUserId && ownerId && ownerId.toString() === currentUserId.toString();
|
||||
|
||||
if (isAdmin || isOwner) {
|
||||
@@ -1099,8 +1104,13 @@ async function handleEditDeleteScene(scene) {
|
||||
const editPrivacyBtn = document.getElementById('btn-edit-privacy-action');
|
||||
const deleteBtn = document.getElementById('btn-delete-action');
|
||||
const shareBtn = document.getElementById('btn-share-action');
|
||||
const desc = document.getElementById('action-modal-desc');
|
||||
|
||||
const tour = scene.tourId; // Tour đã được populate từ backend
|
||||
|
||||
title.innerText = tour ? `Tour: ${tour.name}` : `Scene: ${scene.title}`;
|
||||
desc.innerText = tour ? "Bạn muốn thực hiện thao tác gì với Tour này?" : "Bạn muốn thực hiện thao tác gì với scene này?";
|
||||
|
||||
title.innerText = `Scene: ${scene.title}`;
|
||||
modal.style.display = 'flex';
|
||||
|
||||
// Hành động Lấy link chia sẻ trực tiếp
|
||||
@@ -1113,22 +1123,38 @@ async function handleEditDeleteScene(scene) {
|
||||
editPrivacyBtn.onclick = () => {
|
||||
returnToDashboardAfterEdit = false;
|
||||
closeActionModal();
|
||||
// Sử dụng thuộc tính isChildScene từ backend để quyết định quyền chỉnh sửa
|
||||
openEditMetadataModal(scene, scene.isChildScene);
|
||||
if (tour) {
|
||||
openEditTourModal(tour);
|
||||
} else {
|
||||
openEditMetadataModal(scene, scene.isChildScene);
|
||||
}
|
||||
};
|
||||
|
||||
// Gán sự kiện cho nút Sửa
|
||||
// Cập nhật nhãn và sự kiện cho nút Sửa
|
||||
editBtn.innerHTML = tour ? '<span class="icon">✏️</span> Sửa thông tin Tour' : '<span class="icon">✏️</span> Chế độ sửa scene';
|
||||
editBtn.onclick = () => {
|
||||
returnToDashboardAfterEdit = false;
|
||||
closeActionModal();
|
||||
openEditMetadataModal(scene, scene.isChildScene);
|
||||
if (tour) {
|
||||
openEditTourModal(tour);
|
||||
} else {
|
||||
openEditMetadataModal(scene, scene.isChildScene);
|
||||
}
|
||||
};
|
||||
|
||||
// Gán sự kiện cho nút Xóa
|
||||
// Cập nhật nhãn và sự kiện cho nút Xóa
|
||||
deleteBtn.innerHTML = tour ? '<span class="icon">🗑️</span> Xóa vĩnh viễn Tour' : '<span class="icon">🗑️</span> Xóa vĩnh viễn';
|
||||
deleteBtn.onclick = () => {
|
||||
returnToDashboardAfterEdit = false; // Đảm bảo không mở dashboard nếu xóa từ map
|
||||
closeActionModal();
|
||||
deleteScene(scene._id);
|
||||
if (tour) {
|
||||
// Tái sử dụng logic xóa tour từ dashboard
|
||||
if (confirm(`Bạn có chắc muốn xóa Tour "${tour.name}" và toàn bộ cảnh bên trong?`)) {
|
||||
confirmDeleteTourFromMap(tour._id);
|
||||
}
|
||||
} else {
|
||||
deleteScene(scene._id);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1139,6 +1165,23 @@ function closeActionModal() {
|
||||
document.getElementById('action-choice-modal').style.display = 'none';
|
||||
}
|
||||
|
||||
/**
|
||||
* Xóa Tour trực tiếp từ Map
|
||||
*/
|
||||
async function confirmDeleteTourFromMap(tourId) {
|
||||
const token = localStorage.getItem('jwt');
|
||||
try {
|
||||
const res = await fetch(`${API_BASE_URL}/tours/${tourId}`, {
|
||||
method: 'DELETE',
|
||||
headers: { 'Authorization': `Bearer ${token}` }
|
||||
});
|
||||
if (res.ok) {
|
||||
showNotification("Đã xóa Tour thành công", "success");
|
||||
loadScenes(); // Tải lại bản đồ
|
||||
}
|
||||
} catch (e) { showNotification("Lỗi xóa tour", "error"); }
|
||||
}
|
||||
|
||||
/**
|
||||
* Mở modal xác nhận xóa scene
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user