This commit is contained in:
emmymayo
2025-02-04 23:06:08 +01:00
commit 77037e7e84
74 changed files with 33573 additions and 0 deletions
+254
View File
@@ -0,0 +1,254 @@
<div class="container">
<h2>Edit Campaign</h2>
<form method="post" action="/<?php echo $_SESSION['role']; ?>/campaign/edit/<?php echo $data['campaign']->id; ?>" class="needs-validation" novalidate>
<div class="form-group">
<label for="name">Campaign Name</label>
<input type="text" class="form-control" id="name" name="name"
value="<?php echo htmlspecialchars($data['campaign']->name); ?>" required>
</div>
<div class="form-group">
<label for="file_id">Google Sheet</label>
<div class="card">
<div class="card-body text-center p-4">
<div class="mb-3">
<input type="text" name="file_id" id="file_id" class="form-control bg-white text-center"
value="<?php echo $data['campaign']->file_id; ?>" placeholder="No file selected" readonly required>
</div>
<button type="button" class="btn btn-primary" onclick="openDrivePicker()">
<i class="fas fa-file-excel mr-2"></i>Select Google Sheet
</button>
</div>
</div>
</div>
<button type="submit" class="btn btn-primary">Update Campaign</button>
<a href="/<?php echo $_SESSION['role']; ?>/campaign" class="btn btn-secondary">Cancel</a>
</form>
</div>
<style>
/* Copy all styles from campaignAdd.php */
.drive-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
gap: 1rem;
padding: 1rem;
}
.drive-item {
display: flex;
flex-direction: column;
align-items: center;
padding: 1rem;
border: 1px solid #dee2e6;
border-radius: 0.25rem;
cursor: pointer;
transition: background-color 0.2s;
text-align: center;
}
.drive-item:hover {
background-color: #f8f9fa;
}
.drive-item svg {
width: 48px;
height: 48px;
margin-bottom: 0.5rem;
}
.drive-item-name {
font-size: 0.9rem;
word-break: break-word;
max-width: 100%;
}
.drive-breadcrumb {
padding: 0.5rem 1rem;
background-color: #f8f9fa;
border-bottom: 1px solid #dee2e6;
}
.drive-breadcrumb a {
color: #007bff;
text-decoration: none;
}
.drive-breadcrumb a:hover {
text-decoration: underline;
}
.modal-body-scroll {
max-height: 60vh;
overflow-y: auto;
}
.drive-loader {
display: flex;
justify-content: center;
align-items: center;
min-height: 200px;
}
.drive-loader-spinner {
width: 50px;
height: 50px;
border: 5px solid #f3f3f3;
border-top: 5px solid #3498db;
border-radius: 50%;
animation: spin 1s linear infinite;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
.drive-grid {
min-height: 300px;
}
.drive-content {
transition: opacity 0.2s;
}
.drive-content.loading {
opacity: 0.5;
pointer-events: none;
}
</style>
<script>
// Copy all JavaScript from campaignAdd.php
let currentFolderId = 'root';
let folderPath = [{id: 'root', name: 'My Drive'}];
let currentModal = null;
async function createModal() {
const modal = document.createElement('div');
modal.className = 'modal fade';
modal.innerHTML = `
<div class="modal-dialog modal-xl">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Select Google Sheet</h5>
<button type="button" class="close" data-dismiss="modal">
<span>&times;</span>
</button>
</div>
<div class="drive-breadcrumb">
${renderBreadcrumb()}
</div>
<div class="modal-body p-0 modal-body-scroll">
<div class="drive-content">
<div class="drive-loader">
<div class="drive-loader-spinner"></div>
</div>
</div>
</div>
</div>
</div>
`;
document.body.appendChild(modal);
currentModal = modal;
$(modal).on('hidden.bs.modal', function () {
modal.remove();
currentModal = null;
});
$(modal).modal('show');
return modal;
}
async function updateModalContent(modal, files) {
const content = modal.querySelector('.drive-content');
content.innerHTML = `
<div class="drive-grid">
${files.length === 0 ?
'<div class="text-center p-4 w-100">No files found in this folder</div>' :
files.map(file => `
<div class="drive-item ${file.mimeType === 'application/vnd.google-apps.folder' ? 'folder' : 'sheet'}"
onclick="${file.mimeType === 'application/vnd.google-apps.folder' ?
`openFolder('${file.id}', '${file.name}')` :
`selectFile('${file.id}', '${file.name}')`}">
${file.mimeType === 'application/vnd.google-apps.folder' ?
`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 50 50">
<path d="M 5 4 C 3.3544268 4 2 5.3555411 2 7 L 2 16 L 2 26 L 2 43 C 2 44.644459 3.3544268 46 5 46 L 45 46 C 46.645063 46 48 44.645063 48 43 L 48 26 L 48 16 L 48 11 C 48 9.3549372 46.645063 8 45 8 L 18 8 C 18.08657 8 17.96899 8.000364 17.724609 7.71875 C 17.480227 7.437136 17.179419 6.9699412 16.865234 6.46875 C 16.55105 5.9675588 16.221777 5.4327899 15.806641 4.9628906 C 15.391504 4.4929914 14.818754 4 14 4 L 5 4 z M 5 6 L 14 6 C 13.93925 6 14.06114 6.00701 14.308594 6.2871094 C 14.556051 6.5672101 14.857231 7.0324412 15.169922 7.53125 C 15.482613 8.0300588 15.806429 8.562864 16.212891 9.03125 C 16.619352 9.499636 17.178927 10 18 10 L 45 10 C 45.562937 10 46 10.437063 46 11 L 46 13.1875 C 45.685108 13.07394 45.351843 13 45 13 L 5 13 C 4.6481575 13 4.3148915 13.07394 4 13.1875 L 4 7 C 4 6.4364589 4.4355732 6 5 6 z M 5 15 L 45 15 C 45.56503 15 46 15.43497 46 16 L 46 26 L 46 43 C 46 43.562937 45.562937 44 45 44 L 5 44 C 4.4355732 44 4 43.563541 4 43 L 4 26 L 4 16 C 4 15.43497 4.4349698 15 5 15 z"></path>
</svg>` :
`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48">
<path fill="#43a047" d="M37,45H11c-1.657,0-3-1.343-3-3V6c0-1.657,1.343-3,3-3h19l10,10v29C40,43.657,38.657,45,37,45z"></path>
<path fill="#c8e6c9" d="M40 13L30 13 30 3z"></path>
<path fill="#2e7d32" d="M30 13L40 23 40 13z"></path>
<path fill="#e8f5e9" d="M31,23H17h-2v2v2v2v2v2v2v2h18v-2v-2v-2v-2v-2v-2v-2H31z M17,25h4v2h-4V25z M17,29h4v2h-4V29z M17,33h4v2h-4V33z M31,35h-8v-2h8V35z M31,31h-8v-2h8V31z M31,27h-8v-2h8V27z"></path>
</svg>`
}
<div class="drive-item-name">${file.name}</div>
</div>
`).join('')
}
</div>
`;
modal.querySelector('.drive-breadcrumb').innerHTML = renderBreadcrumb();
}
async function loadFiles(modal) {
const content = modal.querySelector('.drive-content');
content.classList.add('loading');
try {
const response = await fetch(`/drive/files?folderId=${currentFolderId}`);
if (!response.ok) throw new Error('Failed to fetch files');
const data = await response.json();
if (!data.files || !Array.isArray(data.files)) {
throw new Error('Invalid response format');
}
await updateModalContent(modal, data.files);
} catch (error) {
alert('Error loading files: ' + error.message);
currentFolderId = 'root';
folderPath = [{id: 'root', name: 'My Drive'}];
} finally {
content.classList.remove('loading');
}
}
async function openDrivePicker() {
if (!currentModal) {
const modal = await createModal();
await loadFiles(modal);
}
}
async function openFolder(folderId, folderName) {
currentFolderId = folderId;
folderPath.push({id: folderId, name: folderName});
await loadFiles(currentModal);
}
async function navigateToFolder(index) {
currentFolderId = folderPath[index].id;
folderPath = folderPath.slice(0, index + 1);
await loadFiles(currentModal);
}
function selectFile(fileId, fileName) {
document.getElementById('file_id').value = fileId;
if (currentModal) {
$(currentModal).modal('hide');
}
}
function renderBreadcrumb() {
return folderPath.map((folder, index) => `
<a href="#" onclick="event.preventDefault(); navigateToFolder(${index})">${folder.name}</a>
${index < folderPath.length - 1 ? ' / ' : ''}
`).join('');
}
</script>