merge feature umkm
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import { Dropzone } from "dropzone";
|
||||
import GlobalConfig from "../../global-config.js";
|
||||
|
||||
Dropzone.autoDiscover = false;
|
||||
|
||||
@@ -14,7 +15,7 @@ console.log(dropzonePreviewNode);
|
||||
((previewTemplate = dropzonePreviewNode.parentNode.innerHTML),
|
||||
dropzonePreviewNode.parentNode.removeChild(dropzonePreviewNode),
|
||||
(dropzone = new Dropzone(".dropzone", {
|
||||
url: "http://localhost:8000/api/advertisements/import",
|
||||
url: `${GlobalConfig.apiHost}/api/advertisements/import`,
|
||||
// url: "https://httpbin.org/post",
|
||||
method: "post",
|
||||
acceptedFiles: ".xls,.xlsx", // Use acceptedFiles for better validation
|
||||
@@ -85,6 +86,40 @@ dropzone.on("complete", function(file) {
|
||||
dropzone.removeFile(file);
|
||||
});
|
||||
|
||||
// Add event listener to donwload file template
|
||||
document.getElementById('downloadtempadvertisement').addEventListener('click', function() {
|
||||
var url = `${GlobalConfig.apiHost}/api/download-template-advertisement`;
|
||||
fetch(url, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
Authorization: `Bearer ${document
|
||||
.querySelector('meta[name="api-token"]')
|
||||
.getAttribute("content")}`
|
||||
},
|
||||
})
|
||||
.then(response => {
|
||||
if (response.ok) {
|
||||
return response.blob();
|
||||
} else {
|
||||
return response.json();
|
||||
}
|
||||
})
|
||||
.then((blob) => {
|
||||
const url = window.URL.createObjectURL(blob);
|
||||
const a = document.createElement('a');
|
||||
a.style.display = 'none';
|
||||
a.href = url;
|
||||
a.download = 'template_reklame.xlsx';
|
||||
document.body.appendChild(a);
|
||||
a.click();
|
||||
window.URL.revokeObjectURL(url);
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error("Gagal mendownload file:", error);
|
||||
showToast('bxs-error-alt', 'red', "Template file is not already exist.");
|
||||
})
|
||||
})
|
||||
|
||||
// Function to show toast
|
||||
function showToast(iconClass, iconColor, message) {
|
||||
const toastElement = document.getElementById('toastUploadAdvertisement');
|
||||
|
||||
79
resources/js/data/tourisms/data-tourisms.js
Normal file
79
resources/js/data/tourisms/data-tourisms.js
Normal file
@@ -0,0 +1,79 @@
|
||||
import { Grid } from "gridjs/dist/gridjs.umd.js";
|
||||
import gridjs from "gridjs/dist/gridjs.umd.js";
|
||||
import "gridjs/dist/gridjs.umd.js";
|
||||
import GlobalConfig from "../../global-config.js";
|
||||
import GeneralTable from "../../table-generator.js";
|
||||
|
||||
|
||||
const dataTourismsColumns = [
|
||||
"Proyek ID",
|
||||
"Jenis Proyek",
|
||||
"NIB",
|
||||
"Nama Perusahaan",
|
||||
"Terbit OSS",
|
||||
"Status Penanaman Modal",
|
||||
"Bentuk Bisnis",
|
||||
"Uraian Resiko Proyek",
|
||||
"Nama Proyek",
|
||||
"Alamat Usaha",
|
||||
"Kecamatan",
|
||||
"Desa",
|
||||
"Luas Tanah",
|
||||
"Jumlah Investasi",
|
||||
"TKI",
|
||||
"Tipe Usaha",
|
||||
{
|
||||
name: "Actions",
|
||||
widht: "120px",
|
||||
formatter: function(cell, row) {
|
||||
const id = row.cells[16].data;
|
||||
const model = "data/tourisms";
|
||||
return gridjs.html(`
|
||||
<div class="d-flex justify-items-end gap-10">
|
||||
<button class="btn btn-warning me-2 btn-edit"
|
||||
data-id="${id}"
|
||||
data-model="${model}">
|
||||
<i class='bx bx-edit' ></i></button>
|
||||
<button class="btn btn-red btn-delete"
|
||||
data-id="${id}">
|
||||
<i class='bx bxs-trash' ></i></button>
|
||||
</div>
|
||||
`);
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
const table = new GeneralTable(
|
||||
"tourisms-data-table",
|
||||
`${GlobalConfig.apiHost}/api/tourisms`,
|
||||
`${GlobalConfig.apiHost}`,
|
||||
dataTourismsColumns
|
||||
);
|
||||
|
||||
table.processData = function (data) {
|
||||
return data.data.map((item) => {
|
||||
return [
|
||||
item.project_id,
|
||||
item.jenis_project,
|
||||
item.nib,
|
||||
item.business_name,
|
||||
item.terbit_oss,
|
||||
item.status_penanaman_modal,
|
||||
item.business_form,
|
||||
item.uraian_resiko_project,
|
||||
item.project_name,
|
||||
item.business_address,
|
||||
item.district_name,
|
||||
item.village_name,
|
||||
item.land_area,
|
||||
item.investment_amount,
|
||||
item.number_of_employee,
|
||||
item.business_type,
|
||||
item.id,
|
||||
];
|
||||
});
|
||||
};
|
||||
|
||||
table.init();
|
||||
})
|
||||
149
resources/js/data/tourisms/form-upload.js
Normal file
149
resources/js/data/tourisms/form-upload.js
Normal file
@@ -0,0 +1,149 @@
|
||||
import { Dropzone } from "dropzone";
|
||||
import GlobalConfig from "../../global-config.js";
|
||||
|
||||
Dropzone.autoDiscover = false;
|
||||
|
||||
var previewTemplate,
|
||||
dropzone,
|
||||
dropzonePreviewNode = document.querySelector("#dropzone-preview-list");
|
||||
console.log(previewTemplate);
|
||||
console.log(dropzone);
|
||||
console.log(dropzonePreviewNode);
|
||||
|
||||
(dropzonePreviewNode.id = ""),
|
||||
dropzonePreviewNode &&
|
||||
((previewTemplate = dropzonePreviewNode.parentNode.innerHTML),
|
||||
dropzonePreviewNode.parentNode.removeChild(dropzonePreviewNode),
|
||||
(dropzone = new Dropzone(".dropzone", {
|
||||
url: `${GlobalConfig.apiHost}/api/tourisms/import`,
|
||||
// url: "https://httpbin.org/post",
|
||||
method: "post",
|
||||
acceptedFiles: ".xls,.xlsx", // Use acceptedFiles for better validation
|
||||
previewTemplate: previewTemplate,
|
||||
previewsContainer: "#dropzone-preview",
|
||||
autoProcessQueue: false, // Disable auto post
|
||||
headers: {
|
||||
Authorization: `Bearer ${document
|
||||
.querySelector('meta[name="api-token"]')
|
||||
.getAttribute("content")}`
|
||||
},
|
||||
init: function() {
|
||||
// Listen for the success event
|
||||
this.on("success", function(file, response) {
|
||||
console.log("File successfully uploaded:", file);
|
||||
console.log("API Response:", response);
|
||||
|
||||
// Show success toast
|
||||
showToast('bxs-check-square', 'green', response.message);
|
||||
document.getElementById("submit-upload").innerHTML = "Upload Files";
|
||||
// Tunggu sebentar lalu reload halaman
|
||||
setTimeout(() => {
|
||||
window.location.href = "/data/tourisms";
|
||||
}, 2000);
|
||||
});
|
||||
// Listen for the error event
|
||||
this.on("error", function(file, errorMessage) {
|
||||
console.error("Error uploading file:", file);
|
||||
console.error("Error message:", errorMessage);
|
||||
// Handle the error response
|
||||
|
||||
// Show error toast
|
||||
showToast('bxs-error-alt', 'red', errorMessage.message);
|
||||
document.getElementById("submit-upload").innerHTML = "Upload Files";
|
||||
});
|
||||
}
|
||||
})));
|
||||
|
||||
// Add event listener to control the submission manually
|
||||
document.querySelector("#submit-upload").addEventListener("click", function() {
|
||||
console.log("Ini adalah value dropzone", dropzone.files[0]);
|
||||
const formData = new FormData()
|
||||
console.log("Dropzonefiles",dropzone.files);
|
||||
|
||||
this.innerHTML = '<span class="spinner-border spinner-border-sm me-1" role="status" aria-hidden="true"></span>Loading...';
|
||||
|
||||
// Pastikan ada file dalam queue sebelum memprosesnya
|
||||
if (dropzone.files.length > 0) {
|
||||
formData.append('file', dropzone.files[0])
|
||||
console.log("ini adalah form data on submit", ...formData);
|
||||
dropzone.processQueue(); // Ini akan manual memicu upload
|
||||
} else {
|
||||
// Show error toast when no file is selected
|
||||
showToast('bxs-error-alt', 'red', "Please add a file first.");
|
||||
document.getElementById("submit-upload").innerHTML = "Upload Files";
|
||||
}
|
||||
});
|
||||
|
||||
// Optional: Listen for the 'addedfile' event to log or control file add behavior
|
||||
dropzone.on("addedfile", function (file) {
|
||||
console.log("File ditambahkan:", file);
|
||||
console.log("Nama File:", file.name);
|
||||
console.log("Tipe File:", file.type);
|
||||
console.log("Ukuran File:", (file.size / 1024).toFixed(2) + " KB");
|
||||
});
|
||||
|
||||
dropzone.on("complete", function(file) {
|
||||
dropzone.removeFile(file);
|
||||
});
|
||||
|
||||
// Add event listener to download file template
|
||||
document.getElementById('downloadtemptourisms').addEventListener('click', function() {
|
||||
var url = `${GlobalConfig.apiHost}/api/download-template-umkm`;
|
||||
fetch(url, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
Authorization: `Bearer ${document
|
||||
.querySelector('meta[name="api-token"]')
|
||||
.getAttribute("content")}`
|
||||
},
|
||||
})
|
||||
.then(response => {
|
||||
if (response.ok) {
|
||||
return response.blob(); // Jika respons OK, konversi menjadi blob
|
||||
} else {
|
||||
return response.json(); // Jika respons gagal, konversi menjadi JSON untuk menangani pesan error
|
||||
}
|
||||
})
|
||||
.then((blob) => {
|
||||
const url = window.URL.createObjectURL(blob);
|
||||
const a = document.createElement('a');
|
||||
a.style.display = 'none';
|
||||
a.href = url;
|
||||
a.download = 'template_tourisms.xlsx';
|
||||
document.body.appendChild(a);
|
||||
a.click();
|
||||
window.URL.revokeObjectURL(url);
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error("Gagal mendownload file:", error);
|
||||
showToast('bxs-error-alt', 'red', "Template file is not already exist.");
|
||||
})
|
||||
})
|
||||
|
||||
// Function to show toast
|
||||
function showToast(iconClass, iconColor, message) {
|
||||
const toastElement = document.getElementById('toastUploadUmkm');
|
||||
const toastBody = toastElement.querySelector('.toast-body');
|
||||
const toastHeader = toastElement.querySelector('.toast-header');
|
||||
|
||||
// Remove existing icon (if any) before adding the new one
|
||||
const existingIcon = toastHeader.querySelector('.bx');
|
||||
if (existingIcon) {
|
||||
toastHeader.querySelector('.auth-logo').removeChild(existingIcon); // Remove the existing icon
|
||||
}
|
||||
|
||||
// Add the new icon to the toast header
|
||||
const icon = document.createElement('i');
|
||||
icon.classList.add('bx', iconClass);
|
||||
icon.style.fontSize = '25px';
|
||||
icon.style.color = iconColor;
|
||||
toastHeader.querySelector('.auth-logo').appendChild(icon);
|
||||
|
||||
// Set the toast message
|
||||
toastBody.textContent = message;
|
||||
|
||||
// Show the toast
|
||||
const toast = new bootstrap.Toast(toastElement); // Inisialisasi Bootstrap Toast
|
||||
toast.show();
|
||||
}
|
||||
|
||||
81
resources/js/data/umkm/data-umkm.js
Normal file
81
resources/js/data/umkm/data-umkm.js
Normal file
@@ -0,0 +1,81 @@
|
||||
import gridjs from "gridjs/dist/gridjs.umd.js";
|
||||
import "gridjs/dist/gridjs.umd.js";
|
||||
import GlobalConfig from "../../global-config.js";
|
||||
import GeneralTable from "../../table-generator.js";
|
||||
|
||||
const dataUMKMColumns = [
|
||||
"Nama Usaha",
|
||||
"Alamat Usaha",
|
||||
"Deskripsi Usaha",
|
||||
"Kontak Usaha",
|
||||
"NIB",
|
||||
"Skala Usaha",
|
||||
"NIK",
|
||||
"Nama Pemilik",
|
||||
"Alamat Pemilik",
|
||||
"Kontak Pemilik",
|
||||
"Jenis Usaha",
|
||||
"Bentuk Usaha",
|
||||
"Revenue",
|
||||
"Desa",
|
||||
"Kecamatan",
|
||||
"Jumlah Karyawan",
|
||||
"Luas Tanah",
|
||||
"Ijin Status",
|
||||
{
|
||||
name: "Actions",
|
||||
widht: "120px",
|
||||
formatter: function(cell, row) {
|
||||
const id = row.cells[18].data;
|
||||
const model = "data/umkm";
|
||||
return gridjs.html(`
|
||||
<div class="d-flex justify-items-end gap-10">
|
||||
<button class="btn btn-warning me-2 btn-edit"
|
||||
data-id="${id}"
|
||||
data-model="${model}">
|
||||
<i class='bx bx-edit' ></i></button>
|
||||
<button class="btn btn-red btn-delete"
|
||||
data-id="${id}">
|
||||
<i class='bx bxs-trash' ></i></button>
|
||||
</div>
|
||||
`);
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
const table = new GeneralTable(
|
||||
"umkm-data-table",
|
||||
`${GlobalConfig.apiHost}/api/umkm`,
|
||||
`${GlobalConfig.apiHost}`,
|
||||
dataUMKMColumns
|
||||
);
|
||||
|
||||
table.processData = function (data) {
|
||||
return data.data.map((item) => {
|
||||
return [
|
||||
item.business_name,
|
||||
item.business_address,
|
||||
item.business_desc,
|
||||
item.business_contact,
|
||||
item.business_id_number,
|
||||
item.business_scale,
|
||||
item.owner_id,
|
||||
item.owner_name,
|
||||
item.owner_address,
|
||||
item.owner_contact,
|
||||
item.business_type,
|
||||
item.business_form,
|
||||
item.revenue,
|
||||
item.village_name,
|
||||
item.district_name,
|
||||
item.number_of_employee,
|
||||
item.land_area,
|
||||
item.permit_status,
|
||||
item.id,
|
||||
];
|
||||
});
|
||||
};
|
||||
|
||||
table.init();
|
||||
});
|
||||
185
resources/js/data/umkm/form-create-update.js
Normal file
185
resources/js/data/umkm/form-create-update.js
Normal file
@@ -0,0 +1,185 @@
|
||||
import GlobalConfig from "../../global-config";
|
||||
|
||||
document.addEventListener("DOMContentLoaded", function () {
|
||||
const saveButton = document.querySelector(".modal-footer .btn-primary");
|
||||
const modalButton = document.querySelector(".btn-modal");
|
||||
const form = document.querySelector("form#create-update-form");
|
||||
var authLogo = document.querySelector(".auth-logo");
|
||||
|
||||
if (!saveButton || !form) return;
|
||||
|
||||
saveButton.addEventListener("click", function () {
|
||||
// Disable tombol dan tampilkan spinner
|
||||
modalButton.disabled = true;
|
||||
modalButton.innerHTML = `
|
||||
<span class="spinner-border spinner-border-sm me-1" role="status" aria-hidden="true"></span>
|
||||
Loading...
|
||||
`;
|
||||
const isEdit = saveButton.classList.contains("btn-edit");
|
||||
const formData = new FormData(form)
|
||||
const toast = document.getElementById('toastEditUpdate');
|
||||
const toastBody = toast.querySelector('.toast-body');
|
||||
const toastHeader = toast.querySelector('.toast-header small');
|
||||
|
||||
const data = {};
|
||||
|
||||
// Mengonversi FormData ke dalam JSON
|
||||
formData.forEach((value, key) => {
|
||||
data[key] = value;
|
||||
});
|
||||
|
||||
// Log semua data dalam FormData
|
||||
for (let pair of formData.entries()) {
|
||||
console.log(pair[0] + ": " + pair[1]);
|
||||
}
|
||||
const url = form.getAttribute("action");
|
||||
console.log("Ini adalah url dari form action", url);
|
||||
|
||||
const method = isEdit ? "PUT" : "POST";
|
||||
|
||||
fetch(url, {
|
||||
method: method,
|
||||
body: JSON.stringify(data),
|
||||
headers: {
|
||||
Authorization: `Bearer ${document
|
||||
.querySelector('meta[name="api-token"]')
|
||||
.getAttribute("content")}`,
|
||||
"Content-Type": "application/json",
|
||||
}
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
console.log("Response data:", data);
|
||||
if (!data.errors) {
|
||||
// Remove existing icon (if any) before adding the new one
|
||||
if (authLogo) {
|
||||
// Hapus ikon yang sudah ada jika ada
|
||||
const existingIcon = authLogo.querySelector('.bx');
|
||||
if (existingIcon) {
|
||||
authLogo.removeChild(existingIcon);
|
||||
}
|
||||
|
||||
// Buat ikon baru
|
||||
const icon = document.createElement('i');
|
||||
icon.classList.add('bx', 'bxs-check-square');
|
||||
icon.style.fontSize = '25px';
|
||||
icon.style.color = 'green'; // Pastikan 'green' dalam bentuk string
|
||||
|
||||
// Tambahkan ikon ke dalam auth-logo
|
||||
authLogo.appendChild(icon);
|
||||
}
|
||||
|
||||
// Set success message for the toast
|
||||
toastBody.textContent = isEdit ? "Data updated successfully!" : "Data created successfully!";
|
||||
toast.classList.add('show'); // Show the toast
|
||||
setTimeout(() => {
|
||||
toast.classList.remove('show'); // Hide the toast after 3 seconds
|
||||
}, 3000);
|
||||
|
||||
setTimeout(() => {
|
||||
window.location.href = '/data/umkm';
|
||||
}, 3000);
|
||||
} else {
|
||||
if (authLogo) {
|
||||
// Hapus ikon yang sudah ada jika ada
|
||||
const existingIcon = authLogo.querySelector('.bx');
|
||||
if (existingIcon) {
|
||||
authLogo.removeChild(existingIcon);
|
||||
}
|
||||
|
||||
// Buat ikon baru
|
||||
const icon = document.createElement('i');
|
||||
icon.classList.add('bx', 'bxs-error-alt');
|
||||
icon.style.fontSize = '25px';
|
||||
icon.style.color = 'red'; // Pastikan 'green' dalam bentuk string
|
||||
|
||||
// Tambahkan ikon ke dalam auth-logo
|
||||
authLogo.appendChild(icon);
|
||||
}
|
||||
// Set error message for the toast
|
||||
toastBody.textContent = "Error: " + (data.message || "Something went wrong");
|
||||
toast.classList.add('show'); // Show the toast
|
||||
|
||||
// Enable button and reset its text on error
|
||||
modalButton.disabled = false;
|
||||
modalButton.innerHTML = isEdit ? "Update" : "Create";
|
||||
|
||||
setTimeout(() => {
|
||||
toast.classList.remove('show'); // Hide the toast after 3 seconds
|
||||
}, 3000);
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error("Error:", error);
|
||||
if (authLogo) {
|
||||
// Hapus ikon yang sudah ada jika ada
|
||||
const existingIcon = authLogo.querySelector('.bx');
|
||||
if (existingIcon) {
|
||||
authLogo.removeChild(existingIcon);
|
||||
}
|
||||
|
||||
// Buat ikon baru
|
||||
const icon = document.createElement('i');
|
||||
icon.classList.add('bx', 'bxs-error-alt');
|
||||
icon.style.fontSize = '25px';
|
||||
icon.style.color = 'red'; // Pastikan 'green' dalam bentuk string
|
||||
|
||||
// Tambahkan ikon ke dalam auth-logo
|
||||
authLogo.appendChild(icon);
|
||||
}
|
||||
// Set error message for the toast
|
||||
toastBody.textContent = "An error occurred while processing your request.";
|
||||
toast.classList.add('show'); // Show the toast
|
||||
|
||||
// Enable button and reset its text on error
|
||||
modalButton.disabled = false;
|
||||
modalButton.innerHTML = isEdit ? "Update" : "Create";
|
||||
|
||||
setTimeout(() => {
|
||||
toast.classList.remove('show'); // Hide the toast after 3 seconds
|
||||
}, 3000);
|
||||
});
|
||||
});
|
||||
|
||||
// Fungsi fetchOptions untuk autocomplete server-side
|
||||
window.fetchOptions = function (field) {
|
||||
let inputValue = document.getElementById(field).value;
|
||||
console.log("Query Value:", inputValue); // Debugging log
|
||||
if (inputValue.length < 2) return;
|
||||
let districtValue = document.getElementById("district_name").value; // Ambil kecamatan terpilih
|
||||
|
||||
let url = `${GlobalConfig.apiHost}/api/combobox/search-options?query=${encodeURIComponent(inputValue)}&field=${field}`;
|
||||
|
||||
// Jika field desa, tambahkan kecamatan sebagai filter
|
||||
if (field === "village_name") {
|
||||
url += `&district=${encodeURIComponent(districtValue)}`;
|
||||
}
|
||||
|
||||
fetch(url, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
Authorization: `Bearer ${document
|
||||
.querySelector('meta[name="api-token"]')
|
||||
.getAttribute("content")}`,
|
||||
"Content-Type": "application/json",
|
||||
}
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
let dataList = document.getElementById(field + "Options");
|
||||
dataList.innerHTML = "";
|
||||
|
||||
data.forEach(item => {
|
||||
let option = document.createElement("option");
|
||||
option.value = item.name;
|
||||
option.dataset.code = item.code;
|
||||
dataList.appendChild(option);
|
||||
});
|
||||
})
|
||||
.catch(error => console.error("Error fetching options:", error));
|
||||
};
|
||||
|
||||
document.querySelector('.btn-back').addEventListener('click', function() {
|
||||
window.history.back();
|
||||
});
|
||||
});
|
||||
149
resources/js/data/umkm/form-upload.js
Normal file
149
resources/js/data/umkm/form-upload.js
Normal file
@@ -0,0 +1,149 @@
|
||||
import { Dropzone } from "dropzone";
|
||||
import GlobalConfig from "../../global-config.js";
|
||||
|
||||
Dropzone.autoDiscover = false;
|
||||
|
||||
var previewTemplate,
|
||||
dropzone,
|
||||
dropzonePreviewNode = document.querySelector("#dropzone-preview-list");
|
||||
console.log(previewTemplate);
|
||||
console.log(dropzone);
|
||||
console.log(dropzonePreviewNode);
|
||||
|
||||
(dropzonePreviewNode.id = ""),
|
||||
dropzonePreviewNode &&
|
||||
((previewTemplate = dropzonePreviewNode.parentNode.innerHTML),
|
||||
dropzonePreviewNode.parentNode.removeChild(dropzonePreviewNode),
|
||||
(dropzone = new Dropzone(".dropzone", {
|
||||
url: `${GlobalConfig.apiHost}/api/umkm/import`,
|
||||
// url: "https://httpbin.org/post",
|
||||
method: "post",
|
||||
acceptedFiles: ".xls,.xlsx", // Use acceptedFiles for better validation
|
||||
previewTemplate: previewTemplate,
|
||||
previewsContainer: "#dropzone-preview",
|
||||
autoProcessQueue: false, // Disable auto post
|
||||
headers: {
|
||||
Authorization: `Bearer ${document
|
||||
.querySelector('meta[name="api-token"]')
|
||||
.getAttribute("content")}`
|
||||
},
|
||||
init: function() {
|
||||
// Listen for the success event
|
||||
this.on("success", function(file, response) {
|
||||
console.log("File successfully uploaded:", file);
|
||||
console.log("API Response:", response);
|
||||
|
||||
// Show success toast
|
||||
showToast('bxs-check-square', 'green', response.message);
|
||||
document.getElementById("submit-upload").innerHTML = "Upload Files";
|
||||
// Tunggu sebentar lalu reload halaman
|
||||
setTimeout(() => {
|
||||
window.location.href = "/data/umkm";
|
||||
}, 2000);
|
||||
});
|
||||
// Listen for the error event
|
||||
this.on("error", function(file, errorMessage) {
|
||||
console.error("Error uploading file:", file);
|
||||
console.error("Error message:", errorMessage);
|
||||
// Handle the error response
|
||||
|
||||
// Show error toast
|
||||
showToast('bxs-error-alt', 'red', errorMessage.message);
|
||||
document.getElementById("submit-upload").innerHTML = "Upload Files";
|
||||
});
|
||||
}
|
||||
})));
|
||||
|
||||
// Add event listener to control the submission manually
|
||||
document.querySelector("#submit-upload").addEventListener("click", function() {
|
||||
console.log("Ini adalah value dropzone", dropzone.files[0]);
|
||||
const formData = new FormData()
|
||||
console.log("Dropzonefiles",dropzone.files);
|
||||
|
||||
this.innerHTML = '<span class="spinner-border spinner-border-sm me-1" role="status" aria-hidden="true"></span>Loading...';
|
||||
|
||||
// Pastikan ada file dalam queue sebelum memprosesnya
|
||||
if (dropzone.files.length > 0) {
|
||||
formData.append('file', dropzone.files[0])
|
||||
console.log("ini adalah form data on submit", ...formData);
|
||||
dropzone.processQueue(); // Ini akan manual memicu upload
|
||||
} else {
|
||||
// Show error toast when no file is selected
|
||||
showToast('bxs-error-alt', 'red', "Please add a file first.");
|
||||
document.getElementById("submit-upload").innerHTML = "Upload Files";
|
||||
}
|
||||
});
|
||||
|
||||
// Optional: Listen for the 'addedfile' event to log or control file add behavior
|
||||
dropzone.on("addedfile", function (file) {
|
||||
console.log("File ditambahkan:", file);
|
||||
console.log("Nama File:", file.name);
|
||||
console.log("Tipe File:", file.type);
|
||||
console.log("Ukuran File:", (file.size / 1024).toFixed(2) + " KB");
|
||||
});
|
||||
|
||||
dropzone.on("complete", function(file) {
|
||||
dropzone.removeFile(file);
|
||||
});
|
||||
|
||||
// Add event listener to download file template
|
||||
document.getElementById('downloadtempumkm').addEventListener('click', function() {
|
||||
var url = `${GlobalConfig.apiHost}/api/download-template-umkm`;
|
||||
fetch(url, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
Authorization: `Bearer ${document
|
||||
.querySelector('meta[name="api-token"]')
|
||||
.getAttribute("content")}`
|
||||
},
|
||||
})
|
||||
.then(response => {
|
||||
if (response.ok) {
|
||||
return response.blob(); // Jika respons OK, konversi menjadi blob
|
||||
} else {
|
||||
return response.json(); // Jika respons gagal, konversi menjadi JSON untuk menangani pesan error
|
||||
}
|
||||
})
|
||||
.then((blob) => {
|
||||
const url = window.URL.createObjectURL(blob);
|
||||
const a = document.createElement('a');
|
||||
a.style.display = 'none';
|
||||
a.href = url;
|
||||
a.download = 'template_umkm.xlsx';
|
||||
document.body.appendChild(a);
|
||||
a.click();
|
||||
window.URL.revokeObjectURL(url);
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error("Gagal mendownload file:", error);
|
||||
showToast('bxs-error-alt', 'red', "Template file is not already exist.");
|
||||
})
|
||||
})
|
||||
|
||||
// Function to show toast
|
||||
function showToast(iconClass, iconColor, message) {
|
||||
const toastElement = document.getElementById('toastUploadUmkm');
|
||||
const toastBody = toastElement.querySelector('.toast-body');
|
||||
const toastHeader = toastElement.querySelector('.toast-header');
|
||||
|
||||
// Remove existing icon (if any) before adding the new one
|
||||
const existingIcon = toastHeader.querySelector('.bx');
|
||||
if (existingIcon) {
|
||||
toastHeader.querySelector('.auth-logo').removeChild(existingIcon); // Remove the existing icon
|
||||
}
|
||||
|
||||
// Add the new icon to the toast header
|
||||
const icon = document.createElement('i');
|
||||
icon.classList.add('bx', iconClass);
|
||||
icon.style.fontSize = '25px';
|
||||
icon.style.color = iconColor;
|
||||
toastHeader.querySelector('.auth-logo').appendChild(icon);
|
||||
|
||||
// Set the toast message
|
||||
toastBody.textContent = message;
|
||||
|
||||
// Show the toast
|
||||
const toast = new bootstrap.Toast(toastElement); // Inisialisasi Bootstrap Toast
|
||||
toast.show();
|
||||
}
|
||||
|
||||
16
resources/js/report/tourisms/index.js
Normal file
16
resources/js/report/tourisms/index.js
Normal file
@@ -0,0 +1,16 @@
|
||||
import gridjs from "gridjs/dist/gridjs.umd.js";
|
||||
import "gridjs/dist/gridjs.umd.js";
|
||||
|
||||
// Mengambil data dari input dengan id="business_type_counts"
|
||||
const businessTypeCountsElement = document.getElementById("business_type_counts");
|
||||
console.log(businessTypeCountsElement);
|
||||
const businessTypeCounts = JSON.parse(businessTypeCountsElement.value); // Cek apakah data sudah terbawa dengan benar
|
||||
|
||||
// Membuat Grid.js instance
|
||||
new gridjs.Grid({
|
||||
columns: ["Jenis Bisnis Pariwisata", "Jumlah Total"], // Nama kolom
|
||||
data: businessTypeCounts.map(item => [item.business_type, item.count]), // Mengubah data untuk Grid.js
|
||||
search: true, // Menambahkan fitur pencarian
|
||||
pagination: true, // Menambahkan fitur pagination
|
||||
sort: true, // Menambahkan fitur sorting
|
||||
}).render(document.getElementById("tourisms-report-data-table"));
|
||||
@@ -1,5 +1,6 @@
|
||||
import { Grid } from "gridjs/dist/gridjs.umd.js";
|
||||
import "gridjs/dist/gridjs.umd.js";
|
||||
import Swal from "sweetalert2";
|
||||
|
||||
class GeneralTable {
|
||||
constructor(tableId, apiUrl, baseUrl, columns, options = {}) {
|
||||
@@ -94,9 +95,29 @@ class GeneralTable {
|
||||
handleDelete(event) {
|
||||
const id = event.target.getAttribute('data-id');
|
||||
console.log(id);
|
||||
if (confirm("Are you sure you want to delete this item?")) {
|
||||
this.deleteRecord(id);
|
||||
}
|
||||
// if (confirm("Are you sure you want to delete this item?")) {
|
||||
// this.deleteRecord(id);
|
||||
// }
|
||||
Swal.fire({
|
||||
title: "Are you sure?",
|
||||
text: "You won't be able to revert this!",
|
||||
icon: "warning",
|
||||
showCancelButton: true,
|
||||
confirmButtonColor: "#d33",
|
||||
cancelButtonColor: "#3085d6",
|
||||
confirmButtonText: "Yes, delete it!"
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
this.deleteRecord(id);
|
||||
Swal.fire({
|
||||
title: "Deleted!",
|
||||
text: "Your record has been deleted.",
|
||||
icon: "success",
|
||||
showConfirmButton: false, // Menghilangkan tombol OK
|
||||
timer: 2000 // Menutup otomatis dalam 2 detik (opsional)
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async deleteRecord(id) {
|
||||
@@ -110,23 +131,30 @@ class GeneralTable {
|
||||
.getAttribute("content")}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
// headers: {
|
||||
// 'Authorization': `Bearer ${document.querySelector('meta[name="api-token"]').getAttribute("content")}`,
|
||||
// 'Content-Type': 'application/json',
|
||||
// },
|
||||
});
|
||||
if (response.status === 204) { // Jika status code 204, berarti berhasil
|
||||
alert('Data deleted successfully!');
|
||||
if (response.status === 204) {
|
||||
location.reload();
|
||||
} else {
|
||||
const data = await response.json(); // Jika ada data di response body
|
||||
alert('Failed to delete data: ' + (data.message || 'Unknown error.'));
|
||||
const data = await response.json();
|
||||
showErrorAlert(`Failed to delete record: ${data.message || "Unknown error"}`);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error deleting data:', error);
|
||||
alert('Error deleting data.');
|
||||
showErrorAlert("Error deleting data. Please try again.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Fungsi untuk menampilkan alert
|
||||
function showErrorAlert(message) {
|
||||
const alertContainer = document.getElementById("alert-container");
|
||||
|
||||
alertContainer.innerHTML = `
|
||||
<div class="alert alert-danger alert-dismissible fade show" role="alert">
|
||||
${message}
|
||||
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
export default GeneralTable;
|
||||
@@ -8,14 +8,10 @@
|
||||
<div class="col-xl-12">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h5 class="card-title">Upload Data Reklame</h5>
|
||||
<p class="card-subtitle">
|
||||
Please upload a file with the extension <strong>.xls or .xlsx</strong> with a maximum size of <strong>10 MB</strong>.
|
||||
<br>
|
||||
For <strong>.xls</strong> and <strong>.xlsx</strong> files, ensure that the data is contained within a <strong>single sheet</strong> with the following columns:
|
||||
<strong>No, Nama Wajib Pajak, NPWPD, Jenis Reklame, Isi Reklame, Alamat Wajib Pajak, Lokasi Reklame, Desa,
|
||||
Kecamatan, Panajang, Lebar, Sudut Pandang, Muka, Luas, Sudut, Kontak.</strong>
|
||||
</p>
|
||||
<div class="d-flex justify-content-between align-items-center">
|
||||
<h5 class="card-title">Upload Data Reklame</h5>
|
||||
<button id="downloadtempadvertisement" class="btn btn-secondary">Download Template</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card-body">
|
||||
@@ -31,6 +27,10 @@
|
||||
<div class="dz-message needsclick">
|
||||
<i class="h1 bx bx-cloud-upload"></i>
|
||||
<h3>Drop files here or click to upload.</h3>
|
||||
<p class="card-subtitle">
|
||||
Please upload a file with the extension <strong>.xls or .xlsx</strong> with a maximum size of <strong>10 MB</strong>.
|
||||
<br>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -82,7 +82,7 @@
|
||||
<div class="toast-body">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@endsection
|
||||
|
||||
|
||||
91
resources/views/data/tourisms/form-upload.blade.php
Normal file
91
resources/views/data/tourisms/form-upload.blade.php
Normal file
@@ -0,0 +1,91 @@
|
||||
@extends('layouts.vertical', ['subtitle' => 'File Upload'])
|
||||
|
||||
@section('content')
|
||||
|
||||
@include('layouts.partials/page-title', ['title' => 'Form', 'subtitle' => 'File Uploads'])
|
||||
|
||||
<div class="row">
|
||||
<div class="col-xl-12">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<div class="d-flex justify-content-between align-items-center">
|
||||
<h5 class="card-title mb-0">Upload Data Pariwisata</h5>
|
||||
<button id="downloadtemptourisms" class="btn btn-secondary">Download Template</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card-body">
|
||||
|
||||
<div class="mb-3">
|
||||
|
||||
<div class="dropzone">
|
||||
<form action="" method="post" enctype="multipart/form-data">
|
||||
<div class="fallback">
|
||||
<input id="file-dropzone"type="file" name="file" multiple/>
|
||||
</div>
|
||||
</form>
|
||||
<div class="dz-message needsclick">
|
||||
<i class="h1 bx bx-cloud-upload"></i>
|
||||
<h3>Drop files here or click to upload.</h3>
|
||||
<p class="card-subtitle">
|
||||
Please upload a file with the extension <strong>.xls or .xlsx</strong> with a maximum size of <strong>10 MB</strong>.
|
||||
<br>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ul class="list-unstyled mb-0" id="dropzone-preview">
|
||||
<li class="mt-2" id="dropzone-preview-list">
|
||||
<!-- This is used as the file preview template -->
|
||||
<div class="border rounded">
|
||||
<div class="d-flex align-items-center p-2">
|
||||
<div class="flex-shrink-0 me-3">
|
||||
<div class="avatar-sm bg-light rounded">
|
||||
<img data-dz-thumbnail class="img-fluid rounded d-block" src="#"
|
||||
alt="" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex-grow-1">
|
||||
<div class="pt-1">
|
||||
<h5 class="fs-14 mb-1" data-dz-name>
|
||||
</h5>
|
||||
<p class="fs-13 text-muted mb-0" data-dz-size></p>
|
||||
<strong class="error text-danger" data-dz-errormessage></strong>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex-shrink-0 ms-3">
|
||||
<button data-dz-remove class="btn btn-sm btn-danger">Delete</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
<!-- end dropzon-preview -->
|
||||
</div>
|
||||
<div class="d-flex justify-content-end">
|
||||
<button id="submit-upload" class="btn btn-primary">Upload Files</button>
|
||||
</div>
|
||||
</div> <!-- end card body -->
|
||||
</div> <!-- end card -->
|
||||
</div> <!-- end col -->
|
||||
</div> <!-- end row -->
|
||||
|
||||
<div class="toast-container position-fixed end-0 top-0 p-3">
|
||||
<div id="toastUploadUmkm" class="toast" role="alert" aria-live="assertive" aria-atomic="true">
|
||||
<div class="toast-header">
|
||||
<div class="auth-logo me-auto">
|
||||
</div>
|
||||
<small class="text-muted"></small>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="toast"
|
||||
aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="toast-body">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@endsection
|
||||
|
||||
@section('scripts')
|
||||
@vite(['resources/js/data/tourisms/form-upload.js'])
|
||||
@endsection
|
||||
127
resources/views/data/tourisms/form.blade.php
Normal file
127
resources/views/data/tourisms/form.blade.php
Normal file
@@ -0,0 +1,127 @@
|
||||
@extends('layouts.vertical', ['subtitle' => $subtitle]) <!-- Menggunakan subtitle dari controller -->
|
||||
|
||||
@section('content')
|
||||
|
||||
@include('layouts.partials/page-title', ['title' => $title, 'subtitle' => $subtitle]) <!-- Menggunakan title dan subtitle dari controller -->
|
||||
|
||||
<div class="row d-flex justify-content-center">
|
||||
@if (session('error'))
|
||||
<div class="alert alert-danger">
|
||||
{{ session('error') }}
|
||||
</div>
|
||||
@endif
|
||||
|
||||
@if ($errors->any())
|
||||
<div class="alert alert-danger">
|
||||
<ul>
|
||||
@foreach ($errors->all() as $error)
|
||||
<li>{{ $error }}</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<div class="col-lg-12 col-md-12">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<button class="btn btn-danger float-end btn-back">
|
||||
<i class='bx bx-arrow-back'></i>
|
||||
Back
|
||||
</button>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<form id="create-update-form" action="{{ isset($modelInstance) && $modelInstance->id ? $apiUrl . '/' . $modelInstance->id : $apiUrl }}" method="POST">
|
||||
@csrf
|
||||
@if(isset($modelInstance))
|
||||
@method('PUT')
|
||||
@endif
|
||||
|
||||
<div class="row">
|
||||
@foreach($fields as $field => $label)
|
||||
<div class="col-md-6 form-group mb-3">
|
||||
<label for="{{ $field }}">{{ $label }}</label>
|
||||
@php
|
||||
$fieldType = $fieldTypes[$field] ?? 'text'; // Default text jika tidak ditemukan tipe
|
||||
@endphp
|
||||
|
||||
@if($fieldType == 'textarea')
|
||||
<textarea id="{{ $field }}" name="{{ $field }}" class="form-control">{{ old($field, isset($modelInstance) ? $modelInstance->{$field} : '') }}</textarea>
|
||||
@elseif($fieldType == 'select' && isset($dropdownOptions[$field]))
|
||||
<select id="{{ $field }}" name="{{ $field }}" class="form-control">
|
||||
@foreach($dropdownOptions[$field] as $code => $name)
|
||||
@php
|
||||
// $selectedValue = old($field, $modelInstance->{$field});
|
||||
$selectedValue = old($field, $modelInstance->$field ?? '');
|
||||
$isSelected = strval($selectedValue) === strval($code);
|
||||
@endphp
|
||||
<option value="{{ $code }}" class="{{ $isSelected ? 'selected' : '' }}" {{ $isSelected ? 'selected' : '' }}>
|
||||
{{ $name }}
|
||||
</option>
|
||||
@endforeach
|
||||
</select>
|
||||
@elseif($fieldType == 'combobox' && isset($dropdownOptions[$field]))
|
||||
<input class="form-control" list="{{ $field }}Options" id="{{ $field }}" name="{{ $field }}"
|
||||
value="{{ old($field, isset($modelInstance) ? $modelInstance->{$field} : '') }}" placeholder="Type to search..." oninput="fetchOptions('{{ $field }}')">
|
||||
<datalist id="{{ $field }}Options"></datalist>
|
||||
@else
|
||||
<input type="{{ $fieldType }}" id="{{ $field }}" name="{{ $field }}" class="form-control" value="{{ old($field, isset($modelInstance) ? $modelInstance->{$field} : '') }}">
|
||||
@endif
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
|
||||
<div class="d-flex justify-content-end">
|
||||
<button type="button" class="btn {{ isset($modelInstance) ? 'btn-warning' : 'btn-success' }} width-lg btn-modal" data-bs-toggle="modal" data-bs-target="#confirmationModalCenter">
|
||||
{{ isset($modelInstance) ? 'Update' : 'Create' }}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- Modal -->
|
||||
<div class="modal fade" id="confirmationModalCenter" tabindex="-1"
|
||||
aria-labelledby="confirmationModalCenterTitle" aria-hidden="true">
|
||||
<div class="modal-dialog modal-dialog-centered">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="confirmationModalCenterTitle">
|
||||
{{ isset($modelInstance) ? 'Update Confirmation' : 'Create Confirmation' }}
|
||||
</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal"
|
||||
aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p>{{ isset($modelInstance) ? 'Are you sure you want to save the data changes?' : 'Are you sure you want to create new data based on the form contents?' }}</p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary"
|
||||
data-bs-dismiss="modal">Close</button>
|
||||
<button type="button" class="btn btn-primary {{ isset($modelInstance) ? 'btn-edit' : 'btn-create' }}" data-bs-dismiss="modal">Save changes</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="toast-container position-fixed end-0 top-0 p-3">
|
||||
<div id="toastEditUpdate" class="toast" role="alert" aria-live="assertive" aria-atomic="true">
|
||||
<div class="toast-header">
|
||||
<div class="auth-logo me-auto">
|
||||
</div>
|
||||
<small class="text-muted"></small>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="toast"
|
||||
aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="toast-body">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@endsection
|
||||
|
||||
@section('scripts')
|
||||
@vite(['resources/js/data/umkm/form-create-update.js'])
|
||||
@endsection
|
||||
38
resources/views/data/tourisms/index.blade.php
Normal file
38
resources/views/data/tourisms/index.blade.php
Normal file
@@ -0,0 +1,38 @@
|
||||
@extends('layouts.vertical', ['subtitle' => 'Pariwisata'])
|
||||
|
||||
@section('css')
|
||||
@vite(['node_modules/gridjs/dist/theme/mermaid.min.css'])
|
||||
@endsection
|
||||
|
||||
@section('content')
|
||||
@include('layouts.partials/page-title', ['title' => 'Data', 'subtitle' => 'Pariwisata'])
|
||||
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h5 class="card-title">Daftar Pariwisata</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="row">
|
||||
<div class="d-flex justify-content-end gap-10 pb-3">
|
||||
<button class="btn btn-success me-2 width-lg btn-create" data-model="data/tourisms">
|
||||
<i class='bx bxs-file-plus'></i>
|
||||
Create</button>
|
||||
<button class="btn btn-primary width-lg btn-bulk-create" data-model="data/tourisms">
|
||||
<i class='bx bx-upload' ></i>
|
||||
Bulk Create
|
||||
</button>
|
||||
</div>
|
||||
<div>
|
||||
<div id="tourisms-data-table"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- <div id="alert-container"></div> --}}
|
||||
|
||||
@endsection
|
||||
|
||||
@section('scripts')
|
||||
@vite(['resources/js/data/tourisms/data-tourisms.js'])
|
||||
@endsection
|
||||
91
resources/views/data/umkm/form-upload.blade.php
Normal file
91
resources/views/data/umkm/form-upload.blade.php
Normal file
@@ -0,0 +1,91 @@
|
||||
@extends('layouts.vertical', ['subtitle' => 'File Upload'])
|
||||
|
||||
@section('content')
|
||||
|
||||
@include('layouts.partials/page-title', ['title' => 'Form', 'subtitle' => 'File Uploads'])
|
||||
|
||||
<div class="row">
|
||||
<div class="col-xl-12">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<div class="d-flex justify-content-between align-items-center">
|
||||
<h5 class="card-title mb-0">Upload Data Umkm</h5>
|
||||
<button id="downloadtempumkm" class="btn btn-secondary">Download Template</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card-body">
|
||||
|
||||
<div class="mb-3">
|
||||
|
||||
<div class="dropzone">
|
||||
<form action="" method="post" enctype="multipart/form-data">
|
||||
<div class="fallback">
|
||||
<input id="file-dropzone"type="file" name="file" multiple/>
|
||||
</div>
|
||||
</form>
|
||||
<div class="dz-message needsclick">
|
||||
<i class="h1 bx bx-cloud-upload"></i>
|
||||
<h3>Drop files here or click to upload.</h3>
|
||||
<p class="card-subtitle">
|
||||
Please upload a file with the extension <strong>.xls or .xlsx</strong> with a maximum size of <strong>10 MB</strong>.
|
||||
<br>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ul class="list-unstyled mb-0" id="dropzone-preview">
|
||||
<li class="mt-2" id="dropzone-preview-list">
|
||||
<!-- This is used as the file preview template -->
|
||||
<div class="border rounded">
|
||||
<div class="d-flex align-items-center p-2">
|
||||
<div class="flex-shrink-0 me-3">
|
||||
<div class="avatar-sm bg-light rounded">
|
||||
<img data-dz-thumbnail class="img-fluid rounded d-block" src="#"
|
||||
alt="" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex-grow-1">
|
||||
<div class="pt-1">
|
||||
<h5 class="fs-14 mb-1" data-dz-name>
|
||||
</h5>
|
||||
<p class="fs-13 text-muted mb-0" data-dz-size></p>
|
||||
<strong class="error text-danger" data-dz-errormessage></strong>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex-shrink-0 ms-3">
|
||||
<button data-dz-remove class="btn btn-sm btn-danger">Delete</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
<!-- end dropzon-preview -->
|
||||
</div>
|
||||
<div class="d-flex justify-content-end">
|
||||
<button id="submit-upload" class="btn btn-primary">Upload Files</button>
|
||||
</div>
|
||||
</div> <!-- end card body -->
|
||||
</div> <!-- end card -->
|
||||
</div> <!-- end col -->
|
||||
</div> <!-- end row -->
|
||||
|
||||
<div class="toast-container position-fixed end-0 top-0 p-3">
|
||||
<div id="toastUploadUmkm" class="toast" role="alert" aria-live="assertive" aria-atomic="true">
|
||||
<div class="toast-header">
|
||||
<div class="auth-logo me-auto">
|
||||
</div>
|
||||
<small class="text-muted"></small>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="toast"
|
||||
aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="toast-body">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@endsection
|
||||
|
||||
@section('scripts')
|
||||
@vite(['resources/js/data/umkm/form-upload.js'])
|
||||
@endsection
|
||||
127
resources/views/data/umkm/form.blade.php
Normal file
127
resources/views/data/umkm/form.blade.php
Normal file
@@ -0,0 +1,127 @@
|
||||
@extends('layouts.vertical', ['subtitle' => $subtitle]) <!-- Menggunakan subtitle dari controller -->
|
||||
|
||||
@section('content')
|
||||
|
||||
@include('layouts.partials/page-title', ['title' => $title, 'subtitle' => $subtitle]) <!-- Menggunakan title dan subtitle dari controller -->
|
||||
|
||||
<div class="row d-flex justify-content-center">
|
||||
@if (session('error'))
|
||||
<div class="alert alert-danger">
|
||||
{{ session('error') }}
|
||||
</div>
|
||||
@endif
|
||||
|
||||
@if ($errors->any())
|
||||
<div class="alert alert-danger">
|
||||
<ul>
|
||||
@foreach ($errors->all() as $error)
|
||||
<li>{{ $error }}</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<div class="col-lg-12 col-md-12">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<button class="btn btn-danger float-end btn-back">
|
||||
<i class='bx bx-arrow-back'></i>
|
||||
Back
|
||||
</button>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<form id="create-update-form" action="{{ isset($modelInstance) && $modelInstance->id ? $apiUrl . '/' . $modelInstance->id : $apiUrl }}" method="POST">
|
||||
@csrf
|
||||
@if(isset($modelInstance))
|
||||
@method('PUT')
|
||||
@endif
|
||||
|
||||
<div class="row">
|
||||
@foreach($fields as $field => $label)
|
||||
<div class="col-md-6 form-group mb-3">
|
||||
<label for="{{ $field }}">{{ $label }}</label>
|
||||
@php
|
||||
$fieldType = $fieldTypes[$field] ?? 'text'; // Default text jika tidak ditemukan tipe
|
||||
@endphp
|
||||
|
||||
@if($fieldType == 'textarea')
|
||||
<textarea id="{{ $field }}" name="{{ $field }}" class="form-control">{{ old($field, isset($modelInstance) ? $modelInstance->{$field} : '') }}</textarea>
|
||||
@elseif($fieldType == 'select' && isset($dropdownOptions[$field]))
|
||||
<select id="{{ $field }}" name="{{ $field }}" class="form-control">
|
||||
@foreach($dropdownOptions[$field] as $code => $name)
|
||||
@php
|
||||
// $selectedValue = old($field, $modelInstance->{$field});
|
||||
$selectedValue = old($field, $modelInstance->$field ?? '');
|
||||
$isSelected = strval($selectedValue) === strval($code);
|
||||
@endphp
|
||||
<option value="{{ $code }}" class="{{ $isSelected ? 'selected' : '' }}" {{ $isSelected ? 'selected' : '' }}>
|
||||
{{ $name }}
|
||||
</option>
|
||||
@endforeach
|
||||
</select>
|
||||
@elseif($fieldType == 'combobox' && isset($dropdownOptions[$field]))
|
||||
<input class="form-control" list="{{ $field }}Options" id="{{ $field }}" name="{{ $field }}"
|
||||
value="{{ old($field, isset($modelInstance) ? $modelInstance->{$field} : '') }}" placeholder="Type to search..." oninput="fetchOptions('{{ $field }}')">
|
||||
<datalist id="{{ $field }}Options"></datalist>
|
||||
@else
|
||||
<input type="{{ $fieldType }}" id="{{ $field }}" name="{{ $field }}" class="form-control" value="{{ old($field, isset($modelInstance) ? $modelInstance->{$field} : '') }}">
|
||||
@endif
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
|
||||
<div class="d-flex justify-content-end">
|
||||
<button type="button" class="btn {{ isset($modelInstance) ? 'btn-warning' : 'btn-success' }} width-lg btn-modal" data-bs-toggle="modal" data-bs-target="#confirmationModalCenter">
|
||||
{{ isset($modelInstance) ? 'Update' : 'Create' }}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- Modal -->
|
||||
<div class="modal fade" id="confirmationModalCenter" tabindex="-1"
|
||||
aria-labelledby="confirmationModalCenterTitle" aria-hidden="true">
|
||||
<div class="modal-dialog modal-dialog-centered">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="confirmationModalCenterTitle">
|
||||
{{ isset($modelInstance) ? 'Update Confirmation' : 'Create Confirmation' }}
|
||||
</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal"
|
||||
aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p>{{ isset($modelInstance) ? 'Are you sure you want to save the data changes?' : 'Are you sure you want to create new data based on the form contents?' }}</p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary"
|
||||
data-bs-dismiss="modal">Close</button>
|
||||
<button type="button" class="btn btn-primary {{ isset($modelInstance) ? 'btn-edit' : 'btn-create' }}" data-bs-dismiss="modal">Save changes</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="toast-container position-fixed end-0 top-0 p-3">
|
||||
<div id="toastEditUpdate" class="toast" role="alert" aria-live="assertive" aria-atomic="true">
|
||||
<div class="toast-header">
|
||||
<div class="auth-logo me-auto">
|
||||
</div>
|
||||
<small class="text-muted"></small>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="toast"
|
||||
aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="toast-body">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@endsection
|
||||
|
||||
@section('scripts')
|
||||
@vite(['resources/js/data/umkm/form-create-update.js'])
|
||||
@endsection
|
||||
38
resources/views/data/umkm/index.blade.php
Normal file
38
resources/views/data/umkm/index.blade.php
Normal file
@@ -0,0 +1,38 @@
|
||||
@extends('layouts.vertical', ['subtitle' => 'UMKM'])
|
||||
|
||||
@section('css')
|
||||
@vite(['node_modules/gridjs/dist/theme/mermaid.min.css'])
|
||||
@endsection
|
||||
|
||||
@section('content')
|
||||
@include('layouts.partials/page-title', ['title' => 'Data', 'subtitle' => 'UMKM'])
|
||||
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h5 class="card-title">Daftar UMKM</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="row">
|
||||
<div class="d-flex justify-content-end gap-10 pb-3">
|
||||
<button class="btn btn-success me-2 width-lg btn-create" data-model="data/umkm">
|
||||
<i class='bx bxs-file-plus'></i>
|
||||
Create</button>
|
||||
<button class="btn btn-primary width-lg btn-bulk-create" data-model="data/umkm">
|
||||
<i class='bx bx-upload' ></i>
|
||||
Bulk Create
|
||||
</button>
|
||||
</div>
|
||||
<div>
|
||||
<div id="umkm-data-table"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="alert-container"></div>
|
||||
|
||||
@endsection
|
||||
|
||||
@section('scripts')
|
||||
@vite(['resources/js/data/umkm/data-umkm.js'])
|
||||
@endsection
|
||||
28
resources/views/report/tourisms/index.blade.php
Normal file
28
resources/views/report/tourisms/index.blade.php
Normal file
@@ -0,0 +1,28 @@
|
||||
@extends('layouts.vertical', ['subtitle' => 'Report Pariwisata'])
|
||||
|
||||
@section('css')
|
||||
@vite(['node_modules/gridjs/dist/theme/mermaid.min.css'])
|
||||
@endsection
|
||||
|
||||
@section('content')
|
||||
@include('layouts.partials/page-title', ['title' => 'Report', 'subtitle' => 'Report Pariwisata'])
|
||||
|
||||
<input id="business_type_counts" type="hidden" value="{{ json_encode($businessTypeCounts) }}">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h5 class="card-title">Laporan Pariwisata</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="row">
|
||||
<div>
|
||||
<div id="tourisms-report-data-table"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@endsection
|
||||
|
||||
@section('scripts')
|
||||
@vite(['resources/js/report/tourisms/index.js'])
|
||||
@endsection
|
||||
Reference in New Issue
Block a user