From 36614817cb222ade1de9fe2fe08624e25e5a475d Mon Sep 17 00:00:00 2001 From: chark1es Date: Thu, 13 Feb 2025 05:39:25 -0800 Subject: [PATCH] fix file deletion --- .../dashboard/Officer_EventManagement.astro | 206 +++++++++++------- 1 file changed, 122 insertions(+), 84 deletions(-) diff --git a/src/components/dashboard/Officer_EventManagement.astro b/src/components/dashboard/Officer_EventManagement.astro index 426d3a9..f06d9b0 100644 --- a/src/components/dashboard/Officer_EventManagement.astro +++ b/src/components/dashboard/Officer_EventManagement.astro @@ -80,6 +80,7 @@ declare global { [key: string]: any; openEditModal: (event?: any) => void; deleteFile: (eventId: string, filename: string) => void; + undoDeleteFile: (eventId: string, filename: string) => void; previewFile: (url: string, filename: string) => void; openDetailsModal: (event: Event) => void; showFilePreview: (file: { @@ -923,6 +924,7 @@ declare global { // Add file storage const selectedFileStorage = new Map(); + const filesToDelete = new Set(); // Add storage for files to delete interface AttendeeEntry { user_id: string; @@ -2021,7 +2023,7 @@ declare global { return files .map( (filename) => ` -
+
${filename}
- +
+ ${ + filesToDelete.has(filename) + ? `` + : `` + } +
` @@ -2141,10 +2149,8 @@ declare global { // Immediately disable buttons and show loading state submitButton.disabled = true; cancelButton.disabled = true; - submitButton.innerHTML = ` - - Saving... - `; + submitButton.classList.add("btn-disabled"); + submitButton.innerHTML = ``; try { const formData = new FormData(form); @@ -2179,22 +2185,49 @@ declare global { try { if (eventId) { // Update existing event - submitButton.innerHTML = ` - - Updating event... - `; + submitButton.innerHTML = ``; + + // Get current event data to process file changes + const pb = auth.getPocketBase(); + const currentEvent = await pb + .collection("events") + .getOne(eventId); + const currentFiles = currentEvent.files || []; + + // Filter out files marked for deletion + const remainingFiles = currentFiles.filter( + (filename: string) => !filesToDelete.has(filename) + ); + + // Update event with remaining files + const eventDataWithFiles = { + ...eventData, + files: remainingFiles, + }; + + // Update the event data first updatedEvent = await update.updateFields( "events", eventId, - eventData + eventDataWithFiles ); - // Handle file uploads if any + // Process file deletions + for (const filename of filesToDelete) { + await fileManager.deleteFile( + "events", + eventId, + filename + ); + await sendLog.send( + "delete", + "event_file", + `Deleted file ${filename} from event ${eventData.event_name}` + ); + } + + // Then handle new file uploads if any if (selectedFiles.length > 0) { - submitButton.innerHTML = ` - - Uploading files (0/${selectedFiles.length})... - `; await fileManager.appendFiles( "events", eventId, @@ -2210,10 +2243,7 @@ declare global { ); } else { // Create new event - submitButton.innerHTML = ` - - Creating event... - `; + submitButton.innerHTML = ``; const pb = auth.getPocketBase(); const newEvent = await pb .collection("events") @@ -2221,10 +2251,6 @@ declare global { // Handle file uploads if any if (selectedFiles.length > 0) { - submitButton.innerHTML = ` - - Uploading files (0/${selectedFiles.length})... - `; await fileManager.uploadFiles( "events", newEvent.id, @@ -2241,13 +2267,12 @@ declare global { } // Show success state briefly + submitButton.classList.remove("btn-disabled"); + submitButton.classList.add("btn-success"); submitButton.innerHTML = ` -
- - - - Saved! -
+ + + `; await new Promise((resolve) => setTimeout(resolve, 1000)); @@ -2262,7 +2287,7 @@ declare global { await refreshCache(); // Refresh the cache await fetchEvents(); // Update the UI - // Clear form inputs + // Clear form inputs and storage const formFileInput = document.getElementById( "editEventFiles" ) as HTMLInputElement; @@ -2270,85 +2295,98 @@ declare global { if (formFileInput) formFileInput.value = ""; if (newFiles) newFiles.innerHTML = ""; - // Clear storage after successful upload + // Clear storages after successful save selectedFileStorage.clear(); + filesToDelete.clear(); } catch (error) { - throw error; // Re-throw to be caught by outer try-catch + throw error; } } catch (error) { console.error("Failed to save event:", error); - // Show error message in the button with icon + submitButton.classList.remove("btn-disabled"); + submitButton.classList.add("btn-error"); submitButton.innerHTML = ` -
- - + + - Failed -
- `; + `; await new Promise((resolve) => setTimeout(resolve, 2000)); - // Show detailed error to user alert("Failed to save event. Please try again."); } finally { - // Reset button state submitButton.disabled = false; cancelButton.disabled = false; + submitButton.classList.remove( + "btn-disabled", + "btn-success", + "btn-error" + ); submitButton.innerHTML = originalText; window.hideLoading?.(); } }); - // Clear storage when modal is closed + // Clear both storages when modal is closed document.getElementById("editEventModal")?.addEventListener("close", () => { selectedFileStorage.clear(); + filesToDelete.clear(); }); // Add delete file handler window.deleteFile = async function (eventId: string, filename: string) { - if (!confirm("Are you sure you want to delete this file?")) return; + if (!confirm("Are you sure you want to remove this file?")) return; try { - window.showLoading?.(); - const pb = auth.getPocketBase(); + // Add file to deletion set + filesToDelete.add(filename); - // Get current event data - const event = await pb.collection("events").getOne(eventId); - - // Filter out the file to delete - const updatedFiles = event.files.filter( - (f: string) => f !== filename - ); - - // Update the event with the new files array - await pb.collection("events").update(eventId, { - files: updatedFiles, - }); - - await sendLog.send( - "delete", - "event_file", - `Deleted file ${filename} from event ${event.event_name}` - ); - - // Refresh the current files display + // Update the UI to show file as pending deletion const currentFiles = document.getElementById("currentFiles"); - if (currentFiles && updatedFiles.length > 0) { - currentFiles.innerHTML = updateFilePreviewButtons( - updatedFiles, - eventId + if (currentFiles) { + const fileElement = currentFiles.querySelector( + `[data-filename="${filename}"]` ); - } else if (currentFiles) { - currentFiles.innerHTML = ` -
-

No files attached

-
- `; + if (fileElement) { + fileElement.classList.add("opacity-50"); + const deleteButton = + fileElement.querySelector(".text-error"); + if (deleteButton) { + deleteButton.innerHTML = ` + + `; + } + } } } catch (error) { - console.error("Failed to delete file:", error); - alert("Failed to delete file. Please try again."); - } finally { - window.hideLoading?.(); + console.error("Failed to stage file deletion:", error); + alert("Failed to stage file deletion. Please try again."); + } + }; + + // Add undo delete function + window.undoDeleteFile = function (eventId: string, filename: string) { + filesToDelete.delete(filename); + + // Update the UI to show file as restored + const currentFiles = document.getElementById("currentFiles"); + if (currentFiles) { + const fileElement = currentFiles.querySelector( + `[data-filename="${filename}"]` + ); + if (fileElement) { + fileElement.classList.remove("opacity-50"); + const undoButton = fileElement.querySelector(".text-error"); + if (undoButton) { + undoButton.innerHTML = ` + + `; + } + } } };