From 7b3127384c8450c52c9dd2101721f93dc1d5543a Mon Sep 17 00:00:00 2001 From: error311 Date: Mon, 3 Mar 2025 04:03:58 -0500 Subject: [PATCH] some refactoring --- .DS_Store | Bin 6148 -> 6148 bytes auth.js | 129 +++++---- displayFileList.js | 286 +++++++++--------- index.html | 646 +---------------------------------------- upload.js | 124 ++++---- utils.js | 704 +++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 977 insertions(+), 912 deletions(-) create mode 100644 utils.js diff --git a/.DS_Store b/.DS_Store index 84591f9fc8b843ee282bbd6a2b58a3de121ae7a2..72bf487293e1c5e6fe870c8c336a4834691d45b7 100644 GIT binary patch delta 111 zcmZoMXffEJ#uS%p&cMLH!l1{H&XCDalAG`1l9ZF51Qg@Azt+9$;I3nisPZXz response.json()) - .then(data => { - console.log("Login response:", data); - if (data.success) { - console.log("Login successful."); - document.getElementById("loginForm").style.display = "none"; - document.getElementById("uploadFileForm").style.display = "block"; - document.getElementById("fileListContainer").style.display = "block"; - checkAuthentication(); // Recheck authentication to show the file list - } else { - alert("Login failed: " + (data.error || "Unknown error")); - } - }) - .catch(error => console.error("Error logging in:", error)); - }); + document.getElementById("authForm").addEventListener("submit", function (event) { + event.preventDefault(); + const formData = { + username: document.getElementById("loginUsername").value.trim(), + password: document.getElementById("loginPassword").value.trim() + }; + console.log("Sending login data:", formData); + sendRequest("auth.php", "POST", formData) + .then(data => { + console.log("Login response:", data); + if (data.success) { + console.log("Login successful."); + toggleVisibility("loginForm", false); + toggleVisibility("uploadFileForm", true); + toggleVisibility("fileListContainer", true); + checkAuthentication(); // Recheck authentication to update UI. + } else { + alert("Login failed: " + (data.error || "Unknown error")); + } + }) + .catch(error => console.error("Error logging in:", error)); + }); }); -function checkAuthentication() { - fetch("checkAuth.php") - .then(response => response.json()) - .then(data => { - console.log("Authentication check:", data); - if (data.authenticated) { - console.log("User authenticated, showing file list."); - document.getElementById("loginForm").style.display = "none"; - document.getElementById("uploadFileForm").style.display = "block"; - document.getElementById("fileListContainer").style.display = "block"; - loadFileList(); - } else { - // Only log a warning if the file list is supposed to be shown (i.e. after a login) - if (document.getElementById("uploadFileForm").style.display === "block") { - console.warn("User not authenticated."); - } - document.getElementById("loginForm").style.display = "block"; - document.getElementById("uploadFileForm").style.display = "none"; - document.getElementById("fileListContainer").style.display = "none"; - } - }) - .catch(error => console.error("Error checking authentication:", error)); +export function checkAuthentication() { + sendRequest("checkAuth.php") + .then(data => { + console.log("Authentication check:", data); + if (data.setup) { + setupMode = true; + // In setup mode, hide all sections except the Add User modal. + toggleVisibility("loginForm", false); + toggleVisibility("uploadFileForm", false); + toggleVisibility("fileListContainer", false); + document.querySelector(".header-buttons").style.visibility = "hidden"; + toggleVisibility("addUserModal", true); + return; + } else { + setupMode = false; + } + if (data.authenticated) { + toggleVisibility("loginForm", false); + toggleVisibility("uploadFileForm", true); + toggleVisibility("fileListContainer", true); + if (typeof loadFileList === "function") { + loadFileList(); + } + } else { + toggleVisibility("loginForm", true); + toggleVisibility("uploadFileForm", false); + toggleVisibility("fileListContainer", false); + } + }) + .catch(error => console.error("Error checking authentication:", error)); +} +window.checkAuthentication = checkAuthentication; + +// Helper functions for the Add User modal. +function closeAddUserModal() { + toggleVisibility("addUserModal", false); + resetUserForm(); +} + +function resetUserForm() { + document.getElementById("newUsername").value = ""; + document.getElementById("newPassword").value = ""; } diff --git a/displayFileList.js b/displayFileList.js index 0974b68..c2062fe 100644 --- a/displayFileList.js +++ b/displayFileList.js @@ -1,60 +1,70 @@ -let fileData = []; // Store file data globally -let sortOrder = { column: "uploaded", ascending: false }; // Default sorting by uploaded date (newest first) +// displayFileList.js +import { sendRequest, toggleVisibility } from './utils.js'; -// Load and display the file list -window.loadFileList = function () { - fetch("checkAuth.php") - .then(response => response.json()) - .then(authData => { - if (!authData.authenticated) { - console.warn("User not authenticated, hiding file list."); - document.getElementById("fileListContainer").style.display = "none"; - return; - } - document.getElementById("fileListContainer").style.display = "block"; - fetch("getFileList.php") - .then(response => response.json()) - .then(data => { - if (data.error) { - document.getElementById("fileList").innerHTML = `

