Sửa chữa giao diện, lỗi privacy
This commit is contained in:
+46
-17
@@ -1076,8 +1076,12 @@ html, body {
|
||||
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
/* --- Edit Metadata Modal (Dark Theme) --- */
|
||||
#edit-scene-metadata-modal .modal-content {
|
||||
/* --- Unified Dark Theme for Modals (Tour, Scene, Metadata, Hotspot, Actions) --- */
|
||||
#edit-scene-metadata-modal .modal-content,
|
||||
#create-tour-modal .modal-content,
|
||||
#create-scene-modal .modal-content,
|
||||
#hotspot-modal .modal-content,
|
||||
#action-choice-modal .modal-content {
|
||||
background: rgba(30, 30, 30, 0.95);
|
||||
color: #fff;
|
||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
@@ -1085,36 +1089,54 @@ html, body {
|
||||
max-width: 500px;
|
||||
}
|
||||
|
||||
#edit-scene-metadata-modal .form-group label {
|
||||
#edit-scene-metadata-modal .form-group label,
|
||||
#create-tour-modal .form-group label,
|
||||
#create-scene-modal .form-group label,
|
||||
#hotspot-modal .form-group label,
|
||||
#action-choice-modal .form-group label {
|
||||
color: #ccc;
|
||||
}
|
||||
|
||||
#edit-scene-metadata-modal input,
|
||||
#edit-scene-metadata-modal textarea,
|
||||
#edit-scene-metadata-modal select {
|
||||
#create-tour-modal input,
|
||||
#create-tour-modal select,
|
||||
#create-tour-modal textarea,
|
||||
#create-scene-modal input,
|
||||
#create-scene-modal select,
|
||||
#create-scene-modal textarea,
|
||||
#hotspot-modal input,
|
||||
#hotspot-modal textarea,
|
||||
#hotspot-modal select {
|
||||
background: rgba(255, 255, 255, 0.05);
|
||||
border: 1px solid rgba(255, 255, 255, 0.2);
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
/* Trạng thái vô hiệu hóa (Disabled) cho các trường nhập liệu trong Modal sửa */
|
||||
#edit-scene-metadata-modal input:disabled,
|
||||
#edit-scene-metadata-modal textarea:disabled,
|
||||
#edit-scene-metadata-modal select:disabled {
|
||||
background: rgba(255, 255, 255, 0.02) !important;
|
||||
color: #777 !important;
|
||||
cursor: not-allowed;
|
||||
border-color: rgba(255, 255, 255, 0.1) !important;
|
||||
/* Select option colors for Dark Theme */
|
||||
#edit-scene-metadata-modal select option,
|
||||
#create-tour-modal select option,
|
||||
#create-scene-modal select option,
|
||||
#hotspot-modal select option {
|
||||
background-color: #1e1e1e;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
/* Tùy chỉnh màu sắc cho danh sách lựa chọn (dropdown options) trong modal tối */
|
||||
#edit-scene-metadata-modal select option {
|
||||
background-color: #000; /* Nền đen cho các item */
|
||||
color: #fff; /* Chữ trắng */
|
||||
#hs-mini-map {
|
||||
height: 200px;
|
||||
width: 100%;
|
||||
border-radius: 8px;
|
||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
#edit-scene-metadata-modal select option:hover {
|
||||
background-color: #555; /* Nền xám khi di chuột qua (tùy trình duyệt hỗ trợ) */
|
||||
#edit-scene-metadata-modal .modal-header,
|
||||
#create-tour-modal .modal-header,
|
||||
#create-scene-modal .modal-header,
|
||||
#hotspot-modal .modal-header,
|
||||
#action-choice-modal .modal-header {
|
||||
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
|
||||
#edit-mini-map {
|
||||
@@ -1372,3 +1394,10 @@ html, body {
|
||||
color: #dc3545;
|
||||
border: 1px solid rgba(220, 53, 69, 0.4);
|
||||
}
|
||||
|
||||
/* Temporary hiding rules for notification overlays */
|
||||
body.notification-active #dashboard-overlay,
|
||||
body.notification-active .modal,
|
||||
body.notification-active .modal-overlay:not(#success-modal):not(#error-modal) {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
+1
-1
@@ -526,7 +526,7 @@
|
||||
</div>
|
||||
<!-- Hotspot Editor Modal -->
|
||||
<div id="hotspot-modal" class="modal-overlay" style="display: none; z-index: 3000;">
|
||||
<div class="modal-content">
|
||||
<div class="modal-content action-modal-content logout-modal-dark" style="max-width: 500px; border-top: 4px solid #ffc107;">
|
||||
<div class="modal-header">
|
||||
<h3 id="hotspot-modal-title">Biên tập điểm điều hướng</h3>
|
||||
<span class="close-btn" onclick="closeHotspotModal()">×</span>
|
||||
|
||||
+185
-42
@@ -711,7 +711,11 @@ function openCreateTourModal(lat, lng) {
|
||||
* Đóng Modal tạo Tour
|
||||
*/
|
||||
function closeTourModal() {
|
||||
document.getElementById('create-tour-modal').style.display = 'none';
|
||||
const modal = document.getElementById('create-tour-modal');
|
||||
if (modal) {
|
||||
modal.style.display = 'none';
|
||||
modal.removeAttribute('data-original-display');
|
||||
}
|
||||
if (tempMarker) {
|
||||
map.removeLayer(tempMarker);
|
||||
tempMarker = null;
|
||||
@@ -733,9 +737,14 @@ function openEditTourModal(tour) {
|
||||
const token = localStorage.getItem('jwt');
|
||||
if (!token) return;
|
||||
|
||||
dashboardReturnTab = 'my-scenes';
|
||||
returnToDashboardAfterEdit = true;
|
||||
closeDashboard();
|
||||
const isDashboardOpen = document.getElementById('dashboard-overlay').style.display === 'flex';
|
||||
if (isDashboardOpen) {
|
||||
dashboardReturnTab = 'my-scenes';
|
||||
returnToDashboardAfterEdit = true;
|
||||
closeDashboard();
|
||||
} else {
|
||||
returnToDashboardAfterEdit = false;
|
||||
}
|
||||
|
||||
const tourIdInput = document.getElementById('tour-id');
|
||||
if (tourIdInput) tourIdInput.value = tour._id;
|
||||
@@ -833,8 +842,16 @@ function openCreateSceneModal(lat, lng, tourId = null) {
|
||||
* Closes the Create Scene Modal and removes temporary marker
|
||||
*/
|
||||
function closeModal() {
|
||||
document.getElementById('create-tour-modal').style.display = 'none'; // Đảm bảo đóng cả modal Tour
|
||||
document.getElementById('create-scene-modal').style.display = 'none';
|
||||
const tourModal = document.getElementById('create-tour-modal');
|
||||
if (tourModal) {
|
||||
tourModal.style.display = 'none';
|
||||
tourModal.removeAttribute('data-original-display');
|
||||
}
|
||||
const sceneModal = document.getElementById('create-scene-modal');
|
||||
if (sceneModal) {
|
||||
sceneModal.style.display = 'none';
|
||||
sceneModal.removeAttribute('data-original-display');
|
||||
}
|
||||
if (tempMarker) {
|
||||
map.removeLayer(tempMarker);
|
||||
tempMarker = null;
|
||||
@@ -1144,12 +1161,12 @@ async function handleEditDeleteScene(scene) {
|
||||
|
||||
// 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 = () => {
|
||||
deleteBtn.onclick = async () => {
|
||||
returnToDashboardAfterEdit = false; // Đảm bảo không mở dashboard nếu xóa từ map
|
||||
closeActionModal();
|
||||
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?`)) {
|
||||
if (await window.showConfirmModal(`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 {
|
||||
@@ -1187,10 +1204,15 @@ async function confirmDeleteTourFromMap(tourId) {
|
||||
*/
|
||||
window.deleteScene = async function(sceneId, sceneData = null) { // Thêm sceneData để tránh fetch lại
|
||||
sceneIdToDelete = sceneId;
|
||||
// Tạm thời đóng dashboard và lưu trạng thái để mở lại sau
|
||||
dashboardReturnTab = 'my-scenes';
|
||||
returnToDashboardAfterEdit = true;
|
||||
closeDashboard();
|
||||
// Tạm thời đóng dashboard nếu nó đang mở
|
||||
const isDashboardOpen = document.getElementById('dashboard-overlay').style.display === 'flex';
|
||||
if (isDashboardOpen) {
|
||||
dashboardReturnTab = 'my-scenes';
|
||||
returnToDashboardAfterEdit = true;
|
||||
closeDashboard();
|
||||
} else {
|
||||
returnToDashboardAfterEdit = false;
|
||||
}
|
||||
const confirmModal = document.getElementById('delete-scene-confirm-modal');
|
||||
const confirmMessageElem = document.getElementById('delete-scene-confirm-message'); // Giả định có element này trong HTML
|
||||
|
||||
@@ -1546,7 +1568,7 @@ window.handleHotspotCreation = async function(pitch, yaw, existingHotspot = null
|
||||
return;
|
||||
}
|
||||
await saveHotspotToDB(pitch, yaw, formData.get('title'), formData.get('description'), finalTargetId, existingHotspot?._id);
|
||||
modal.style.display = 'none';
|
||||
closeHotspotModal();
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1554,7 +1576,11 @@ window.handleHotspotCreation = async function(pitch, yaw, existingHotspot = null
|
||||
* Đóng Modal biên tập Hotspot
|
||||
*/
|
||||
function closeHotspotModal() {
|
||||
document.getElementById('hotspot-modal').style.display = 'none';
|
||||
const modal = document.getElementById('hotspot-modal');
|
||||
if (modal) {
|
||||
modal.style.display = 'none';
|
||||
modal.removeAttribute('data-original-display');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1680,7 +1706,7 @@ async function saveHotspotToDB(pitch, yaw, title, description, targetSceneId, ho
|
||||
* Gọi lệnh: systemReset() từ trình duyệt
|
||||
*/
|
||||
window.systemReset = async function() {
|
||||
if (!confirm("CẢNH BÁO: Thao tác này sẽ xóa sạch TOÀN BỘ scene và ảnh trên server. Bạn có chắc chắn?")) return;
|
||||
if (!await window.showConfirmModal("CẢNH BÁO: Thao tác này sẽ xóa sạch TOÀN BỘ scene và ảnh trên server. Bạn có chắc chắn?")) return;
|
||||
|
||||
const token = localStorage.getItem('jwt');
|
||||
try {
|
||||
@@ -1720,7 +1746,7 @@ window.openHotspotMenu = function(hotspot) {
|
||||
|
||||
// Hành động Xóa: Xác nhận và gọi API xóa
|
||||
deleteBtn.onclick = async () => {
|
||||
if (confirm('Bạn có chắc chắn muốn xóa điểm điều hướng này?')) {
|
||||
if (await window.showConfirmModal('Bạn có chắc chắn muốn xóa điểm điều hướng này?')) {
|
||||
closeHotspotActionModal();
|
||||
await deleteHotspot(hotspot._id);
|
||||
}
|
||||
@@ -1831,6 +1857,10 @@ async function loadMyTours() {
|
||||
|
||||
card.style.borderLeft = `5px solid ${tour.privacy === 'public' ? '#28a745' : '#ffc107'}`;
|
||||
|
||||
const currentUserId = localStorage.getItem('userId');
|
||||
const userRole = localStorage.getItem('role');
|
||||
const isTourOwner = (tour.createdBy?._id === currentUserId || tour.createdBy === currentUserId || userRole === 'admin' || userRole === 'Chủ sở hữu');
|
||||
|
||||
card.innerHTML = `
|
||||
<div class="scene-card-overlay">
|
||||
<div class="scene-card-info">
|
||||
@@ -1844,8 +1874,10 @@ async function loadMyTours() {
|
||||
</div>
|
||||
</div>
|
||||
<div class="media-actions" style="border: none; padding: 0;">
|
||||
<button class="edit-btn-small" id="edit-tour-${tour._id}" style="background:#007bff">Sửa</button>
|
||||
<button class="delete-btn-small" id="delete-tour-${tour._id}">Xóa</button>
|
||||
${isTourOwner ? `
|
||||
<button class="edit-btn-small" id="edit-tour-${tour._id}" style="background:#007bff">Sửa</button>
|
||||
<button class="delete-btn-small" id="delete-tour-${tour._id}">Xóa</button>
|
||||
` : ''}
|
||||
<button class="edit-btn-small" id="view-tour-${tour._id}" style="background:#28a745">Xem</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1853,26 +1885,32 @@ async function loadMyTours() {
|
||||
listContainer.appendChild(card);
|
||||
|
||||
// Nút Sửa Tour
|
||||
document.getElementById(`edit-tour-${tour._id}`).onclick = () => {
|
||||
openEditTourModal(tour);
|
||||
};
|
||||
const editBtn = document.getElementById(`edit-tour-${tour._id}`);
|
||||
if (editBtn) {
|
||||
editBtn.onclick = () => {
|
||||
openEditTourModal(tour);
|
||||
};
|
||||
}
|
||||
|
||||
// Nút Xóa Tour: Gọi API xóa Tour (bao gồm xóa cascade các scene bên trong)
|
||||
document.getElementById(`delete-tour-${tour._id}`).onclick = async () => {
|
||||
if (confirm(`Bạn có chắc muốn xóa Tour "${tour.name}" và toàn bộ ${tour.scenes?.length || 0} cảnh bên trong?`)) {
|
||||
try {
|
||||
const res = await fetch(`${API_BASE_URL}/tours/${tour._id}`, {
|
||||
method: 'DELETE',
|
||||
headers: { 'Authorization': `Bearer ${token}` }
|
||||
});
|
||||
if (res.ok) {
|
||||
showNotification("Đã xóa Tour thành công", "success");
|
||||
loadMyTours();
|
||||
loadScenes();
|
||||
}
|
||||
} catch (e) { showNotification("Lỗi xóa tour", "error"); }
|
||||
}
|
||||
};
|
||||
const deleteBtn = document.getElementById(`delete-tour-${tour._id}`);
|
||||
if (deleteBtn) {
|
||||
deleteBtn.onclick = async () => {
|
||||
if (await window.showConfirmModal(`Bạn có chắc muốn xóa Tour "${tour.name}" và toàn bộ ${tour.scenes?.length || 0} cảnh bên trong?`)) {
|
||||
try {
|
||||
const res = await fetch(`${API_BASE_URL}/tours/${tour._id}`, {
|
||||
method: 'DELETE',
|
||||
headers: { 'Authorization': `Bearer ${token}` }
|
||||
});
|
||||
if (res.ok) {
|
||||
showNotification("Đã xóa Tour thành công", "success");
|
||||
loadMyTours();
|
||||
loadScenes();
|
||||
}
|
||||
} catch (e) { showNotification("Lỗi xóa tour", "error"); }
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// Nút Xem Tour: Bay tới vị trí và mở cảnh khởi đầu
|
||||
document.getElementById(`view-tour-${tour._id}`).onclick = () => {
|
||||
@@ -1990,7 +2028,7 @@ window.updateUserByAdmin = async function(userId) {
|
||||
};
|
||||
|
||||
window.deleteUserByAdmin = async function(userId) {
|
||||
if (!confirm('Xóa vĩnh viễn người dùng này?')) return;
|
||||
if (!await window.showConfirmModal('Xóa vĩnh viễn người dùng này?')) return;
|
||||
const token = localStorage.getItem('jwt');
|
||||
try {
|
||||
const res = await fetch(`${API_BASE_URL}/admin/users/${userId}`, {
|
||||
@@ -2170,12 +2208,26 @@ async function loadMyAssets() {
|
||||
*/
|
||||
window.deleteAsset = function(assetId) {
|
||||
assetIdToDelete = assetId;
|
||||
const isDashboardOpen = document.getElementById('dashboard-overlay').style.display === 'flex';
|
||||
if (isDashboardOpen) {
|
||||
dashboardReturnTab = 'media-library';
|
||||
returnToDashboardAfterEdit = true;
|
||||
closeDashboard();
|
||||
} else {
|
||||
returnToDashboardAfterEdit = false;
|
||||
}
|
||||
document.getElementById('delete-asset-confirm-modal').style.display = 'flex';
|
||||
};
|
||||
|
||||
window.closeDeleteAssetModal = function() {
|
||||
document.getElementById('delete-asset-confirm-modal').style.display = 'none';
|
||||
assetIdToDelete = null;
|
||||
if (returnToDashboardAfterEdit) {
|
||||
const targetTab = dashboardReturnTab;
|
||||
returnToDashboardAfterEdit = false;
|
||||
openDashboard();
|
||||
openDashboardTab(targetTab);
|
||||
}
|
||||
};
|
||||
|
||||
window.confirmDeleteAsset = async function() {
|
||||
@@ -2207,6 +2259,40 @@ window.confirmDeleteAsset = async function() {
|
||||
}
|
||||
};
|
||||
|
||||
window.hiddenModalsStack = window.hiddenModalsStack || [];
|
||||
|
||||
window.tempHideActiveModals = function(exceptModalIds = []) {
|
||||
const modals = document.querySelectorAll('.modal, .modal-overlay');
|
||||
const hiddenInThisTurn = [];
|
||||
modals.forEach(modal => {
|
||||
if (exceptModalIds.includes(modal.id)) return;
|
||||
|
||||
const style = window.getComputedStyle(modal);
|
||||
if (style.display !== 'none' && modal.style.display !== 'none') {
|
||||
const originalDisplay = modal.style.display || style.display;
|
||||
modal.setAttribute('data-original-display', originalDisplay);
|
||||
modal.style.display = 'none';
|
||||
hiddenInThisTurn.push(modal);
|
||||
}
|
||||
});
|
||||
if (hiddenInThisTurn.length > 0) {
|
||||
window.hiddenModalsStack.push(hiddenInThisTurn);
|
||||
}
|
||||
};
|
||||
|
||||
window.restorePreviousModals = function() {
|
||||
if (window.hiddenModalsStack && window.hiddenModalsStack.length > 0) {
|
||||
const lastHiddenGroup = window.hiddenModalsStack.pop();
|
||||
lastHiddenGroup.forEach(modal => {
|
||||
if (modal.hasAttribute('data-original-display')) {
|
||||
const originalDisplay = modal.getAttribute('data-original-display') || 'flex';
|
||||
modal.style.display = originalDisplay;
|
||||
modal.removeAttribute('data-original-display');
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Hiển thị Modal thông báo thành công
|
||||
*/
|
||||
@@ -2215,6 +2301,7 @@ window.showSuccessModal = function(message, icon = '✓') {
|
||||
const msgElem = document.getElementById('success-modal-message');
|
||||
const iconElem = document.getElementById('success-modal-icon');
|
||||
if (modal && msgElem && iconElem) {
|
||||
window.tempHideActiveModals(['success-modal']);
|
||||
msgElem.innerText = message;
|
||||
iconElem.innerText = icon;
|
||||
modal.style.display = 'flex';
|
||||
@@ -2231,7 +2318,10 @@ window.closeSuccessModal = function(e) {
|
||||
if (!modal) return;
|
||||
// Nếu nhấn từ code (không có e) hoặc click trúng overlay thì đóng
|
||||
if (e && e.target !== modal) return;
|
||||
modal.style.display = 'none';
|
||||
if (modal.style.display !== 'none') {
|
||||
modal.style.display = 'none';
|
||||
window.restorePreviousModals();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -2243,6 +2333,7 @@ window.showErrorModal = function(message, title = "Thông báo", icon = '⚠️'
|
||||
const titleElem = document.getElementById('error-modal-title');
|
||||
const iconElem = document.getElementById('error-modal-icon');
|
||||
if (modal && msgElem && iconElem) {
|
||||
window.tempHideActiveModals(['error-modal']);
|
||||
msgElem.innerText = message;
|
||||
iconElem.innerText = icon;
|
||||
if (titleElem) titleElem.innerText = title;
|
||||
@@ -2258,7 +2349,10 @@ window.closeErrorModal = function(e) {
|
||||
if (!modal) return;
|
||||
// Nếu nhấn từ code (không có e) hoặc click trúng overlay thì đóng
|
||||
if (e && e.target !== modal) return;
|
||||
modal.style.display = 'none';
|
||||
if (modal.style.display !== 'none') {
|
||||
modal.style.display = 'none';
|
||||
window.restorePreviousModals();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -2274,6 +2368,51 @@ window.showNotification = function(message, type = 'success') {
|
||||
}
|
||||
};
|
||||
|
||||
// Đè hàm alert mặc định của trình duyệt để gọi modal tương ứng
|
||||
window.alert = function(message) {
|
||||
window.showErrorModal(message, 'Thông báo', '⚠️');
|
||||
};
|
||||
|
||||
// Hàm hiển thị confirm dạng modal bất đồng bộ
|
||||
window.showConfirmModal = function(message) {
|
||||
return new Promise((resolve) => {
|
||||
// Tạm ẩn các modal đang mở
|
||||
window.tempHideActiveModals(['generic-confirm-modal']);
|
||||
|
||||
let modal = document.getElementById('generic-confirm-modal');
|
||||
if (!modal) {
|
||||
modal = document.createElement('div');
|
||||
modal.id = 'generic-confirm-modal';
|
||||
modal.className = 'modal-overlay';
|
||||
modal.style.zIndex = '9999';
|
||||
modal.innerHTML = `
|
||||
<div class="modal-content action-modal-content logout-modal-dark" style="border-top: 4px solid #ffc107; max-width: 400px; text-align: center;">
|
||||
<div style="font-size: 40px; color: #ffc107; margin-bottom: 10px;">⚠️</div>
|
||||
<h2 style="color: #fff; margin-bottom: 10px;">Xác nhận</h2>
|
||||
<p id="generic-confirm-message" style="color: #ccc; margin-bottom: 25px; line-height: 1.5; font-size: 14px; text-align: center;"></p>
|
||||
<div class="action-buttons" style="display: flex; gap: 10px; justify-content: center;">
|
||||
<button id="generic-confirm-ok-btn" class="delete-btn-large" style="background: #dc3545; flex: 1; padding: 10px 20px; font-size: 14px; cursor: pointer; border: none; border-radius: 4px; color: white;">Xác nhận</button>
|
||||
<button id="generic-confirm-cancel-btn" class="edit-btn-large" style="background: #6c757d; flex: 1; padding: 10px 20px; font-size: 14px; cursor: pointer; border: none; border-radius: 4px; color: white;">Hủy bỏ</button>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
document.body.appendChild(modal);
|
||||
}
|
||||
|
||||
document.getElementById('generic-confirm-message').innerText = message;
|
||||
modal.style.display = 'flex';
|
||||
|
||||
const handleResolve = (value) => {
|
||||
modal.style.display = 'none';
|
||||
window.restorePreviousModals();
|
||||
resolve(value);
|
||||
};
|
||||
|
||||
document.getElementById('generic-confirm-ok-btn').onclick = () => handleResolve(true);
|
||||
document.getElementById('generic-confirm-cancel-btn').onclick = () => handleResolve(false);
|
||||
});
|
||||
};
|
||||
|
||||
window.openEditFromMedia = function(scene, isChild = false) {
|
||||
if (!scene || !scene._id) {
|
||||
showNotification("Không thể chỉnh sửa: Ảnh này không được gắn với một Scene hợp lệ.", 'error');
|
||||
@@ -2347,7 +2486,11 @@ window.openEditMetadataModal = function(scene, isChildArg = null) {
|
||||
};
|
||||
|
||||
function closeEditMetadataModal() {
|
||||
document.getElementById('edit-scene-metadata-modal').style.display = 'none';
|
||||
const modal = document.getElementById('edit-scene-metadata-modal');
|
||||
if (modal) {
|
||||
modal.style.display = 'none';
|
||||
modal.removeAttribute('data-original-display');
|
||||
}
|
||||
if (returnToDashboardAfterEdit) {
|
||||
const targetTab = dashboardReturnTab;
|
||||
returnToDashboardAfterEdit = false;
|
||||
@@ -2586,7 +2729,7 @@ async function handleBackup() {
|
||||
*/
|
||||
async function handleRestore(input) {
|
||||
if (!input.files || !input.files[0]) return;
|
||||
if (!confirm("CẢNH BÁO: Khôi phục dữ liệu sẽ xóa sạch dữ liệu hiện tại và thay thế bằng dữ liệu từ bản sao lưu. Bạn có chắc chắn?")) {
|
||||
if (!await window.showConfirmModal("CẢNH BÁO: Khôi phục dữ liệu sẽ xóa sạch dữ liệu hiện tại và thay thế bằng dữ liệu từ bản sao lưu. Bạn có chắc chắn?")) {
|
||||
input.value = ''; return;
|
||||
}
|
||||
const token = localStorage.getItem('jwt');
|
||||
@@ -2643,7 +2786,7 @@ async function updateSystemSettings(e) {
|
||||
*/
|
||||
window.recalculateAllTourCenters = async function() {
|
||||
const token = localStorage.getItem('jwt');
|
||||
if (!confirm("Bạn có chắc chắn muốn tính toán lại tọa độ trung tâm cho TOÀN BỘ Tour trong hệ thống? Việc này có thể mất một chút thời gian nếu dữ liệu lớn.")) return;
|
||||
if (!await window.showConfirmModal("Bạn có chắc chắn muốn tính toán lại tọa độ trung tâm cho TOÀN BỘ Tour trong hệ thống? Việc này có thể mất một chút thời gian nếu dữ liệu lớn.")) return;
|
||||
|
||||
try {
|
||||
showNotification("Đang xử lý tính toán lại...", "success");
|
||||
|
||||
Reference in New Issue
Block a user