done all view dummy new modul

This commit is contained in:
arifal
2025-03-12 00:32:50 +07:00
parent b8f7d7f655
commit dce5409248
25 changed files with 1301 additions and 10 deletions

View File

@@ -0,0 +1,90 @@
import { Grid } from "gridjs/dist/gridjs.umd.js";
import "gridjs/dist/gridjs.umd.js";
import gridjs from "gridjs/dist/gridjs.umd.js";
import GlobalConfig from "../global-config";
class Approval {
constructor() {
this.toastMessage = document.getElementById("toast-message");
this.toastElement = document.getElementById("toastNotification");
this.toast = new bootstrap.Toast(this.toastElement);
this.table = null;
this.initTableApproval();
}
initTableApproval() {
let tableContainer = document.getElementById("table-approvals");
this.table = new Grid({
columns: [
"ID",
{ name: "Name", width: "15%" },
{ name: "Condition", width: "7%" },
"Registration Number",
"Document Number",
{ name: "Address", width: "30%" },
"Status",
"Function Type",
"Consultation Type",
{ name: "Due Date", width: "10%" },
{
name: "Action",
formatter: (cell) => {
return gridjs.html(`
<div class="d-flex justify-content-center align-items-center gap-2">
<button class="btn btn-sm btn-success approve-btn" data-id="${cell}">
Approve
</button>
<button class="btn btn-sm btn-danger reject-btn" data-id="${cell}">
Reject
</button>
</div>
`);
},
},
],
search: {
server: {
url: (prev, keyword) => `${prev}?search=${keyword}`,
},
debounceTimeout: 1000,
},
pagination: {
limit: 15,
server: {
url: (prev, page) =>
`${prev}${prev.includes("?") ? "&" : "?"}page=${
page + 1
}`,
},
},
sort: true,
server: {
url: `${GlobalConfig.apiHost}/api/request-assignments`,
credentials: "include",
headers: {
Authorization: `Bearer ${document
.querySelector('meta[name="api-token"]')
.getAttribute("content")}`,
"Content-Type": "application/json",
},
then: (data) =>
data.data.map((item) => [
item.id,
item.name,
item.condition,
item.registration_number,
item.document_number,
item.address,
item.status_name,
item.function_type,
item.consultation_type,
item.due_date,
item.id,
]),
total: (data) => data.meta.total,
},
}).render(tableContainer);
}
}
document.addEventListener("DOMContentLoaded", function (e) {
new Approval();
});

View File

@@ -0,0 +1,56 @@
import { Grid } from "gridjs/dist/gridjs.umd.js";
import "gridjs/dist/gridjs.umd.js";
// Fungsi untuk menghasilkan data dummy
function generateDummyInvitations(count = 10) {
const statuses = ["Terkirim", "Gagal", "Menunggu"];
const dummyData = [];
for (let i = 1; i <= count; i++) {
const email = `user${i}@example.com`;
const status = statuses[Math.floor(Math.random() * statuses.length)];
const createdAt = new Date(
Date.now() - Math.floor(Math.random() * 100000000)
)
.toISOString()
.replace("T", " ")
.substring(0, 19);
dummyData.push([i, email, status, createdAt]);
}
return dummyData;
}
class Invitations {
constructor() {
this.table = null;
this.initEvents();
}
initEvents() {
this.initTableInvitations();
}
initTableInvitations() {
let tableContainer = document.getElementById("table-invitations");
this.table = new Grid({
columns: [
{ name: "ID" },
{ name: "Email" },
{ name: "Status" },
{ name: "Created" },
],
data: generateDummyInvitations(50), // Bisa ganti jumlah data dummy
pagination: {
limit: 10,
},
sort: true,
search: true,
}).render(tableContainer);
}
}
document.addEventListener("DOMContentLoaded", function () {
new Invitations();
});

View File

