From be6f73b19c1c7a6d66d7ab247751085e6f32a2e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CVeLiTi=E2=80=9D?= <“info@veliti.nl”> Date: Mon, 12 Jan 2026 10:51:55 +0100 Subject: [PATCH] feat: Add edit functionality for marketing files and update handling --- .DS_Store | Bin 12292 -> 12292 bytes .gitignore | 3 + api/.DS_Store | Bin 6148 -> 6148 bytes api/v1/.DS_Store | Bin 6148 -> 6148 bytes api/v2/.DS_Store | Bin 6148 -> 6148 bytes api/v2/post/marketing_update.php | 71 ++++++++++++++ assets/.DS_Store | Bin 6148 -> 6148 bytes assets/images/.DS_Store | Bin 6148 -> 6148 bytes assets/marketing.js | 102 ++++++++++++++++++++ custom/morvalwatches/style/VeLiTi-Logo2.png | Bin marketing.php | 45 +++++++++ style/marketing.css | 2 +- 12 files changed, 222 insertions(+), 1 deletion(-) create mode 100644 api/v2/post/marketing_update.php mode change 100644 => 100755 custom/morvalwatches/style/VeLiTi-Logo2.png diff --git a/.DS_Store b/.DS_Store index 1b6483b1c4bed5cc3953daaf953afd7a34f838bf..9d4c452e8d05565dc11a62679d1101247abf067b 100644 GIT binary patch delta 63 zcmZokXi1ph&uFOs=$R$85kIt7|Ixoa`RnWl5+BsfP9WQ#$tC9KOA#J$fe+v bE66YmPR`FQ0IFqRU~iaMxMwpv$6tN`mHi(E diff --git a/api/v1/.DS_Store b/api/v1/.DS_Store index cb2f10e1357faf68309e1e8364e209576c0aa91c..ad7d9ddda816a54c2ad792535b6d79ae8299b745 100644 GIT binary patch delta 15 WcmZoMXffE(!@^{vy}6I2Oc($v0|ejz delta 15 WcmZoMXffE(!@^|Cw7HL^Oc($u6a=^c diff --git a/api/v2/.DS_Store b/api/v2/.DS_Store index c28ab400b19f012f4b0c962037a8f72c937b427b..16d8e396faeb73974af56135799be2f37bed8a85 100644 GIT binary patch delta 323 zcmZoMXfc=|#>B)qu~2NHo}wrh0|Nsi1A_oVaY0f}eiD$kBdK6BBhzxmdXN+|Lpnn$ zLrGFOvUE;nafyM!HAW_87FITP4t5T1j@aOg{PN(E#FEltr^KRY5HBP@KPL&sPD~2R zOf8QW5OL1WD@n}EODzIx$V^EEDv1ft%uC5Hcgio#ODP8H4F*aC0A)BhIXL45B&w^; zOpSCD49(4Jbrh;CjSO@YOpMKHYdJYYmG!NI;B`mu~2NHo}wrR0|Nsi1A_pAVQ_MOZUK)+c G7G?lQksJL0 diff --git a/api/v2/post/marketing_update.php b/api/v2/post/marketing_update.php new file mode 100644 index 0000000..1062147 --- /dev/null +++ b/api/v2/post/marketing_update.php @@ -0,0 +1,71 @@ +soldto) || $partner->soldto == ''){$soldto_search = '%';} else {$soldto_search = '-%';} + +//default whereclause +list($whereclause,$condition) = getWhereclauselvl2("",$permission,$partner,''); + +//QUERY AND VERIFY ALLOWED +if (isAllowed('marketing',$profile,$permission,'U') === 1){ + // Get JSON input + $input = json_decode(file_get_contents('php://input'), true); + + $file_id = $input['file_id'] ?? ''; + $folder_id = $input['folder_id'] ?? ''; + $tags = $input['tags'] ?? []; + $title = $input['title'] ?? ''; + + if (empty($file_id)) { + echo json_encode(['success' => false, 'error' => 'File ID is required']); + exit; + } + + try { + // Update file + $update_sql = 'UPDATE `marketing_files` SET `title` = ?, `folder_id` = ? WHERE `id` = ? AND `accounthierarchy` LIKE ?'; + $stmt = $pdo->prepare($update_sql); + $stmt->execute([ + $title, + $folder_id ?: null, + $file_id, + $condition + ]); + + if ($stmt->rowCount() === 0) { + echo json_encode(['success' => false, 'error' => 'File not found or access denied']); + exit; + } + + // Update tags - first remove existing + $pdo->prepare('DELETE FROM `marketing_file_tags` WHERE `file_id` = ?')->execute([$file_id]); + + // Insert new tags + if (!empty($tags)) { + $tag_sql = 'INSERT IGNORE INTO `marketing_tags` (`tag_name`) VALUES (?)'; + $tag_stmt = $pdo->prepare($tag_sql); + + $file_tag_sql = 'INSERT INTO `marketing_file_tags` (`file_id`, `tag_id`) SELECT ?, id FROM marketing_tags WHERE tag_name = ?'; + $file_tag_stmt = $pdo->prepare($file_tag_sql); + + foreach ($tags as $tag) { + $tag_stmt->execute([trim($tag)]); + $file_tag_stmt->execute([$file_id, trim($tag)]); + } + } + + echo json_encode(['success' => true, 'message' => 'File updated successfully']); + } catch (Exception $e) { + echo json_encode(['success' => false, 'error' => 'Update failed: ' . $e->getMessage()]); + } +} else { + echo json_encode(['success' => false, 'error' => 'Insufficient permissions']); +} +?> \ No newline at end of file diff --git a/assets/.DS_Store b/assets/.DS_Store index 7502f1f324f78f13bfed6b98ca295d7072285086..1ba4cf5a23caa3cca1ed969ea790723f77e30419 100644 GIT binary patch delta 31 ncmZoMXfc@J&&ahgU^g=(*JK_Rw3OoHr2PCG#?3Y?>zFsQ IbNuB80FWLJ3jhEB diff --git a/assets/images/.DS_Store b/assets/images/.DS_Store index a97d4fbaa404ff33dc6f3ce0b447852bdbc24d80..12648aee244ff9e88c6e0a810e6dfa961ee7437f 100644 GIT binary patch delta 31 ncmZoMXfc@J&&abeU^g=(&t@K$$4ryG+4oFrh}q1}@s}R}qwxx* delta 110 zcmZoMXfc@J&&azmU^g=(?`9sB$4r4@3?U4`Kp4-E$&klT#*h!BlNnNh{0tzO$dCdg zix~763V^cdDVaIRNjdpR3=9kkK+M3v#K7?X|G#5EypMs=Sf7EBnRoINw&R=GIsWnk E0P`gt5&!@I diff --git a/assets/marketing.js b/assets/marketing.js index 30f8c9c..d5581f7 100644 --- a/assets/marketing.js +++ b/assets/marketing.js @@ -100,6 +100,11 @@ class MarketingFileManager { this.deleteFile(this.selectedFile); } }); + + // Save edit + document.getElementById('saveEdit')?.addEventListener('click', () => { + this.saveEdit(); + }); } bindUploadEvents() { @@ -359,6 +364,9 @@ class MarketingFileManager { +
@@ -385,6 +393,10 @@ class MarketingFileManager { this.downloadFile(file); }); + fileElement.querySelector('.edit-btn').addEventListener('click', () => { + this.editFile(file); + }); + fileElement.addEventListener('dblclick', () => { this.previewFile(file); }); @@ -870,6 +882,96 @@ class MarketingFileManager { return iconMap[fileType.toLowerCase()] || 'fa-file'; } + // Edit file functionality + editFile(file) { + this.selectedFile = file; + this.showEditModal(); + this.populateEditModal(file); + } + + showEditModal() { + const modal = document.getElementById('editModal'); + if (modal) { + this.showModal(modal); + } + } + + populateEditModal(file) { + // Populate title + const titleInput = document.getElementById('editTitle'); + if (titleInput) { + titleInput.value = file.title || ''; + } + + // Populate folder select + const folderSelect = document.getElementById('editFolder'); + if (folderSelect) { + folderSelect.innerHTML = ''; + this.addFolderOptions(folderSelect, this.folders); + + // Select current folder + if (file.folder_id) { + folderSelect.value = file.folder_id; + } + } + + // Populate tags + const tagsInput = document.getElementById('editTags'); + if (tagsInput) { + tagsInput.value = file.tags ? file.tags.join(', ') : ''; + } + } + + saveEdit() { + if (!this.selectedFile) return; + + const title = document.getElementById('editTitle').value.trim(); + const folderId = document.getElementById('editFolder').value; + const tags = document.getElementById('editTags').value.trim(); + + // Prepare update data + const updateData = { + file_id: this.selectedFile.id, + title: title || null, + folder_id: folderId || null, + tags: tags ? tags.split(',').map(tag => tag.trim()).filter(tag => tag) : [] + }; + + // Show loading state + const saveBtn = document.getElementById('saveEdit'); + const originalText = saveBtn.innerHTML; + saveBtn.innerHTML = ' Saving...'; + saveBtn.disabled = true; + + // Send update request + fetch('./marketing.php?action=update_file', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify(updateData) + }) + .then(response => response.json()) + .then(data => { + if (data.success) { + this.showToast('File updated successfully!', 'success'); + this.closeModal(document.getElementById('editModal')); + this.loadFiles(); // Reload to show changes + } else { + throw new Error(data.message || 'Failed to update file'); + } + }) + .catch(error => { + console.error('Update error:', error); + this.showToast('Error updating file: ' + error.message, 'error'); + }) + .finally(() => { + // Restore button state + saveBtn.innerHTML = originalText; + saveBtn.disabled = false; + }); + } + updateQueueItem(index, item) { const queueItems = document.querySelectorAll('.upload-item'); if (queueItems[index]) { diff --git a/custom/morvalwatches/style/VeLiTi-Logo2.png b/custom/morvalwatches/style/VeLiTi-Logo2.png old mode 100644 new mode 100755 diff --git a/marketing.php b/marketing.php index 009f561..abdee3c 100644 --- a/marketing.php +++ b/marketing.php @@ -125,6 +125,15 @@ if (isset($_GET['action'])) { echo $response; exit; } + + // Marketing update + if ($action === 'marketing_update' && $_SERVER['REQUEST_METHOD'] === 'POST') { + $payload = $_POST; + $response = ioServer('/v2/marketing_update', json_encode($payload)); + header('Content-Type: application/json'); + echo $response; + exit; + } } catch (Exception $e) { header('Content-Type: application/json'); http_response_code(500); @@ -364,6 +373,42 @@ template_header('Marketing', 'marketing');
+ + + + +