init
This commit is contained in:
@@ -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>×</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>
|
||||
Reference in New Issue
Block a user