2025-03-24 11:14:13 +00:00
|
|
|
<div class="block">
|
2025-05-10 08:50:41 +01:00
|
|
|
<input type="hidden" id="csrf-token-clipboard" value="{{ \CSRFHelper::token() }}">
|
|
|
|
|
<style>
|
|
|
|
|
#upload-area {
|
|
|
|
|
height: 250px;
|
|
|
|
|
border: 2px dashed #aaa;
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
margin-top: 10px;
|
|
|
|
|
color: #555;
|
|
|
|
|
font-family: sans-serif;
|
|
|
|
|
text-align: center;
|
|
|
|
|
}
|
2025-03-24 11:14:13 +00:00
|
|
|
|
2025-05-10 08:50:41 +01:00
|
|
|
#upload-area.hover {
|
|
|
|
|
background-color: #f0f0f0;
|
|
|
|
|
border-color: #444;
|
|
|
|
|
}
|
2025-03-24 11:14:13 +00:00
|
|
|
|
2025-05-10 08:50:41 +01:00
|
|
|
#preview {
|
|
|
|
|
max-width: 100%;
|
|
|
|
|
margin-top: 10px;
|
|
|
|
|
}
|
|
|
|
|
</style>
|
2025-03-24 11:14:13 +00:00
|
|
|
|
2025-05-10 08:50:41 +01:00
|
|
|
<div id="upload-area" contenteditable="true">
|
|
|
|
|
Paste or drag an image here
|
|
|
|
|
</div>
|
|
|
|
|
<img id="preview" alt="image preview" hidden>
|
|
|
|
|
<p id="status"></p>
|
2025-03-24 11:14:13 +00:00
|
|
|
|
2025-05-10 08:50:41 +01:00
|
|
|
<script>
|
|
|
|
|
const area = document.getElementById('upload-area');
|
|
|
|
|
const preview = document.getElementById('preview');
|
|
|
|
|
const status = document.getElementById('status');
|
|
|
|
|
const csrfTokenClipboard = document.getElementById('csrf-token-clipboard').value;
|
2025-03-24 11:14:13 +00:00
|
|
|
|
2025-05-10 08:50:41 +01:00
|
|
|
async function uploadImage(file) {
|
|
|
|
|
const reader = new FileReader();
|
|
|
|
|
reader.onload = () => {
|
|
|
|
|
preview.src = reader.result;
|
|
|
|
|
preview.hidden = false;
|
|
|
|
|
};
|
|
|
|
|
reader.readAsDataURL(file);
|
2025-03-24 11:14:13 +00:00
|
|
|
|
2025-05-10 08:50:41 +01:00
|
|
|
const formData = new FormData();
|
|
|
|
|
formData.append('attachment', file);
|
|
|
|
|
formData.append('csrf_token', csrfTokenClipboard);
|
2025-03-24 11:14:13 +00:00
|
|
|
|
2025-05-10 08:50:41 +01:00
|
|
|
try {
|
|
|
|
|
const res = await fetch('/ticket/{{@ticket->id}}/attachments/upload', {
|
|
|
|
|
method: 'POST',
|
|
|
|
|
body: formData
|
|
|
|
|
});
|
|
|
|
|
if(res.ok){
|
|
|
|
|
const responseData = await res.json(); // assuming json returned
|
|
|
|
|
statusMsg.textContent = responseData || 'Upload success, no message';
|
|
|
|
|
window.location.reload();
|
|
|
|
|
} else {
|
|
|
|
|
const errorData = await res.json();
|
|
|
|
|
statusMsg.textContent = 'Upload failed: ' + (errorData.error || res.statusText);
|
|
|
|
|
}
|
|
|
|
|
} catch (e) {
|
|
|
|
|
status.textContent = 'upload failed.'
|
|
|
|
|
}
|
2025-03-24 11:14:13 +00:00
|
|
|
}
|
|
|
|
|
|
2025-05-10 08:50:41 +01:00
|
|
|
// paste
|
|
|
|
|
area.addEventListener('paste', (e) => {
|
|
|
|
|
for (let item of e.clipboardData.items) {
|
|
|
|
|
if (item.type.startsWith('image/')) {
|
|
|
|
|
uploadImage(item.getAsFile());
|
|
|
|
|
}
|
2025-03-24 11:14:13 +00:00
|
|
|
}
|
2025-05-10 08:50:41 +01:00
|
|
|
});
|
2025-03-24 11:14:13 +00:00
|
|
|
|
2025-05-10 08:50:41 +01:00
|
|
|
// drag and drop
|
|
|
|
|
area.addEventListener('dragover', (e) => {
|
|
|
|
|
e.preventDefault();
|
|
|
|
|
area.classList.add('hover');
|
|
|
|
|
});
|
2025-03-24 11:14:13 +00:00
|
|
|
|
2025-05-10 08:50:41 +01:00
|
|
|
area.addEventListener('dragLeave', () => {
|
|
|
|
|
area.classList.remove('hover');
|
|
|
|
|
});
|
2025-03-24 11:14:13 +00:00
|
|
|
|
2025-05-10 08:50:41 +01:00
|
|
|
area.addEventListener('drop', (e) => {
|
|
|
|
|
e.preventDefault();
|
|
|
|
|
area.classList.remove('hover');
|
|
|
|
|
const files = e.dataTransfer.files;
|
|
|
|
|
for (let file of files) {
|
|
|
|
|
if (file.type.startsWith('image/')) {
|
|
|
|
|
uploadImage(file);
|
|
|
|
|
}
|
2025-03-24 11:14:13 +00:00
|
|
|
}
|
2025-05-10 08:50:41 +01:00
|
|
|
});
|
|
|
|
|
</script>
|
2025-03-24 11:14:13 +00:00
|
|
|
</div>
|