feat: Add edit functionality for marketing files and update handling
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -23,3 +23,6 @@ assets/database/migration_v3.sql
|
|||||||
api/.DS_Store
|
api/.DS_Store
|
||||||
api/v1/.DS_Store
|
api/v1/.DS_Store
|
||||||
api/v2/.DS_Store
|
api/v2/.DS_Store
|
||||||
|
api/.DS_Store
|
||||||
|
assets/.DS_Store
|
||||||
|
assets/images/.DS_Store
|
||||||
|
|||||||
BIN
api/.DS_Store
vendored
BIN
api/.DS_Store
vendored
Binary file not shown.
BIN
api/v1/.DS_Store
vendored
BIN
api/v1/.DS_Store
vendored
Binary file not shown.
BIN
api/v2/.DS_Store
vendored
BIN
api/v2/.DS_Store
vendored
Binary file not shown.
71
api/v2/post/marketing_update.php
Normal file
71
api/v2/post/marketing_update.php
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
<?php
|
||||||
|
defined($security_key) or exit;
|
||||||
|
|
||||||
|
//------------------------------------------
|
||||||
|
// Marketing Update
|
||||||
|
//------------------------------------------
|
||||||
|
//Connect to DB
|
||||||
|
$pdo = dbConnect($dbname);
|
||||||
|
|
||||||
|
//SoldTo is empty
|
||||||
|
if (empty($partner->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']);
|
||||||
|
}
|
||||||
|
?>
|
||||||
BIN
assets/.DS_Store
vendored
BIN
assets/.DS_Store
vendored
Binary file not shown.
BIN
assets/images/.DS_Store
vendored
BIN
assets/images/.DS_Store
vendored
Binary file not shown.
@@ -100,6 +100,11 @@ class MarketingFileManager {
|
|||||||
this.deleteFile(this.selectedFile);
|
this.deleteFile(this.selectedFile);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Save edit
|
||||||
|
document.getElementById('saveEdit')?.addEventListener('click', () => {
|
||||||
|
this.saveEdit();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
bindUploadEvents() {
|
bindUploadEvents() {
|
||||||
@@ -359,6 +364,9 @@ class MarketingFileManager {
|
|||||||
<button class="download-btn" title="Download">
|
<button class="download-btn" title="Download">
|
||||||
<i class="fa fa-download"></i>
|
<i class="fa fa-download"></i>
|
||||||
</button>
|
</button>
|
||||||
|
<button class="edit-btn" title="Edit">
|
||||||
|
<i class="fa fa-edit"></i>
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="file-info">
|
<div class="file-info">
|
||||||
@@ -385,6 +393,10 @@ class MarketingFileManager {
|
|||||||
this.downloadFile(file);
|
this.downloadFile(file);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
fileElement.querySelector('.edit-btn').addEventListener('click', () => {
|
||||||
|
this.editFile(file);
|
||||||
|
});
|
||||||
|
|
||||||
fileElement.addEventListener('dblclick', () => {
|
fileElement.addEventListener('dblclick', () => {
|
||||||
this.previewFile(file);
|
this.previewFile(file);
|
||||||
});
|
});
|
||||||
@@ -870,6 +882,96 @@ class MarketingFileManager {
|
|||||||
return iconMap[fileType.toLowerCase()] || 'fa-file';
|
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 = '<option value="">Root Folder</option>';
|
||||||
|
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 = '<i class="fa fa-spinner fa-spin"></i> 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) {
|
updateQueueItem(index, item) {
|
||||||
const queueItems = document.querySelectorAll('.upload-item');
|
const queueItems = document.querySelectorAll('.upload-item');
|
||||||
if (queueItems[index]) {
|
if (queueItems[index]) {
|
||||||
|
|||||||
0
custom/morvalwatches/style/VeLiTi-Logo2.png
Normal file → Executable file
0
custom/morvalwatches/style/VeLiTi-Logo2.png
Normal file → Executable file
|
Before Width: | Height: | Size: 2.7 KiB After Width: | Height: | Size: 2.7 KiB |
@@ -125,6 +125,15 @@ if (isset($_GET['action'])) {
|
|||||||
echo $response;
|
echo $response;
|
||||||
exit;
|
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) {
|
} catch (Exception $e) {
|
||||||
header('Content-Type: application/json');
|
header('Content-Type: application/json');
|
||||||
http_response_code(500);
|
http_response_code(500);
|
||||||
@@ -364,6 +373,42 @@ template_header('Marketing', 'marketing');
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Edit File Modal -->
|
||||||
|
<?php if ($update_allowed === 1): ?>
|
||||||
|
<div id="editModal" class="modal">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h3>Edit File</h3>
|
||||||
|
<button class="modal-close">×</button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="editTitle">Title:</label>
|
||||||
|
<input type="text" id="editTitle" class="form-control" placeholder="Enter file title">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="editFolder">Folder:</label>
|
||||||
|
<select id="editFolder" class="form-control">
|
||||||
|
<option value="">Root Folder</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="editTags">Tags (comma separated):</label>
|
||||||
|
<input type="text" id="editTags" class="form-control" placeholder="marketing, brochure, product">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button id="saveEdit" class="btn btn-primary">
|
||||||
|
<i class="fa fa-save"></i> Save Changes
|
||||||
|
</button>
|
||||||
|
<button class="modal-cancel btn btn-secondary">Cancel</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
<script src="./assets/marketing.js"></script>
|
<script src="./assets/marketing.js"></script>
|
||||||
|
|
||||||
<?php
|
<?php
|
||||||
|
|||||||
@@ -414,7 +414,7 @@
|
|||||||
display: none;
|
display: none;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
z-index: 1000;
|
z-index: 1000001;
|
||||||
}
|
}
|
||||||
|
|
||||||
.modal.show {
|
.modal.show {
|
||||||
|
|||||||
Reference in New Issue
Block a user