@@ -0,0 +1,104 @@
import { Grid } from "gridjs/dist/gridjs.umd.js";
import "gridjs/dist/gridjs.umd.js";
import gridjs from "gridjs/dist/gridjs.umd.js";
import GlobalConfig, { addThousandSeparators } from "../global-config.js";
import moment from "moment";
import InitDatePicker from "../utils/InitDatePicker.js";
class PaymentRecaps {
constructor() {
this.toastMessage = document.getElementById("toast-message");
this.toastElement = document.getElementById("toastNotification");
this.toast = new bootstrap.Toast(this.toastElement);
this.table = null;
this.initTablePaymentRecaps();
this.initFilterDatepicker();
}
initFilterDatepicker() {
new InitDatePicker(
"#datepicker-payment-recap",
this.handleChangeFilterDate.bind(this)
).init();
}
handleChangeFilterDate(strDate) {
console.log("filter date : ", strDate);
}
formatCategory(category) {
const categoryMap = {
potention_sum: "Potensi",
non_verified_sum: "Belum Terverifikasi",
verified_sum: "Terverifikasi",
business_sum: "Usaha",
non_business_sum: "Non Usaha",
spatial_sum: "Tata Ruang",
waiting_click_dpmptsp_sum: "Menunggu Klik DPMPTSP",
issuance_realization_pbg_sum: "Realisasi Terbit PBG",
process_in_technical_office_sum: "Proses Di Dinas Teknis",
};
return categoryMap[category] || category; // Return mapped value or original category
}
initTablePaymentRecaps() {
let tableContainer = document.getElementById("table-payment-recaps");
this.table = new Grid({
columns: [
{ name: "Kategori", data: (row) => row[0] },
{ name: "Nominal", data: (row) => row[1] },
{
name: "Created",
data: (row) => row[2],
attributes: { style: "width: 200px; white-space: nowrap;" },
},
],
pagination: {
limit: 10,
server: {
url: (prev, page) =>
`${prev}${prev.includes("?") ? "&" : "?"}page=${
page + 1
}`,
},
},
sort: true,
server: {
url: `${GlobalConfig.apiHost}/api/payment-recaps`,
headers: {
Authorization: `Bearer ${document
.querySelector('meta[name="api-token"]')
.getAttribute("content")}`,
"Content-Type": "application/json",
},
then: (response) => {
console.log("API Response:", response); // Debugging
if (!response.data || !Array.isArray(response.data)) {
console.error(
"Error: Data is not an array",
response.data
);
return [];
}
return response.data.map((item) => [
this.formatCategory(item.category ?? "Unknown"), // Ensure category is not null
addThousandSeparators(
Number(item.nominal).toString() || 0
), // Ensure nominal is a valid number
moment(item.created_at).isValid()
? moment(item.created_at).format(
"YYYY-MM-DD H:mm:ss"
)
: "-", // Handle invalid dates
]);
},
total: (response) => response.pagination?.total || 0,
},
width: "auto",
fixedHeader: true,
}).render(tableContainer);
}
}
document.addEventListener("DOMContentLoaded", function (e) {
new PaymentRecaps();
});

View File