Error: ${data.error}

`; - return; - } - if (!Array.isArray(data.files)) { - console.error("Unexpected response format:", data); - return; - } - fileData = data.files; // Store file data globally - sortFiles("uploaded", false); // Sort by upload date (newest first) on load - }) - .catch(error => console.error("Error fetching file list:", error)); - }) - .catch(error => console.error("Error checking authentication:", error)); -}; +let fileData = []; +let sortOrder = { column: "uploaded", ascending: false }; -// Sort files when clicking headers -function sortFiles(column, forceAscending = null) { - if (sortOrder.column === column) { - sortOrder.ascending = forceAscending !== null ? forceAscending : !sortOrder.ascending; // Toggle order - } else { - sortOrder.column = column; - sortOrder.ascending = forceAscending !== null ? forceAscending : true; // Default to ascending when switching column - } - fileData.sort((a, b) => { - let valA = a[column] || ""; - let valB = b[column] || ""; - if (typeof valA === "string") valA = valA.toLowerCase(); - if (typeof valB === "string") valB = valB.toLowerCase(); - if (valA < valB) return sortOrder.ascending ? -1 : 1; - if (valA > valB) return sortOrder.ascending ? 1 : -1; - return 0; - }); - renderFileTable(); // Re-render table after sorting +export function loadFileList() { + sendRequest("checkAuth.php") + .then(authData => { + if (!authData.authenticated) { + console.warn("User not authenticated, hiding file list."); + toggleVisibility("fileListContainer", false); + return; + } + toggleVisibility("fileListContainer", true); + return sendRequest("getFileList.php"); + }) + .then(data => { + if (!data) return; + if (data.error) { + document.getElementById("fileList").innerHTML = `

Error: ${data.error}

