feat(frontend): add delete confirmation modal for library management

-- Add dedicated delete confirmation modal to admin/library page
-- Refactor deleteLibrary() to use modal instead of inline confirm()
-- Add showDeleteModal(), hideDeleteModal(), confirmDeleteLibrary() functions
-- Modal displays clear warning about what gets deleted
-- Improves UX by making the confirmation dialog more prominent and informative
This commit is contained in:
2026-02-23 20:23:56 -05:00
parent be49bc13a7
commit 85ba3d4060
3 changed files with 306 additions and 213 deletions
+66 -33
View File
@@ -195,33 +195,7 @@ async function deleteLibrary(libraryId: string): Promise<void> {
const library = libraries.find(l => l.id === libraryId);
if (!library) return;
const message = `Are you sure you want to delete "${library.name}"?
This will remove:
• Library metadata from the database
• All folder references
• All book records from the database
⚠️ Book files on disk will NOT be deleted.
This action cannot be undone.`;
if (!confirm(message)) {
return;
}
try {
const response = await (window as any).api.delete(`/libraries/${libraryId}`);
await (window as any).api.handleVoidResponse(response);
if ((window as any).showToast?.success) {
(window as any).showToast.success('Library deleted successfully');
}
await reloadLibraries();
} catch (error) {
(window as any).api.handleError(error, 'Failed to delete library');
}
showDeleteModal(library);
}
// Show library folders
@@ -361,6 +335,60 @@ function hideCreateLibraryModal(): void {
}
}
// Delete modal state
let libraryToDelete: Library | null = null;
function showDeleteModal(library: Library): void {
libraryToDelete = library;
const modal = document.getElementById('delete-library-modal') as HTMLElement;
const content = document.getElementById('delete-modal-content') as HTMLElement;
if (modal && content) {
const message = `Are you sure you want to delete "<strong>${escapeHtmlLocal(library.name)}</strong>"?
This will remove:
• Library metadata from the database
• All folder references
• All book records from the database
⚠️ Book files on disk will NOT be deleted.
This action cannot be undone.`;
content.innerHTML = message.replace(/\n/g, '<br>');
modal.classList.remove('hidden');
}
}
function hideDeleteModal(): void {
const modal = document.getElementById('delete-library-modal') as HTMLElement;
if (modal) {
modal.classList.add('hidden');
}
libraryToDelete = null;
}
async function confirmDeleteLibrary(): Promise<void> {
if (!libraryToDelete) return;
const libraryId = libraryToDelete.id;
hideDeleteModal();
try {
const response = await (window as any).api.delete(`/libraries/${libraryId}`);
await (window as any).api.handleVoidResponse(response);
if ((window as any).showToast?.success) {
(window as any).showToast.success('Library deleted successfully');
}
await reloadLibraries();
} catch (error) {
(window as any).api.handleError(error, 'Failed to delete library');
}
}
// Local escape HTML helper
function escapeHtmlLocal(text: string): string {
const div = document.createElement('div');
@@ -443,6 +471,12 @@ function handleGlobalClick(event: Event): void {
case 'hide-create-modal':
hideCreateLibraryModal();
break;
case 'hide-delete-modal':
hideDeleteModal();
break;
case 'confirm-delete':
void confirmDeleteLibrary();
break;
}
}
@@ -564,12 +598,8 @@ function initializeLibraryAdmin(): void {
createLibraryForm.addEventListener('submit', handleCreateLibrarySubmit);
}
// Initial data is already SSR'd, no need to fetch
// Just store it for updates
const ssrLibraries = document.querySelectorAll('#libraries-list [data-library-id]');
if (ssrLibraries.length === 0) {
// No libraries SSR'd, which is fine
}
// Load libraries from API on page load
void reloadLibraries();
}
// Export functions for global access
@@ -585,6 +615,9 @@ function initializeLibraryAdmin(): void {
(window as any).navigateFolderBrowser = navigateFolderBrowser;
(window as any).selectBrowseFolder = selectBrowseFolder;
(window as any).hideFolderBrowser = hideFolderBrowser;
(window as any).showDeleteModal = showDeleteModal;
(window as any).hideDeleteModal = hideDeleteModal;
(window as any).confirmDeleteLibrary = confirmDeleteLibrary;
// Initialize on DOM ready
if (document.readyState === 'loading') {