@@ -2,10 +2,15 @@ import { Grid } from "gridjs/dist/gridjs.umd.js";
import "gridjs/dist/gridjs.umd.js";
import gridjs from "gridjs/dist/gridjs.umd.js";
import GlobalConfig from "../global-config";
import { Dropzone } from "dropzone";
Dropzone.autoDiscover = false;
class PbgTasks {
init() {
this.initTableRequestAssignment();
this.handleSendNotification();
this.handleUpload();
this.handleUploadBeritaAcara();
}
initTableRequestAssignment() {
@@ -28,25 +33,33 @@ class PbgTasks {
{ name: "Due Date", width: "10%" },
{
name: "Action",
formatter: function (cell) {
let tableContainer = document.getElementById("table-pbg-tasks");
let canUpdate = tableContainer.getAttribute("data-updater") === "1";
formatter: (cell) => {
let tableContainer =
document.getElementById("table-pbg-tasks");
let canUpdate =
tableContainer.getAttribute("data-updater") === "1";
if (!canUpdate) {
return gridjs.html(`
<span class="text-muted">No Privilege</span>
`);
return gridjs.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>
`);
},
}
},
],
search: {
server: {
@@ -91,6 +104,96 @@ class PbgTasks {
},
}).render(document.getElementById("table-pbg-tasks"));
}
handleSendNotification() {
this.toastMessage = document.getElementById("toast-message");
this.toastElement = document.getElementById("toastNotification");
this.toast = new bootstrap.Toast(this.toastElement);
document
.getElementById("sendNotificationBtn")
.addEventListener("click", () => {
let notificationStatus =
document.getElementById("notificationStatus").value;
// Show success toast
this.toastMessage.innerText = "Notifikasi berhasil dikirim!";
this.toast.show();
// Close modal after sending
let modal = bootstrap.Modal.getInstance(
document.getElementById("sendNotificationModal")
);
modal.hide();
});
}
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();
}
});
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]);
}
});
// 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.");
}
});
// Success callback
dz.on("success", function (file, response) {
alert("File uploaded successfully!");
dz.removeAllFiles(); // Clear after upload
});
// Error callback
dz.on("error", function (file, errorMessage) {
alert("Upload failed: " + errorMessage);
});
},
});
}
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();
}
});
}
}
document.addEventListener("DOMContentLoaded", function (e) {

View File

@@ -0,0 +1,69 @@
import { Grid } from "gridjs/dist/gridjs.umd.js";
import "gridjs/dist/gridjs.umd.js";
import gridjs from "gridjs/dist/gridjs.umd.js";
import GlobalConfig, { addThousandSeparators } from "../global-config.js";
class ReportPaymentRecaps {
constructor() {
this.table = null;
this.initTableReportPaymentRecaps();
}
initTableReportPaymentRecaps() {
let tableContainer = document.getElementById(
"table-report-payment-recaps"
);
this.table = new Grid({
columns: [
{ name: "Kecamatan" },
{
name: "Total",
formatter: (cell) => addThousandSeparators(cell),
},
],
pagination: {
limit: 10,
server: {
url: (prev, page) =>
`${prev}${prev.includes("?") ? "&" : "?"}page=${
page + 1
}`,
},
},
sort: true,
server: {
url: `${GlobalConfig.apiHost}/api/report-payment-recaps`,
headers: {
Authorization: `Bearer ${document
.querySelector('meta[name="api-token"]')
.getAttribute("content")}`,
"Content-Type": "application/json",
},
then: (response) => {
console.log("API Response:", response); // Debugging
// Pastikan response memiliki data
if (
!response ||
!response.data ||
!Array.isArray(response.data.data)
) {
console.error("Error: Data is not an array", response);
return [];
}
return response.data.data.map((item) => [
item.kecamatan || "Unknown",
item.total,
]);
},
total: (response) => response.data.total || 0, // Ambil total dari API pagination
},
width: "auto",
fixedHeader: true,
}).render(tableContainer);
}
}
document.addEventListener("DOMContentLoaded", function (e) {
new ReportPaymentRecaps();
});

View File

@@ -0,0 +1,67 @@
import { Grid } from "gridjs/dist/gridjs.umd.js";
import "gridjs/dist/gridjs.umd.js";
import gridjs from "gridjs/dist/gridjs.umd.js";
import GlobalConfig, { addThousandSeparators } from "../global-config.js";
class ReportPbgPTSP {
constructor() {
this.table = null;
this.initTableReportPbgPTSP();
}
initTableReportPbgPTSP() {
let tableContainer = document.getElementById("table-report-pbg-ptsp");
this.table = new Grid({
columns: [
{ name: "Status" },
{
name: "Total",
formatter: (cell) => cell,
},
],
pagination: {
limit: 10,
server: {
url: (prev, page) =>
`${prev}${prev.includes("?") ? "&" : "?"}page=${
page + 1
}`,
},
},
sort: true,
server: {
url: `${GlobalConfig.apiHost}/api/report-pbg-ptsp`,
headers: {
Authorization: `Bearer ${document
.querySelector('meta[name="api-token"]')
.getAttribute("content")}`,
"Content-Type": "application/json",
},
then: (response) => {
console.log("API Response:", response); // Debugging
// Pastikan response memiliki data
if (
!response ||
!response.data ||
!Array.isArray(response.data.data)
) {
console.error("Error: Data is not an array", response);
return [];
}
return response.data.data.map((item) => [
item.status_name || "Unknown",
item.total,
]);
},
total: (response) => response.data.total || 0, // Ambil total dari API pagination
},
width: "auto",
fixedHeader: true,
}).render(tableContainer);
}
}
document.addEventListener("DOMContentLoaded", function (e) {
new ReportPbgPTSP();
});

View File

@@ -0,0 +1,112 @@
import { Grid } from "gridjs/dist/gridjs.umd.js";
import "gridjs/dist/gridjs.umd.js";
class TpaTpt {
constructor() {
this.toastMessage = document.getElementById("toast-message");
this.toastElement = document.getElementById("toastNotification");
this.toast = new bootstrap.Toast(this.toastElement);
this.table = null;
// Initialize functions
this.initTableTpaTpt();
this.initEvents();
}
initEvents() {}
initTableTpaTpt() {
let tableContainer = document.getElementById("table-tpa-tpt");
tableContainer.innerHTML = "";
let canUpdate = tableContainer.getAttribute("data-updater") === "1";
let canDelete = tableContainer.getAttribute("data-destroyer") === "1";
// Kecamatan (districts) in Kabupaten Bandung
const kecamatanList = [
"Bojongsoang",
"Cangkuang",
"Cicalengka",
"Cikancung",
"Cilengkrang",
"Cileunyi",
"Cimaung",
"Cimenyan",
"Ciparay",
"Cisaat",
"Dayeuhkolot",
"Ibun",
"Katapang",
"Kertasari",
"Kutawaringin",
"Majalaya",
"Margaasih",
"Margahayu",
"Nagreg",
"Pacet",
"Pameungpeuk",
"Pangalengan",
"Paseh",
"Rancaekek",
"Solokanjeruk",
"Soreang",
"Banjaran",
"Baleendah",
];
// Generate random PT (companies)
function generateCompanyName() {
const prefixes = ["PT", "CV", "UD"];
const names = [
"Mitra Sejahtera",
"Berkah Jaya",
"Makmur Abadi",
"Sukses Mandiri",
"Indah Lestari",
"Tirta Alam",
];
const suffixes = [
"Indonesia",
"Sentosa",
"Persada",
"Global",
"Tbk",
"Jaya",
];
return `${prefixes[Math.floor(Math.random() * prefixes.length)]} ${
names[Math.floor(Math.random() * names.length)]
} ${suffixes[Math.floor(Math.random() * suffixes.length)]}`;
}
// Function to generate random dummy data
function generateDummyData(count) {
let data = [];
for (let i = 1; i <= count; i++) {
let name = `TPA ${String.fromCharCode(64 + (i % 26))}${i}`; // Example: TPA A1, TPA B2, etc.
let location =
kecamatanList[
Math.floor(Math.random() * kecamatanList.length)
];
let lat = (-6.9 + Math.random() * 0.3).toFixed(6); // Approximate latitude for Bandung area
let lng = (107.5 + Math.random() * 0.5).toFixed(6); // Approximate longitude for Bandung area
let owner = generateCompanyName();
data.push([name, location, lat, lng, owner]);
}
return data;
}
this.table = new Grid({
columns: ["Nama", "Kecamatan", "Lat", "Lng", "Pemilik (PT)"],
data: generateDummyData(100), // Generate 100 rows of dummy data
pagination: {
limit: 10,
},
search: true,
sort: true,
}).render(tableContainer);
}
}
document.addEventListener("DOMContentLoaded", function (e) {
new TpaTpt();
});

View File

@@ -0,0 +1,27 @@
@extends('layouts.vertical', ['subtitle' => 'Approval'])
@section('css')
@vite(['node_modules/gridjs/dist/theme/mermaid.min.css'])
@endsection
@section('content')
@include('layouts.partials/page-title', ['title' => 'Approval', 'subtitle' => 'Approval Pejabat'])
<x-toast-notification />
<div class="row">
<div class="col-12">
<div class="card w-100">
<div class="card-body">
<div id="table-approvals"></div>
</div>
</div>
</div>
</div>
@endsection
@section('scripts')
@vite(['resources/js/approval/index.js'])
@endsection

View File

@@ -0,0 +1,45 @@
@extends('layouts.vertical', ['subtitle' => 'Undangan'])
@section('css')
@vite(['node_modules/gridjs/dist/theme/mermaid.min.css'])
@endsection
@section('content')
@include('layouts.partials/page-title', ['title' => 'Tools', 'subtitle' => 'Undangan'])
<x-toast-notification />
<div class="container">
<div class="row justify-content-center">
<!-- Bagian Kirim Undangan -->
<div class="col-lg-8 col-md-10">
<div class="card shadow-sm">
<div class="card-body">
<h5 class="card-title">Kirim Undangan</h5>
<label for="email-textarea" class="form-label">Alamat Email</label>
<textarea class="form-control mb-3" id="email-textarea" rows="4" placeholder="Masukkan email, pisahkan dengan koma..."></textarea>
<div class="d-flex justify-content-end">
<button class="btn btn-info btn-sm px-4 btn-send-invitations">Kirim</button>
</div>
</div>
</div>
</div>
<!-- Bagian Tabel Undangan -->
<div class="col-lg-10 col-md-12 mt-4">
<div class="card shadow-sm">
<div class="card-body">
<h5 class="card-title">Log Undangan</h5>
<div id="table-invitations"></div>
</div>
</div>
</div>
</div>
</div>
@endsection
@section('scripts')
@vite(['resources/js/invitations/index.js'])
@endsection

View File

@@ -0,0 +1,34 @@
@extends('layouts.vertical', ['subtitle' => 'Rekap Pembayaran'])
@section('css')
@vite(['node_modules/gridjs/dist/theme/mermaid.min.css'])
@endsection
@section('content')
@include('layouts.partials/page-title', ['title' => 'Laporan', 'subtitle' => 'Rekap Pembayaran'])
<x-toast-notification />
<div class="row">
<div class="col-12">
<div class="card w-100">
<div class="card-body">
<div class="row mb-3">
<div class="col-12 d-flex justify-content-end align-items-center flex-wrap gap-2">
<input type="text" id="datepicker-payment-recap" class="form-control w-auto" placeholder="Filter Tanggal" />
<button class="btn btn-info btn-sm" id="btnFilterData">Filter</button>
</div>
</div>
<div id="table-payment-recaps"></div>
</div>
</div>
</div>
</div>
@endsection
@section('scripts')
@vite(['resources/js/payment-recaps/index.js'])
@endsection

View File

@@ -8,11 +8,16 @@
@include('layouts.partials/page-title', ['title' => 'Data', 'subtitle' => 'PBG'])
<x-toast-notification />
<div class="row">
<div class="col-12">
<div class="card w-100">
<div class="card-body">
<div class="d-flex flex-wrap justify-content-end">
<button class="btn btn-sm btn-info btn-send-notification me-3" data-bs-toggle="modal" data-bs-target="#sendNotificationModal">
Kirim Notifikasi
</button>
@if ($creator)
<a href="{{ route('pbg-task.create')}}" class="btn btn-success btn-sm d-block d-sm-inline w-auto">Create</a>
@endif
@@ -26,6 +31,109 @@
</div>
</div>
<!-- Modal -->
<div class="modal fade" id="sendNotificationModal" tabindex="-1" aria-labelledby="sendNotificationLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="sendNotificationLabel">Kirim Notifikasi</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<label for="notificationStatus" class="form-label">Pilih Status</label>
<select class="form-select" id="notificationStatus">
<option value="ditolak">Permohonan Ditolak</option>
<option value="draf">Draf</option>
<option value="verifikasi-kelengkapan">Verifikasi Kelengkapan Dokumen</option>
<option value="perbaikan-dokumen">Perbaikan Dokumen</option>
<option value="menunggu-penugasan">Menunggu Penugasan TPT/TPA</option>
<option value="menunggu-jadwal">Menunggu Jadwal Konsultasi</option>
<option value="verifikasi-tpt">Verifikasi Data TPT - (SLf Eksisting)</option>
<option value="perbaikan-verifikasi">Perbaikan Verifikasi Data TPT - (SLf Eksisting)</option>
<option value="pelaksanaan-konsultasi">Pelaksanaan Konsultasi</option>
<option value="menunggu-hasil">Menunggu Hasil Konsultasi</option>
<option value="perbaikan-dokumen-konsultasi">Perbaikan Dokumen Konsultasi</option>
<option value="perhitungan-retribusi">Perhitungan Retribusi</option>
<option value="penerbitan-sppst">Penerbitan SPPST</option>
<option value="perbaikan-retribusi">Perbaikan Data Retribusi</option>
<option value="penerbitan-skrd">Proses Penerbitan SKRD</option>
<option value="menunggu-pembayaran">Menunggu Pembayaran Retribusi</option>
<option value="verifikasi-pembayaran">Verifikasi Pembayaran Retribusi</option>
<option value="verifikasi-sk-pbg">Verifikasi SK PBG</option>
</select>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Batal</button>
<button type="button" class="btn btn-primary" id="sendNotificationBtn">Kirim</button>
</div>
</div>
</div>
</div>
<!-- Modal -->
<div class="modal fade" id="uploadModal" tabindex="-1" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Upload Bukti Bayar</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<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>
</div>
<!-- Submit Button -->
<div class="d-flex justify-content-end">
<button type="button" id="uploadBtn" class="btn btn-success">
<i class="bx bx-upload"></i> Upload
</button>
</div>
</div>
</div>
</div>
</div>
<!-- Modal -->
<div class="modal fade" id="uploadBeritaAcara" 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>
</div>
<div class="modal-body">
<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>
</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>
</div>
</div>
</div>
</div>
</div>
@endsection
@section('scripts')

View File

@@ -0,0 +1,28 @@
@extends('layouts.vertical', ['subtitle' => 'Laporan Rekap Data Pembayaran'])
@section('css')
@vite(['node_modules/gridjs/dist/theme/mermaid.min.css'])
@endsection
@section('content')
@include('layouts.partials/page-title', ['title' => 'Laporan', 'subtitle' => 'Lap Rekap Data Pembayaran'])
<x-toast-notification />
<div class="row">
<div class="col-12">
<div class="card w-100">
<div class="card-body">
<div id="table-report-payment-recaps"></div>
</div>
</div>
</div>
</div>
@endsection
@section('scripts')
@vite(['resources/js/report-payment-recaps/index.js'])
@endsection

View File

@@ -0,0 +1,27 @@
@extends('layouts.vertical', ['subtitle' => 'Lap PBG (PTSP)'])
@section('css')
@vite(['node_modules/gridjs/dist/theme/mermaid.min.css'])
@endsection
@section('content')
@include('layouts.partials/page-title', ['title' => 'Laporan', 'subtitle' => 'Lap PBG (PTSP)'])
<x-toast-notification />
<div class="row">
<div class="col-12">
<div class="card w-100">
<div class="card-body">
<div id="table-report-pbg-ptsp"></div>
</div>
</div>
</div>
</div>
@endsection
@section('scripts')
@vite(['resources/js/report-pbg-ptsp/index.js'])
@endsection

View File

@@ -0,0 +1,27 @@
@extends('layouts.vertical', ['subtitle' => 'TPA TPT'])
@section('css')
@vite(['node_modules/gridjs/dist/theme/mermaid.min.css'])
@endsection
@section('content')
@include('layouts.partials/page-title', ['title' => 'Data', 'subtitle' => 'TPA TPT'])
<x-toast-notification />
<div class="row">
<div class="col-12">
<div class="card w-100">
<div class="card-body">
<div id="table-tpa-tpt"></div>
</div>
</div>
</div>
</div>
@endsection
@section('scripts')
@vite(['resources/js/tpa-tpt/index.js'])
@endsection