`; + return; + } + if (!Array.isArray(data.files)) { + console.error("Unexpected response format:", data); + return; + } + fileData = data.files; + sortFiles("uploaded", false); + }) + .catch(error => console.error("Error loading file list:", error)); } -// Function to render file table -function renderFileTable() { - const fileListContainer = document.getElementById("fileList"); - let tableHTML = ` +export function sortFiles(column, forceAscending = null) { + if (sortOrder.column === column) { + sortOrder.ascending = forceAscending !== null ? forceAscending : !sortOrder.ascending; + } else { + sortOrder.column = column; + sortOrder.ascending = forceAscending !== null ? forceAscending : true; + } + fileData.sort((a, b) => { + let valA = a[column] || ""; + let valB = b[column] || ""; + if (column === "modified" || column === "uploaded") { + const dateA = new Date(valA); + const dateB = new Date(valB); + if (!isNaN(dateA.getTime()) && !isNaN(dateB.getTime())) { + valA = dateA.getTime(); + valB = dateB.getTime(); + } else { + valA = valA.toLowerCase(); + valB = valB.toLowerCase(); + } + } else if (typeof valA === "string") { + valA = valA.toLowerCase(); + valB = valB.toLowerCase(); + } + if (valA < valB) return sortOrder.ascending ? -1 : 1; + if (valA > valB) return sortOrder.ascending ? 1 : -1; + return 0; + }); + renderFileTable(); +} + +export function renderFileTable() { + const fileListContainer = document.getElementById("fileList"); + let tableHTML = `
@@ -67,8 +77,8 @@ function renderFileTable() { - `; - - fileData.forEach(file => { - const isEditable = file.name.endsWith(".txt") || file.name.endsWith(".json") || - file.name.endsWith(".ini") || file.name.endsWith(".css") || - file.name.endsWith(".js") || file.name.endsWith(".csv") || - file.name.endsWith(".md") || file.name.endsWith(".xml") || - file.name.endsWith(".html") || file.name.endsWith(".py") || - file.name.endsWith(".log") || file.name.endsWith(".conf") || - file.name.endsWith(".config") || file.name.endsWith(".bat") || - file.name.endsWith(".rtf") || file.name.endsWith(".doc") || - file.name.endsWith(".docx"); - tableHTML += ` + + fileData.forEach(file => { + const isEditable = file.name.endsWith(".txt") || file.name.endsWith(".json") || + file.name.endsWith(".ini") || file.name.endsWith(".css") || + file.name.endsWith(".js") || file.name.endsWith(".csv") || + file.name.endsWith(".md") || file.name.endsWith(".xml") || + file.name.endsWith(".html") || file.name.endsWith(".py") || + file.name.endsWith(".log") || file.name.endsWith(".conf") || + file.name.endsWith(".config") || file.name.endsWith(".bat") || + file.name.endsWith(".rtf") || file.name.endsWith(".doc") || + file.name.endsWith(".docx"); + tableHTML += ` @@ -102,73 +112,60 @@ function renderFileTable() { `; - }); - - tableHTML += `
Upload Date ${sortOrder.column === "uploaded" ? (sortOrder.ascending ? "▲" : "▼") : ""} - File Size ${sortOrder.column === "sizeBytes" ? (sortOrder.ascending ? "▲" : "▼") : ""} + + File Size ${sortOrder.column === "size" ? (sortOrder.ascending ? "▲" : "▼") : ""} Uploader ${sortOrder.column === "uploader" ? (sortOrder.ascending ? "▲" : "▼") : ""} @@ -77,18 +87,18 @@ function renderFileTable() {
${file.name} ${file.modified}
`; - fileListContainer.innerHTML = tableHTML; - - // Always display the batch delete button if there are files; disable it if no file is selected. - const deleteBtn = document.getElementById("deleteSelectedBtn"); - if (fileData.length > 0) { - deleteBtn.style.display = "block"; - // Check if any checkboxes are selected to enable the button; if none, disable it. - const selectedFiles = document.querySelectorAll(".file-checkbox:checked"); - deleteBtn.disabled = selectedFiles.length === 0; - } else { - deleteBtn.style.display = "none"; - } -} - -// Function to toggle delete button enabled state -function toggleDeleteButton() { + }); + + tableHTML += ``; + fileListContainer.innerHTML = tableHTML; + + const deleteBtn = document.getElementById("deleteSelectedBtn"); + if (fileData.length > 0) { + deleteBtn.style.display = "block"; const selectedFiles = document.querySelectorAll(".file-checkbox:checked"); - const deleteBtn = document.getElementById("deleteSelectedBtn"); deleteBtn.disabled = selectedFiles.length === 0; + } else { + deleteBtn.style.display = "none"; + } } -// Select/Deselect All Checkboxes -window.toggleAllCheckboxes = function (source) { - const checkboxes = document.querySelectorAll(".file-checkbox"); - checkboxes.forEach(checkbox => checkbox.checked = source.checked); - toggleDeleteButton(); -}; +export function toggleDeleteButton() { + const selectedFiles = document.querySelectorAll(".file-checkbox:checked"); + const deleteBtn = document.getElementById("deleteSelectedBtn"); + deleteBtn.disabled = selectedFiles.length === 0; +} -// Batch delete function -window.deleteSelectedFiles = function () { - const selectedFiles = Array.from(document.querySelectorAll(".file-checkbox:checked")) - .map(checkbox => checkbox.value); - if (selectedFiles.length === 0) { - alert("No files selected for deletion."); - return; - } - if (!confirm(`Are you sure you want to delete the selected files?`)) { - return; - } - fetch("deleteFiles.php", { - method: "POST", - headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ files: selectedFiles }) - }) - .then(response => response.json()) +export function toggleAllCheckboxes(source) { + const checkboxes = document.querySelectorAll(".file-checkbox"); + checkboxes.forEach(checkbox => checkbox.checked = source.checked); + toggleDeleteButton(); +} + +export function deleteSelectedFiles() { + const selectedFiles = Array.from(document.querySelectorAll(".file-checkbox:checked")) + .map(checkbox => checkbox.value); + if (selectedFiles.length === 0) { + alert("No files selected for deletion."); + return; + } + if (!confirm("Are you sure you want to delete the selected files?")) { + return; + } + sendRequest("deleteFiles.php", "POST", { files: selectedFiles }) .then(result => { - alert(result.success || result.error); - loadFileList(); + alert(result.success || result.error); + loadFileList(); }) .catch(error => console.error("Error deleting files:", error)); -}; +} -// Attach event listener to batch delete button document.addEventListener("DOMContentLoaded", function () { - const deleteBtn = document.getElementById("deleteSelectedBtn"); - if (deleteBtn) { - deleteBtn.addEventListener("click", deleteSelectedFiles); - } + const deleteBtn = document.getElementById("deleteSelectedBtn"); + if (deleteBtn) { + deleteBtn.addEventListener("click", deleteSelectedFiles); + } }); -window.editFile = function(fileName) { +export function editFile(fileName) { const threshold = 10 * 1024 * 1024; // 10 MB threshold - - // Check file size via HEAD request. fetch(`uploads/${encodeURIComponent(fileName)}`, { method: 'HEAD' }) .then(response => { const fileSize = parseInt(response.headers.get('Content-Length') || "0", 10); @@ -187,7 +184,6 @@ window.editFile = function(fileName) { if (!content) return; const modal = document.createElement("div"); modal.id = "editorContainer"; - // Use your existing classes for styling. modal.classList.add("modal", "editor-modal"); modal.innerHTML = `

Editing: ${fileName}

@@ -201,28 +197,32 @@ window.editFile = function(fileName) { modal.style.display = "block"; }) .catch(error => console.error("Error in editFile:", error)); -}; +} -window.saveFile = function(fileName) { - const editor = document.getElementById("fileEditor"); - if (!editor) { - console.error("Editor not found!"); - return; - } - const fileData = { - fileName: fileName, - content: editor.value - }; - fetch("saveFile.php", { - method: "POST", - headers: { "Content-Type": "application/json" }, - body: JSON.stringify(fileData) - }) - .then(response => response.json()) +export function saveFile(fileName) { + const editor = document.getElementById("fileEditor"); + if (!editor) { + console.error("Editor not found!"); + return; + } + const fileData = { + fileName: fileName, + content: editor.value + }; + sendRequest("saveFile.php", "POST", fileData) .then(result => { - alert(result.success || result.error); - document.getElementById("editorContainer")?.remove(); - loadFileList(); + alert(result.success || result.error); + document.getElementById("editorContainer")?.remove(); + loadFileList(); }) .catch(error => console.error("Error saving file:", error)); -}; +} + +// To support inline onclick attributes in the generated HTML, attach these functions to window. +window.sortFiles = sortFiles; +window.toggleDeleteButton = toggleDeleteButton; +window.toggleAllCheckboxes = toggleAllCheckboxes; +window.deleteSelectedFiles = deleteSelectedFiles; +window.editFile = editFile; +window.saveFile = saveFile; +window.loadFileList = loadFileList; diff --git a/index.html b/index.html index e3bc57f..4ef21ac 100644 --- a/index.html +++ b/index.html @@ -1,6 +1,5 @@ - @@ -15,9 +14,11 @@ - - - + + + + + -
@@ -159,7 +158,6 @@
-
@@ -177,7 +175,6 @@
-