merge conflix spatial-plannings

This commit is contained in:
arifal
2025-02-21 08:42:08 +07:00
32 changed files with 1342 additions and 127 deletions

View File

@@ -28,12 +28,7 @@ document.addEventListener("DOMContentLoaded", function () {
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";
@@ -49,7 +44,6 @@ document.addEventListener("DOMContentLoaded", function () {
})
.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) {
@@ -74,11 +68,11 @@ document.addEventListener("DOMContentLoaded", function () {
toast.classList.add('show'); // Show the toast
setTimeout(() => {
toast.classList.remove('show'); // Hide the toast after 3 seconds
}, 3000);
}, 2000);
setTimeout(() => {
window.location.href = '/data/advertisements';
}, 3000);
}, 1000);
} else {
if (authLogo) {
// Hapus ikon yang sudah ada jika ada
@@ -96,21 +90,21 @@ document.addEventListener("DOMContentLoaded", function () {
// Tambahkan ikon ke dalam auth-logo
authLogo.appendChild(icon);
}
// Set error message for the toast
toastBody.textContent = "Error: " + (responseData.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";
// Set error message for the toast
toastBody.textContent = "Failed: " + (data.message || "Something went wrong");
toast.classList.add('show'); // Show the toast
setTimeout(() => {
toast.classList.remove('show'); // Hide the toast after 3 seconds
}, 3000);
}
})
.catch(error => {
console.error("Error:", error);
.catch(errors => {
if (authLogo) {
// Hapus ikon yang sudah ada jika ada
const existingIcon = authLogo.querySelector('.bx');
@@ -127,14 +121,14 @@ document.addEventListener("DOMContentLoaded", function () {
// Tambahkan ikon ke dalam auth-logo
authLogo.appendChild(icon);
}
// Enable button and reset its text on error
modalButton.disabled = false;
modalButton.innerHTML = isEdit ? "Update" : "Create";
// 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);
@@ -144,7 +138,6 @@ document.addEventListener("DOMContentLoaded", function () {
// 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

View File

@@ -0,0 +1,63 @@
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 dataSpatialPlanningColumns = [
"No",
"Nama",
"KBLI",
"Kegiatan",
"Luas",
"Lokasi",
"Nomor",
"Tanggal",
{
name: "Actions",
widht: "120px",
formatter: function (cell, row) {
const id = row.cells[8].data;
const model = "data/spatial-plannings";
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(
"spatial-planning-data-table",
`${GlobalConfig.apiHost}/api/spatial-plannings`,
`${GlobalConfig.apiHost}`,
dataSpatialPlanningColumns
);
table.processData = function (data) {
return data.data.map((item) => {
return [
item.no,
item.name,
item.kbli,
item.activities,
item.area,
item.location,
item.number,
item.date,
item.id,
];
});
};
table.init();
});

View 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;
});
const url = form.getAttribute("action");
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) => {
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/spatial-plannings";
}, 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) => {
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;
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();
});
});

View File

@@ -0,0 +1,150 @@
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/spatial-plannings/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/spatial-plannings";
}, 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('downloadtempspatialPlannings').addEventListener('click', function() {
var url = `${GlobalConfig.apiHost}/api/download-template-spatialPlannings`;
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) => {
console.log(blob);
const url = window.URL.createObjectURL(blob);
const a = document.createElement('a');
a.style.display = 'none';
a.href = url;
a.download = 'template_rencana_tata_ruang.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('toastUploadSpatialPlannings');
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();
}

View File

@@ -5,6 +5,7 @@ import GlobalConfig from "../../global-config.js";
import GeneralTable from "../../table-generator.js";
const dataTourismsColumns = [
"No",
"Nama Perusahaan",
"Nama Proyek",
"Alamat Usaha",
@@ -54,6 +55,7 @@ document.addEventListener("DOMContentLoaded", () => {
table.processData = function (data) {
return data.data.map((item) => {
return [
item.no,
item.business_name,
item.project_name,
item.business_address,

View File

@@ -28,12 +28,7 @@ document.addEventListener("DOMContentLoaded", function () {
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";
@@ -49,7 +44,6 @@ document.addEventListener("DOMContentLoaded", function () {
})
.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) {
@@ -113,7 +107,6 @@ document.addEventListener("DOMContentLoaded", function () {
}
})
.catch((error) => {
console.error("Error:", error);
if (authLogo) {
// Hapus ikon yang sudah ada jika ada
const existingIcon = authLogo.querySelector(".bx");
@@ -148,7 +141,6 @@ document.addEventListener("DOMContentLoaded", function () {
// 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

View File

@@ -88,7 +88,7 @@ dropzone.on("complete", function(file) {
// Add event listener to download file template
document.getElementById('downloadtemptourisms').addEventListener('click', function() {
var url = `${GlobalConfig.apiHost}/api/download-template-umkm`;
var url = `${GlobalConfig.apiHost}/api/download-template-tourism`;
fetch(url, {
method: 'GET',
headers: {
@@ -105,11 +105,12 @@ document.getElementById('downloadtemptourisms').addEventListener('click', functi
}
})
.then((blob) => {
console.log(blob);
const url = window.URL.createObjectURL(blob);
const a = document.createElement('a');
a.style.display = 'none';
a.href = url;
a.download = 'template_tourisms.xlsx';
a.download = 'template_pariwisata.xlsx';
document.body.appendChild(a);
a.click();
window.URL.revokeObjectURL(url);
@@ -122,7 +123,7 @@ document.getElementById('downloadtemptourisms').addEventListener('click', functi
// Function to show toast
function showToast(iconClass, iconColor, message) {
const toastElement = document.getElementById('toastUploadUmkm');
const toastElement = document.getElementById('toastUploadTourisms');
const toastBody = toastElement.querySelector('.toast-body');
const toastHeader = toastElement.querySelector('.toast-header');

View File

@@ -4,6 +4,7 @@ import GlobalConfig from "../../global-config.js";
import GeneralTable from "../../table-generator.js";
const dataUMKMColumns = [
"No",
"Nama Usaha",
"Alamat Usaha",
"Deskripsi Usaha",
@@ -54,6 +55,7 @@ document.addEventListener("DOMContentLoaded", () => {
table.processData = function (data) {
return data.data.map((item) => {
return [
item.no,
item.business_name,
item.business_address,
item.business_desc,

View File

@@ -28,12 +28,7 @@ document.addEventListener("DOMContentLoaded", function () {
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";
@@ -74,11 +69,11 @@ document.addEventListener("DOMContentLoaded", function () {
toast.classList.add('show'); // Show the toast
setTimeout(() => {
toast.classList.remove('show'); // Hide the toast after 3 seconds
}, 3000);
}, 2000);
setTimeout(() => {
window.location.href = '/data/umkm';
}, 3000);
}, 1000);
} else {
if (authLogo) {
// Hapus ikon yang sudah ada jika ada
@@ -96,14 +91,16 @@ document.addEventListener("DOMContentLoaded", function () {
// 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";
// Set error message for the toast
toastBody.textContent = "Error: " + (data.message || "Something went wrong");
toast.classList.add('show'); // Show the toast
setTimeout(() => {
toast.classList.remove('show'); // Hide the toast after 3 seconds
}, 3000);
@@ -127,14 +124,15 @@ document.addEventListener("DOMContentLoaded", function () {
// 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";
// Set error message for the toast
toastBody.textContent = "An error occurred while processing your request.";
toast.classList.add('show'); // Show the toast
setTimeout(() => {
toast.classList.remove('show'); // Hide the toast after 3 seconds
}, 3000);
@@ -144,7 +142,6 @@ document.addEventListener("DOMContentLoaded", function () {
// 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

View 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="downloadtempspatialPlannings" 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>&nbsp;
</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="toastUploadSpatialPlannings" 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/spatialPlannings/form-upload.js'])
@endsection

View File

@@ -0,0 +1,130 @@
@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>
@elseif($fieldType == 'date')
<input type="date" id="{{ $field }}" name="{{ $field }}" class="form-control"
value="{{ old($field, isset($modelInstance) && $modelInstance->{$field} ? \Carbon\Carbon::parse($modelInstance->{$field})->format('Y-m-d') : '') }}">
@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/spatialPlannings/form-create-update.js'])
@endsection

View File

@@ -0,0 +1,38 @@
@extends('layouts.vertical', ['subtitle' => 'Rencana Tata Ruang'])
@section('css')
@vite(['node_modules/gridjs/dist/theme/mermaid.min.css'])
@endsection
@section('content')
@include('layouts.partials/page-title', ['title' => 'Data', 'subtitle' => 'Rencana Tata Ruang'])
<div class="card">
<div class="card-header">
<h5 class="card-title">Daftar Rencana Tata Ruang</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/spatial-plannings">
<i class='bx bxs-file-plus'></i>
Create</button>
<button class="btn btn-primary width-lg btn-bulk-create" data-model="data/spatial-plannings">
<i class='bx bx-upload' ></i>
Bulk Create
</button>
</div>
<div>
<div id="spatial-planning-data-table"></div>
</div>
</div>
</div>
</div>
{{-- <div id="alert-container"></div> --}}
@endsection
@section('scripts')
@vite(['resources/js/data/spatialPlannings/data-spatialPlannings.js'])
@endsection

View File

@@ -71,7 +71,7 @@
</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 id="toastUploadTourisms" class="toast" role="alert" aria-live="assertive" aria-atomic="true">
<div class="toast-header">
<div class="auth-logo me-auto">
</div>