add feat upload pbg task
This commit is contained in:
@@ -1,63 +1,101 @@
|
||||
import { Grid } from "gridjs/dist/gridjs.umd.js";
|
||||
import "gridjs/dist/gridjs.umd.js";
|
||||
import gridjs from "gridjs/dist/gridjs.umd.js";
|
||||
import { Grid, html } from "gridjs/dist/gridjs.umd.js";
|
||||
import GlobalConfig from "../global-config";
|
||||
import { Dropzone } from "dropzone";
|
||||
Dropzone.autoDiscover = false;
|
||||
|
||||
class PbgTasks {
|
||||
constructor() {
|
||||
this.table = null;
|
||||
this.toastMessage = document.getElementById("toast-message");
|
||||
this.toastElement = document.getElementById("toastNotification");
|
||||
}
|
||||
|
||||
init() {
|
||||
this.initTableRequestAssignment();
|
||||
this.handleSendNotification();
|
||||
this.handleUpload();
|
||||
this.handleUploadBuktiBayar();
|
||||
this.handleUploadBeritaAcara();
|
||||
}
|
||||
|
||||
initTableRequestAssignment() {
|
||||
let tableContainer = document.getElementById("table-pbg-tasks");
|
||||
// Ambil token
|
||||
const token = document
|
||||
.querySelector('meta[name="api-token"]')
|
||||
.getAttribute("content");
|
||||
|
||||
// Pastikan kontainer kosong sebelum merender ulang Grid.js
|
||||
tableContainer.innerHTML = "";
|
||||
let canUpdate = tableContainer.getAttribute("data-updater") === "1";
|
||||
new Grid({
|
||||
const config = {
|
||||
columns: [
|
||||
"ID",
|
||||
{ name: "Name", width: "15%" },
|
||||
{ name: "Condition", width: "7%" },
|
||||
{ name: "Name" },
|
||||
{ name: "Condition" },
|
||||
"Registration Number",
|
||||
"Document Number",
|
||||
{ name: "Address", width: "30%" },
|
||||
{ name: "Address" },
|
||||
"Status",
|
||||
"Function Type",
|
||||
"Consultation Type",
|
||||
{ name: "Due Date", width: "10%" },
|
||||
{ name: "Due Date" },
|
||||
{
|
||||
name: "Action",
|
||||
formatter: (cell) => {
|
||||
let tableContainer =
|
||||
document.getElementById("table-pbg-tasks");
|
||||
let canUpdate =
|
||||
tableContainer.getAttribute("data-updater") === "1";
|
||||
|
||||
if (!canUpdate) {
|
||||
return gridjs.html(
|
||||
return html(
|
||||
`<span class="text-muted">No Privilege</span>`
|
||||
);
|
||||
}
|
||||
|
||||
return gridjs.html(`
|
||||
<div class="d-flex justify-content-center align-items-center gap-2">
|
||||
<a href="/pbg-task/${cell}" class="btn btn-yellow btn-sm d-inline-flex align-items-center justify-content-center">
|
||||
Detail
|
||||
</a>
|
||||
<button class="btn btn-sm btn-info upload-btn" data-id="${cell}">
|
||||
Upload Bukti Bayar
|
||||
</button>
|
||||
<button class="btn btn-sm btn-info upload-btn-berita-acara" data-id="${cell}">
|
||||
Buat Berita Acara
|
||||
</button>
|
||||
</div>
|
||||
`);
|
||||
return html(`
|
||||
<div class="d-flex justify-content-center align-items-center gap-2">
|
||||
<a href="/pbg-task/${cell.id}"
|
||||
class="btn btn-yellow btn-sm d-inline-flex align-items-center justify-content-center"
|
||||
style="white-space: nowrap; line-height: 1;">
|
||||
<iconify-icon icon="mingcute:eye-2-fill" width="15" height="15" style="vertical-align: middle;"></iconify-icon>
|
||||
</a>
|
||||
|
||||
${
|
||||
cell.attachment_berita_acara
|
||||
? `
|
||||
<a href="/storage/${cell.attachment_berita_acara.file_path}" target="_blank"
|
||||
class="btn btn-success btn-sm d-inline-flex align-items-center justify-content-center"
|
||||
style="white-space: nowrap; line-height: 1;">
|
||||
<iconify-icon icon="mingcute:download-2-fill" width="15" height="15" style="vertical-align: middle;"></iconify-icon>
|
||||
<span class="ms-1">Berita Acara</span>
|
||||
</a>
|
||||
`
|
||||
: `
|
||||
<button class="btn btn-sm btn-info d-inline-flex align-items-center justify-content-center upload-btn-berita-acara"
|
||||
data-id="${cell.id}"
|
||||
style="white-space: nowrap; line-height: 1;">
|
||||
<iconify-icon icon="mingcute:upload-2-fill" width="15" height="15" style="vertical-align: middle;"></iconify-icon>
|
||||
<span class="ms-1" style="line-height: 1;">Berita Acara</span>
|
||||
</button>
|
||||
`
|
||||
}
|
||||
|
||||
${
|
||||
cell.attachment_bukti_bayar
|
||||
? `
|
||||
<a href="/storage/${cell.attachment_bukti_bayar.file_path}" target="_blank"
|
||||
class="btn btn-success btn-sm d-inline-flex align-items-center justify-content-center"
|
||||
style="white-space: nowrap; line-height: 1;">
|
||||
<iconify-icon icon="mingcute:download-2-fill" width="15" height="15" style="vertical-align: middle;"></iconify-icon>
|
||||
<span class="ms-1">Bukti Bayar</span>
|
||||
</a>
|
||||
`
|
||||
: `
|
||||
<button class="btn btn-sm btn-info d-inline-flex align-items-center justify-content-center upload-btn-bukti-bayar"
|
||||
data-id="${cell.id}"
|
||||
style="white-space: nowrap; line-height: 1;">
|
||||
<iconify-icon icon="mingcute:upload-2-fill" width="15" height="15" style="vertical-align: middle;"></iconify-icon>
|
||||
<span class="ms-1" style="line-height: 1;">Bukti Bayar</span>
|
||||
</button>
|
||||
`
|
||||
}
|
||||
</div>
|
||||
`);
|
||||
},
|
||||
},
|
||||
],
|
||||
@@ -81,9 +119,7 @@ class PbgTasks {
|
||||
url: `${GlobalConfig.apiHost}/api/request-assignments`,
|
||||
credentials: "include",
|
||||
headers: {
|
||||
Authorization: `Bearer ${document
|
||||
.querySelector('meta[name="api-token"]')
|
||||
.getAttribute("content")}`,
|
||||
Authorization: `Bearer ${token}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
then: (data) =>
|
||||
@@ -98,11 +134,20 @@ class PbgTasks {
|
||||
item.function_type,
|
||||
item.consultation_type,
|
||||
item.due_date,
|
||||
item.id,
|
||||
item,
|
||||
]),
|
||||
total: (data) => data.meta.total,
|
||||
},
|
||||
}).render(document.getElementById("table-pbg-tasks"));
|
||||
};
|
||||
|
||||
const tableContainer = document.getElementById("table-pbg-tasks");
|
||||
|
||||
if (this.table) {
|
||||
this.table.updateConfig(config).forceRender();
|
||||
} else {
|
||||
tableContainer.innerHTML = "";
|
||||
this.table = new Grid(config).render(tableContainer);
|
||||
}
|
||||
}
|
||||
|
||||
handleSendNotification() {
|
||||
@@ -128,71 +173,320 @@ class PbgTasks {
|
||||
});
|
||||
}
|
||||
|
||||
handleUpload() {
|
||||
// Handle button click to show modal
|
||||
document.addEventListener("click", function (event) {
|
||||
if (event.target.classList.contains("upload-btn")) {
|
||||
// Show modal
|
||||
let uploadModal = new bootstrap.Modal(
|
||||
document.getElementById("uploadModal")
|
||||
);
|
||||
uploadModal.show();
|
||||
handleUploadBuktiBayar() {
|
||||
const modalEl = document.getElementById("modalBuktiBayar");
|
||||
const modalInstance = new bootstrap.Modal(modalEl);
|
||||
const modalTaskIdSpan = modalEl.querySelector("#modal-task-id span");
|
||||
|
||||
modalEl.addEventListener("hide.bs.modal", () => {
|
||||
if (
|
||||
document.activeElement &&
|
||||
modalEl.contains(document.activeElement)
|
||||
) {
|
||||
document.activeElement.blur();
|
||||
setTimeout(() => {
|
||||
document.body.focus();
|
||||
}, 10);
|
||||
}
|
||||
});
|
||||
let dropzone = new Dropzone("#singleFileDropzone", {
|
||||
url: "/upload-bukti-bayar", // Adjust to your backend endpoint
|
||||
maxFiles: 1, // Allow only 1 file
|
||||
maxFilesize: 5, // Limit size to 5MB
|
||||
acceptedFiles: ".jpg,.png,.pdf", // Allowed file types
|
||||
autoProcessQueue: false, // Prevent automatic upload
|
||||
addRemoveLinks: true, // Show remove button
|
||||
dictDefaultMessage: "Drop your file here or click to upload.",
|
||||
init: function () {
|
||||
let dz = this;
|
||||
|
||||
// Remove previous file when a new file is added
|
||||
dz.on("addedfile", function () {
|
||||
if (dz.files.length > 1) {
|
||||
dz.removeFile(dz.files[0]);
|
||||
}
|
||||
});
|
||||
// Only bind once
|
||||
if (!window.uploadHandlerBoundBuktiBayar) {
|
||||
document.addEventListener("click", (event) => {
|
||||
const uploadBtn = event.target.closest(
|
||||
".upload-btn-bukti-bayar"
|
||||
);
|
||||
|
||||
// Handle upload button click
|
||||
document
|
||||
.getElementById("uploadBtn")
|
||||
.addEventListener("click", function () {
|
||||
if (dz.getQueuedFiles().length > 0) {
|
||||
dz.processQueue(); // Manually process upload
|
||||
} else {
|
||||
alert("Please select a file to upload.");
|
||||
if (uploadBtn) {
|
||||
const taskId = uploadBtn.getAttribute("data-id");
|
||||
modalTaskIdSpan.textContent = taskId;
|
||||
|
||||
// Set task ID on the form element so Dropzone can read it
|
||||
document.getElementById(
|
||||
"dropzoneBuktiBayar"
|
||||
).dataset.taskId = taskId;
|
||||
|
||||
modalInstance.show();
|
||||
}
|
||||
});
|
||||
|
||||
window.uploadHandlerBoundBuktiBayar = true;
|
||||
}
|
||||
|
||||
// Prevent multiple Dropzone instances
|
||||
if (
|
||||
!Dropzone.instances.some(
|
||||
(dz) => dz.element.id === "dropzoneBuktiBayar"
|
||||
)
|
||||
) {
|
||||
const self = this;
|
||||
new Dropzone("#dropzoneBuktiBayar", {
|
||||
url: function () {
|
||||
const taskId =
|
||||
document.getElementById("dropzoneBuktiBayar").dataset
|
||||
.taskId;
|
||||
return `/api/pbg-task-attachment/${taskId}`;
|
||||
},
|
||||
maxFiles: 1,
|
||||
maxFilesize: 5,
|
||||
acceptedFiles: ".jpg,.png,.pdf",
|
||||
autoProcessQueue: false,
|
||||
addRemoveLinks: false,
|
||||
priviewsContainer: null,
|
||||
paramName: "file",
|
||||
headers: {
|
||||
"X-CSRF-TOKEN": document.querySelector(
|
||||
'meta[name="csrf-token"]'
|
||||
).content,
|
||||
Authorization: `Bearer ${document
|
||||
.querySelector('meta[name="api-token"]')
|
||||
.getAttribute("content")}`,
|
||||
Accept: "application/json",
|
||||
},
|
||||
params: {
|
||||
pbg_type: "bukti_bayar",
|
||||
},
|
||||
dictDefaultMessage: "Drop your file here or click to upload.",
|
||||
init: function () {
|
||||
const dz = this;
|
||||
dz.on("addedfile", function (file) {
|
||||
// Always ensure only one file
|
||||
if (dz.files.length > 1) {
|
||||
dz.removeFile(dz.files[0]);
|
||||
}
|
||||
|
||||
// Small delay helps ensure UI updates even with same file
|
||||
setTimeout(() => {
|
||||
document.getElementById(
|
||||
"uploadedFileNameBuktiBayar"
|
||||
).textContent = file.name;
|
||||
document
|
||||
.getElementById("fileInfoBuktiBayar")
|
||||
.classList.remove("d-none");
|
||||
document
|
||||
.querySelector(".dz-message")
|
||||
.classList.add("d-none");
|
||||
}, 10);
|
||||
});
|
||||
|
||||
// Success callback
|
||||
dz.on("success", function (file, response) {
|
||||
alert("File uploaded successfully!");
|
||||
dz.removeAllFiles(); // Clear after upload
|
||||
});
|
||||
dz.on("removedfile", function () {
|
||||
document
|
||||
.getElementById("fileInfoBuktiBayar")
|
||||
.classList.add("d-none");
|
||||
document.getElementById(
|
||||
"uploadedFileNameBuktiBayar"
|
||||
).textContent = "";
|
||||
document
|
||||
.querySelector(".dz-message")
|
||||
.classList.remove("d-none");
|
||||
});
|
||||
|
||||
// Error callback
|
||||
dz.on("error", function (file, errorMessage) {
|
||||
alert("Upload failed: " + errorMessage);
|
||||
});
|
||||
},
|
||||
});
|
||||
document
|
||||
.getElementById("removeFileBtnBuktiBayar")
|
||||
.addEventListener("click", function () {
|
||||
dz.removeAllFiles();
|
||||
});
|
||||
|
||||
document
|
||||
.getElementById("submitBuktiBayar")
|
||||
.addEventListener("click", () => {
|
||||
if (dz.getQueuedFiles().length > 0) {
|
||||
dz.processQueue();
|
||||
} else {
|
||||
self.toastMessage.innerText =
|
||||
"Please select a file to upload.";
|
||||
self.toast.show();
|
||||
}
|
||||
});
|
||||
|
||||
dz.on("success", () => {
|
||||
dz.removeAllFiles(true);
|
||||
// Reset UI
|
||||
document
|
||||
.getElementById("fileInfoBuktiBayar")
|
||||
.classList.add("d-none");
|
||||
document.getElementById(
|
||||
"uploadedFileNameBuktiBayar"
|
||||
).textContent = "";
|
||||
document.querySelector(".dz-message").style.display =
|
||||
"block";
|
||||
document.activeElement.blur(); // Lepas fokus dari tombol
|
||||
setTimeout(() => {
|
||||
document.body.focus(); // Atau fokus ke tombol lain kalau mau
|
||||
modalInstance.hide(); // Tutup modal SETELAH fokus dipindah
|
||||
}, 50); // Delay singkat biar aman
|
||||
self.toastMessage.innerText =
|
||||
"File uploaded successfully!";
|
||||
self.toast.show();
|
||||
self.initTableRequestAssignment();
|
||||
});
|
||||
|
||||
dz.on("error", (file, message) => {
|
||||
self.toastMessage.innerText =
|
||||
message || "Upload failed!";
|
||||
self.toast.show();
|
||||
});
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
handleUploadBeritaAcara() {
|
||||
// Handle button click to show modal
|
||||
document.addEventListener("click", function (event) {
|
||||
if (event.target.classList.contains("upload-btn-berita-acara")) {
|
||||
// Show modal
|
||||
let uploadModal = new bootstrap.Modal(
|
||||
document.getElementById("uploadBeritaAcara")
|
||||
);
|
||||
uploadModal.show();
|
||||
const modalEl = document.getElementById("modalBeritaAcara");
|
||||
const modalInstance = new bootstrap.Modal(modalEl);
|
||||
const modalTaskIdSpan = modalEl.querySelector("#modal-task-id span");
|
||||
|
||||
modalEl.addEventListener("hide.bs.modal", () => {
|
||||
if (
|
||||
document.activeElement &&
|
||||
modalEl.contains(document.activeElement)
|
||||
) {
|
||||
document.activeElement.blur();
|
||||
setTimeout(() => {
|
||||
document.body.focus();
|
||||
}, 10);
|
||||
}
|
||||
});
|
||||
|
||||
// Only bind once
|
||||
if (!window.uploadHandlerBoundBeritaAcara) {
|
||||
document.addEventListener("click", (event) => {
|
||||
const uploadBtn = event.target.closest(
|
||||
".upload-btn-berita-acara"
|
||||
);
|
||||
|
||||
if (uploadBtn) {
|
||||
const taskId = uploadBtn.getAttribute("data-id");
|
||||
modalTaskIdSpan.textContent = taskId;
|
||||
|
||||
// Set task ID on the form element so Dropzone can read it
|
||||
document.getElementById(
|
||||
"dropzoneBeritaAcara"
|
||||
).dataset.taskId = taskId;
|
||||
|
||||
modalInstance.show();
|
||||
}
|
||||
});
|
||||
|
||||
window.uploadHandlerBoundBeritaAcara = true;
|
||||
}
|
||||
|
||||
// Prevent multiple Dropzone instances
|
||||
if (
|
||||
!Dropzone.instances.some(
|
||||
(dz) => dz.element.id === "dropzoneBeritaAcara"
|
||||
)
|
||||
) {
|
||||
const self = this;
|
||||
new Dropzone("#dropzoneBeritaAcara", {
|
||||
url: function () {
|
||||
const taskId = document.getElementById(
|
||||
"dropzoneBeritaAcara"
|
||||
).dataset.taskId;
|
||||
return `/api/pbg-task-attachment/${taskId}`;
|
||||
},
|
||||
maxFiles: 1,
|
||||
maxFilesize: 5,
|
||||
acceptedFiles: ".jpg,.png,.pdf",
|
||||
autoProcessQueue: false,
|
||||
addRemoveLinks: false,
|
||||
priviewsContainer: null,
|
||||
paramName: "file",
|
||||
headers: {
|
||||
"X-CSRF-TOKEN": document.querySelector(
|
||||
'meta[name="csrf-token"]'
|
||||
).content,
|
||||
Authorization: `Bearer ${document
|
||||
.querySelector('meta[name="api-token"]')
|
||||
.getAttribute("content")}`,
|
||||
Accept: "application/json",
|
||||
},
|
||||
params: {
|
||||
pbg_type: "berita_acara",
|
||||
},
|
||||
dictDefaultMessage: "Drop your file here or click to upload.",
|
||||
init: function () {
|
||||
const dz = this;
|
||||
dz.on("addedfile", function (file) {
|
||||
// Always ensure only one file
|
||||
if (dz.files.length > 1) {
|
||||
dz.removeFile(dz.files[0]);
|
||||
}
|
||||
|
||||
// Small delay helps ensure UI updates even with same file
|
||||
setTimeout(() => {
|
||||
document.getElementById(
|
||||
"uploadedFileNameBeritaAcara"
|
||||
).textContent = file.name;
|
||||
document
|
||||
.getElementById("fileInfoBeritaAcara")
|
||||
.classList.remove("d-none");
|
||||
document
|
||||
.querySelector(".dz-message")
|
||||
.classList.add("d-none");
|
||||
}, 10);
|
||||
});
|
||||
|
||||
dz.on("removedfile", function () {
|
||||
document
|
||||
.getElementById("fileInfoBeritaAcara")
|
||||
.classList.add("d-none");
|
||||
document.getElementById(
|
||||
"uploadedFileNameBeritaAcara"
|
||||
).textContent = "";
|
||||
document
|
||||
.querySelector(".dz-message")
|
||||
.classList.remove("d-none");
|
||||
});
|
||||
|
||||
document
|
||||
.getElementById("removeFileBtnBeritaAcara")
|
||||
.addEventListener("click", function () {
|
||||
dz.removeAllFiles();
|
||||
});
|
||||
|
||||
document
|
||||
.getElementById("submitBeritaAcara")
|
||||
.addEventListener("click", () => {
|
||||
if (dz.getQueuedFiles().length > 0) {
|
||||
dz.processQueue();
|
||||
} else {
|
||||
self.toastMessage.innerText =
|
||||
"Please select a file to upload.";
|
||||
self.toast.show();
|
||||
}
|
||||
});
|
||||
|
||||
dz.on("success", () => {
|
||||
dz.removeAllFiles(true);
|
||||
// Reset UI
|
||||
document
|
||||
.getElementById("fileInfoBeritaAcara")
|
||||
.classList.add("d-none");
|
||||
document.getElementById(
|
||||
"uploadedFileNameBeritaAcara"
|
||||
).textContent = "";
|
||||
document.querySelector(".dz-message").style.display =
|
||||
"block";
|
||||
document.activeElement.blur(); // Lepas fokus dari tombol
|
||||
setTimeout(() => {
|
||||
document.body.focus(); // Atau fokus ke tombol lain kalau mau
|
||||
modalInstance.hide(); // Tutup modal SETELAH fokus dipindah
|
||||
}, 50); // Delay singkat biar aman
|
||||
self.toastMessage.innerText =
|
||||
"File uploaded successfully!";
|
||||
self.toast.show();
|
||||
self.initTableRequestAssignment();
|
||||
});
|
||||
|
||||
dz.on("error", (file, message) => {
|
||||
self.toastMessage.innerText =
|
||||
message || "Upload failed!";
|
||||
self.toast.show();
|
||||
});
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,26 @@
|
||||
|
||||
@section('css')
|
||||
@vite(['node_modules/gridjs/dist/theme/mermaid.min.css'])
|
||||
<style>
|
||||
#dropzoneBuktiBayar .dz-preview{
|
||||
display: none;
|
||||
}
|
||||
#dropzoneBeritaAcara .dz-preview{
|
||||
display: none;
|
||||
}
|
||||
.file-info-overlay {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
z-index: 10;
|
||||
background: rgba(255, 255, 255, 0.9);
|
||||
padding: 0.75rem 1rem;
|
||||
border-radius: 0.5rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
</style>
|
||||
@endsection
|
||||
|
||||
@section('content')
|
||||
@@ -71,7 +91,7 @@
|
||||
</div>
|
||||
|
||||
<!-- Modal -->
|
||||
<div class="modal fade" id="uploadModal" tabindex="-1" aria-hidden="true">
|
||||
<div class="modal fade" id="modalBuktiBayar" tabindex="-1" aria-hidden="true">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
@@ -79,21 +99,27 @@
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p id="modal-task-id">Task ID: <span></span></p>
|
||||
<div class="mb-3">
|
||||
<form action="/upload-bukti-bayar" method="POST" class="dropzone" id="singleFileDropzone">
|
||||
<div class="dz-message needsclick">
|
||||
<i class="h1 bx bx-cloud-upload"></i>
|
||||
<h3>Drop file here or click to upload.</h3>
|
||||
<span class="text-muted fs-13">
|
||||
(Only one file allowed. Selected file will be uploaded upon clicking submit.)
|
||||
</span>
|
||||
</div>
|
||||
<form action="/upload-bukti-bayar" method="POST" class="dropzone" id="dropzoneBuktiBayar">
|
||||
<div class="dz-message needsclick">
|
||||
<i class="h1 bx bx-cloud-upload"></i>
|
||||
<h3>Drop file here or click to upload.</h3>
|
||||
<span class="text-muted fs-13">
|
||||
(Only one file allowed. Selected file will be uploaded upon clicking submit.)
|
||||
</span>
|
||||
</div>
|
||||
<!-- File info inside dropzone -->
|
||||
<div id="fileInfoBuktiBayar" class="file-info-overlay d-none">
|
||||
<span id="uploadedFileNameBuktiBayar" class="text-muted me-3"></span>
|
||||
<button type="button" id="removeFileBtnBuktiBayar" class="btn btn-sm btn-danger">Hapus</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<!-- Submit Button -->
|
||||
<div class="d-flex justify-content-end">
|
||||
<button type="button" id="uploadBtn" class="btn btn-success">
|
||||
<button type="button" id="submitBuktiBayar" class="btn btn-success">
|
||||
<i class="bx bx-upload"></i> Upload
|
||||
</button>
|
||||
</div>
|
||||
@@ -103,31 +129,37 @@
|
||||
</div>
|
||||
|
||||
<!-- Modal -->
|
||||
<div class="modal fade" id="uploadBeritaAcara" tabindex="-1" aria-hidden="true">
|
||||
<div class="modal fade" id="modalBeritaAcara" tabindex="-1" aria-hidden="true">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title">Upload Berita Acara</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
||||
<h5 class="modal-title">Upload Berita Acara</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p id="modal-task-id">Task ID: <span></span></p>
|
||||
<div class="mb-3">
|
||||
<form action="/upload-berita-acara" method="POST" class="dropzone" id="singleFileDropzone">
|
||||
<div class="dz-message needsclick">
|
||||
<i class="h1 bx bx-cloud-upload"></i>
|
||||
<h3>Drop file here or click to upload.</h3>
|
||||
<span class="text-muted fs-13">
|
||||
(Only one file allowed. Selected file will be uploaded upon clicking submit.)
|
||||
</span>
|
||||
</div>
|
||||
</form>
|
||||
<form action="/upload-berita-acara" method="POST" class="dropzone" id="dropzoneBeritaAcara">
|
||||
<div class="dz-message needsclick">
|
||||
<i class="h1 bx bx-cloud-upload"></i>
|
||||
<h3>Drop file here or click to upload.</h3>
|
||||
<span class="text-muted fs-13">
|
||||
(Only one file allowed. Selected file will be uploaded upon clicking submit.)
|
||||
</span>
|
||||
</div>
|
||||
<!-- File info inside dropzone -->
|
||||
<div id="fileInfoBeritaAcara" class="file-info-overlay d-none">
|
||||
<span id="uploadedFileNameBeritaAcara" class="text-muted me-3"></span>
|
||||
<button type="button" id="removeFileBtnBeritaAcara" class="btn btn-sm btn-danger">Hapus</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<!-- Submit Button -->
|
||||
<div class="d-flex justify-content-end">
|
||||
<button type="button" id="uploadBeritaAcara" class="btn btn-success">
|
||||
<i class="bx bx-upload"></i> Upload
|
||||
</button>
|
||||
<button type="button" id="submitBeritaAcara" class="btn btn-success">
|
||||
<i class="bx bx-upload"></i> Upload
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user