diff --git a/app/Http/Controllers/Api/BigDataResumeController.php b/app/Http/Controllers/Api/BigDataResumeController.php index 89b4d7f..72446df 100644 --- a/app/Http/Controllers/Api/BigDataResumeController.php +++ b/app/Http/Controllers/Api/BigDataResumeController.php @@ -173,6 +173,53 @@ class BigDataResumeController extends Controller } } + public function payment_recaps(Request $request) + { + try { + $query = BigdataResume::query()->orderBy('id', 'desc'); + + if ($request->filled('date')) { + $query->where('year', 'LIKE', '%' . $request->input('search') . '%'); + } + + $data = $query->paginate(10); + + // Restructure response + $transformedData = []; + + foreach ($data as $item) { + $createdAt = $item->created_at; + $id = $item->id; + + foreach ($item->toArray() as $key => $value) { + // Only include columns with "sum" in their names + if (strpos($key, 'sum') !== false) { + $transformedData[] = [ + 'id' => $id, + 'category' => $key, + 'nominal' => $value, + 'created_at' => $createdAt, + ]; + } + } + } + + return response()->json([ + 'data' => $transformedData, // Flat array + 'pagination' => [ + 'total' => $data->total(), + 'per_page' => $data->perPage(), + 'current_page' => $data->currentPage(), + 'last_page' => $data->lastPage(), + ] + ]); + } catch (\Exception $e) { + Log::error($e->getMessage()); + return response()->json(['message' => 'Error when fetching data'], 500); + } + } + + private function response_empty_resume(){ $result = [ 'target_pad' => [ diff --git a/app/Http/Controllers/Api/RequestAssignmentController.php b/app/Http/Controllers/Api/RequestAssignmentController.php index 3474fe5..d7962a6 100644 --- a/app/Http/Controllers/Api/RequestAssignmentController.php +++ b/app/Http/Controllers/Api/RequestAssignmentController.php @@ -5,7 +5,11 @@ namespace App\Http\Controllers\Api; use App\Http\Controllers\Controller; use App\Http\Resources\RequestAssignmentResouce; use App\Models\PbgTask; +use App\Models\PbgTaskGoogleSheet; +use DB; +use Exception; use Illuminate\Http\Request; +use Log; class RequestAssignmentController extends Controller { @@ -23,6 +27,51 @@ class RequestAssignmentController extends Controller return RequestAssignmentResouce::collection($query->paginate()); } + public function report_payment_recaps(Request $request) + { + try { + // Query dengan group by kecamatan dan sum nilai_retribusi_keseluruhan_simbg + $query = PbgTaskGoogleSheet::select( + 'kecamatan', + DB::raw('SUM(nilai_retribusi_keseluruhan_simbg) as total') + ) + ->groupBy('kecamatan') + ->paginate(10); + + // Return hasil dalam JSON format + return response()->json([ + 'success' => true, + 'data' => $query + ]); + + } catch (Exception $e) { + Log::error($e->getMessage()); + return response()->json(['message' => 'Terjadi kesalahan: ' . $e->getMessage()], 500); + } + } + public function report_pbg_ptsp() + { + try { + // Query dengan group by status dan count total per status + $query = PbgTask::select( + 'status', + 'status_name', + DB::raw('COUNT(*) as total') + ) + ->groupBy('status', 'status_name') + ->paginate(10); + + // Return hasil dalam JSON format + return response()->json([ + 'success' => true, + 'data' => $query + ]); + + } catch (Exception $e) { + Log::error($e->getMessage()); + return response()->json(['message' => 'Terjadi kesalahan: ' . $e->getMessage()], 500); + } + } /** * Store a newly created resource in storage. */ diff --git a/app/Http/Controllers/Approval/ApprovalController.php b/app/Http/Controllers/Approval/ApprovalController.php new file mode 100644 index 0000000..2addfab --- /dev/null +++ b/app/Http/Controllers/Approval/ApprovalController.php @@ -0,0 +1,65 @@ + "mingcute:wechat-line", "parent_id" => null, "sort_order" => 7, - ] + ], + [ + "name" => "Approval", + "url" => "/approval", + "icon" => "mingcute:user-follow-2-line", + "parent_id" => null, + "sort_order" => 8, + ], + [ + "name" => "Tools", + "url" => "/tools", + "icon" => "mingcute:tool-line", + "parent_id" => null, + "sort_order" => 9, + ], ]; foreach ($parent_menus as $parent_menu) { @@ -100,6 +114,8 @@ class UsersRoleMenuSeeder extends Seeder $data = Menu::where('name', 'Data')->first(); $laporan = Menu::where('name', 'Laporan')->first(); $chat_bedas = Menu::where('name', 'Neng Bedas')->first(); + $approval = Menu::where('name', 'Approval')->first(); + $tools = Menu::where('name', 'Tools')->first(); // create children menu $children_menus = [ @@ -138,6 +154,13 @@ class UsersRoleMenuSeeder extends Seeder "parent_id" => $master->id, "sort_order" => 1, ], + [ + "name" => "Approval Pejabat", + "url" => "approval-list", + "icon" => null, + "parent_id" => $approval->id, + "sort_order" => 1, + ], [ "name" => "Syncronize", "url" => "settings.syncronize", @@ -222,6 +245,13 @@ class UsersRoleMenuSeeder extends Seeder "parent_id" => $data->id, "sort_order" => 8, ], + [ + "name" => "TPA TPT", + "url" => "tpa-tpt", + "icon" => null, + "parent_id" => $data->id, + "sort_order" => 9, + ], [ "name" => "Lap Pariwisata", "url" => "tourisms-report.index", @@ -236,6 +266,27 @@ class UsersRoleMenuSeeder extends Seeder "parent_id" => $laporan->id, "sort_order" => 2, ], + [ + "name" => "Rekap Pembayaran", + "url" => "payment-recaps", + "icon" => null, + "parent_id" => $laporan->id, + "sort_order" => 3, + ], + [ + "name" => "Lap Rekap Data Pembayaran", + "url" => "report-payment-recap", + "icon" => null, + "parent_id" => $laporan->id, + "sort_order" => 4, + ], + [ + "name" => "Lap PBG (PTSP)", + "url" => "report-pbg-ptsp", + "icon" => null, + "parent_id" => $laporan->id, + "sort_order" => 5, + ], [ "name" => "Chat", "url" => "main-chatbot.index", @@ -257,6 +308,13 @@ class UsersRoleMenuSeeder extends Seeder "parent_id" => Menu::where('name', 'Dashboard Potensi')->first()->id, "sort_order" => 2, ], + [ + "name" => "Undangan", + "url" => "invitations", + "icon" => null, + "parent_id" => $tools->id, + "sort_order" => 1, + ], ]; foreach ($children_menus as $child_menu) { @@ -285,6 +343,12 @@ class UsersRoleMenuSeeder extends Seeder $dalam_sistem = Menu::where('name', 'Dalam Sistem')->first(); $luar_sistem = Menu::where('name', 'Luar Sistem')->first(); $google_sheets = Menu::where('name', 'Google Sheets')->first(); + $tpa_tpt = Menu::where('name', 'TPA TPT')->first(); + $approval_pejabat = Menu::where('name', 'Approval Pejabat')->first(); + $intivations = Menu::where('name', 'Undangan')->first(); + $payment_recap = Menu::where('name', 'Rekap Pembayaran')->first(); + $report_payment_recap = Menu::where('name', 'Lap Rekap Data Pembayaran')->first(); + $report_pbg_ptsp = Menu::where('name', 'Lap PBG (PTSP)')->first(); // Superadmin gets all menus $superadmin->menus()->sync([ @@ -296,6 +360,8 @@ class UsersRoleMenuSeeder extends Seeder $data->id => ["allow_show" => true, "allow_create" => false, "allow_update" => false, "allow_destroy" => false], $laporan->id => ["allow_show" => true, "allow_create" => false, "allow_update" => false, "allow_destroy" => false], $chat_bedas->id => ["allow_show" => true, "allow_create" => false, "allow_update" => false, "allow_destroy" => false], + $approval->id => ["allow_show" => true, "allow_create" => false, "allow_update" => false, "allow_destroy" => false], + $tools->id => ["allow_show" => true, "allow_create" => false, "allow_update" => false, "allow_destroy" => false], // children $dashboard_pimpinan->id => ["allow_show" => true, "allow_create" => true, "allow_update" => true, "allow_destroy" => true], $dashboard_pbg->id => ["allow_show" => true, "allow_create" => true, "allow_update" => true, "allow_destroy" => true], @@ -319,6 +385,12 @@ class UsersRoleMenuSeeder extends Seeder $bigdata_resume->id => ["allow_show" => true, "allow_create" => true, "allow_update" => true, "allow_destroy" => true], $chatbot->id => ["allow_show" => true, "allow_create" => true, "allow_update" => true, "allow_destroy" => true], $google_sheets->id => ["allow_show" => true, "allow_create" => true, "allow_update" => true, "allow_destroy" => true], + $tpa_tpt->id => ["allow_show" => true, "allow_create" => true, "allow_update" => true, "allow_destroy" => true], + $approval_pejabat->id => ["allow_show" => true, "allow_create" => true, "allow_update" => true, "allow_destroy" => true], + $intivations->id => ["allow_show" => true, "allow_create" => true, "allow_update" => true, "allow_destroy" => true], + $payment_recap->id => ["allow_show" => true, "allow_create" => true, "allow_update" => true, "allow_destroy" => true], + $report_payment_recap->id => ["allow_show" => true, "allow_create" => true, "allow_update" => true, "allow_destroy" => true], + $report_pbg_ptsp->id => ["allow_show" => true, "allow_create" => true, "allow_update" => true, "allow_destroy" => true], ]); // Admin gets limited menus diff --git a/resources/js/approval/index.js b/resources/js/approval/index.js new file mode 100644 index 0000000..bd94558 --- /dev/null +++ b/resources/js/approval/index.js @@ -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(` +
+ + +
+ `); + }, + }, + ], + 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(); +}); diff --git a/resources/js/invitations/index.js b/resources/js/invitations/index.js new file mode 100644 index 0000000..a08bc7b --- /dev/null +++ b/resources/js/invitations/index.js @@ -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(); +}); diff --git a/resources/js/payment-recaps/index.js b/resources/js/payment-recaps/index.js new file mode 100644 index 0000000..0062233 --- /dev/null +++ b/resources/js/payment-recaps/index.js @@ -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(); +}); diff --git a/resources/js/pbg-task/index.js b/resources/js/pbg-task/index.js index 3b91531..51c0b96 100644 --- a/resources/js/pbg-task/index.js +++ b/resources/js/pbg-task/index.js @@ -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(` - No Privilege - `); + return gridjs.html( + `No Privilege` + ); } - + return gridjs.html(`
Detail + +
`); }, - } + }, ], 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) { diff --git a/resources/js/report-payment-recaps/index.js b/resources/js/report-payment-recaps/index.js new file mode 100644 index 0000000..be8100e --- /dev/null +++ b/resources/js/report-payment-recaps/index.js @@ -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(); +}); diff --git a/resources/js/report-pbg-ptsp/index.js b/resources/js/report-pbg-ptsp/index.js new file mode 100644 index 0000000..26376b1 --- /dev/null +++ b/resources/js/report-pbg-ptsp/index.js @@ -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(); +}); diff --git a/resources/js/tpa-tpt/index.js b/resources/js/tpa-tpt/index.js new file mode 100644 index 0000000..12ed634 --- /dev/null +++ b/resources/js/tpa-tpt/index.js @@ -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(); +}); diff --git a/resources/views/approval/index.blade.php b/resources/views/approval/index.blade.php new file mode 100644 index 0000000..361b16d --- /dev/null +++ b/resources/views/approval/index.blade.php @@ -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']) + + + +
+
+
+
+
+
+
+
+
+ +@endsection + +@section('scripts') +@vite(['resources/js/approval/index.js']) +@endsection \ No newline at end of file diff --git a/resources/views/invitations/index.blade.php b/resources/views/invitations/index.blade.php new file mode 100644 index 0000000..3eccee7 --- /dev/null +++ b/resources/views/invitations/index.blade.php @@ -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']) + + + +
+
+ +
+
+
+
Kirim Undangan
+ + +
+ +
+
+
+
+ + +
+
+
+
Log Undangan
+
+
+
+
+
+
+ +@endsection + +@section('scripts') +@vite(['resources/js/invitations/index.js']) +@endsection \ No newline at end of file diff --git a/resources/views/payment-recaps/index.blade.php b/resources/views/payment-recaps/index.blade.php new file mode 100644 index 0000000..60372e7 --- /dev/null +++ b/resources/views/payment-recaps/index.blade.php @@ -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']) + + + +
+
+
+
+
+
+ + +
+
+
+
+
+
+
+ + +@endsection + +@section('scripts') +@vite(['resources/js/payment-recaps/index.js']) +@endsection \ No newline at end of file diff --git a/resources/views/pbg_task/index.blade.php b/resources/views/pbg_task/index.blade.php index db1cdcd..770dec9 100644 --- a/resources/views/pbg_task/index.blade.php +++ b/resources/views/pbg_task/index.blade.php @@ -8,11 +8,16 @@ @include('layouts.partials/page-title', ['title' => 'Data', 'subtitle' => 'PBG']) + +
+ @if ($creator) Create @endif @@ -26,6 +31,109 @@
+ + + + + + + + + @endsection @section('scripts') diff --git a/resources/views/report-payment-recaps/index.blade.php b/resources/views/report-payment-recaps/index.blade.php new file mode 100644 index 0000000..ffe848b --- /dev/null +++ b/resources/views/report-payment-recaps/index.blade.php @@ -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']) + + + +
+
+
+
+
+
+
+
+
+ + +@endsection + +@section('scripts') +@vite(['resources/js/report-payment-recaps/index.js']) +@endsection \ No newline at end of file diff --git a/resources/views/report-pbg-ptsp/index.blade.php b/resources/views/report-pbg-ptsp/index.blade.php new file mode 100644 index 0000000..e562aff --- /dev/null +++ b/resources/views/report-pbg-ptsp/index.blade.php @@ -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)']) + + + +
+
+
+
+
+
+
+
+
+ +@endsection + +@section('scripts') +@vite(['resources/js/report-pbg-ptsp/index.js']) +@endsection \ No newline at end of file diff --git a/resources/views/tpa-tpt/index.blade.php b/resources/views/tpa-tpt/index.blade.php new file mode 100644 index 0000000..f6fd7ee --- /dev/null +++ b/resources/views/tpa-tpt/index.blade.php @@ -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']) + + + +
+
+
+
+
+
+
+
+
+ +@endsection + +@section('scripts') +@vite(['resources/js/tpa-tpt/index.js']) +@endsection \ No newline at end of file diff --git a/routes/api.php b/routes/api.php index 2c9d2b2..060d93c 100644 --- a/routes/api.php +++ b/routes/api.php @@ -51,6 +51,8 @@ Route::group(['middleware' => 'auth:sanctum'], function (){ // request assignments Route::apiResource('request-assignments',RequestAssignmentController::class); + Route::get('/report-payment-recaps',[RequestAssignmentController::class, 'report_payment_recaps'])->name('report-payment-recaps'); + Route::get('/report-pbg-ptsp',[RequestAssignmentController::class, 'report_pbg_ptsp'])->name('report-pbg-ptsp'); // all dashboards Route::controller(DashboardController::class)->group(function(){ @@ -141,6 +143,7 @@ Route::group(['middleware' => 'auth:sanctum'], function (){ Route::controller(BigDataResumeController::class)->group(function (){ Route::get('/bigdata-resume', 'index')->name('api.bigdata-resume'); Route::get('/bigdata-report', 'bigdata_report')->name('api.bigdata-report'); + Route::get('/payment-recaps', 'payment_recaps')->name('api.payment-recaps'); }); // task-assignments diff --git a/routes/web.php b/routes/web.php index 35dd1e3..baaa390 100755 --- a/routes/web.php +++ b/routes/web.php @@ -1,5 +1,6 @@ 'auth'], function(){ Route::get('/google-sheets/{google_sheet_id}', 'show')->name('google-sheets.show'); Route::get('/google-sheets/{google_sheet_id}/edit', 'edit')->name('google-sheets.edit'); }); + + // tpa-tpt + Route::resource('/tpa-tpt', TpatptsController::class); }); // Report @@ -132,5 +141,26 @@ Route::group(['middleware' => 'auth'], function(){ Route::controller(BigdataResumesController::class)->group(function (){ Route::get('/bigdata-resumes', 'index')->name('bigdata-resumes'); }); + Route::controller(PaymentRecapsController::class)->group(function (){ + Route::get('/payment-recaps', 'index')->name('payment-recaps'); + }); + + Route::controller(ReportPaymentRecapsController::class)->group(function (){ + Route::get('/report-payment-recaps', 'index')->name('report-payment-recaps'); + }); + + Route::controller(ReportPbgPTSPController::class)->group(function (){ + Route::get('/report-pbg-ptsp', 'index')->name('report-pbg-ptsp'); + }); + }); + + // approval + Route::group(['prefix' => '/approval'], function (){ + Route::get('/list',[ApprovalController::class, 'index'])->name('approval-list'); + }); + + // tools + Route::group(['prefix' => '/tools'], function (){ + Route::get('/invitations', [InvitationsController::class, 'index'])->name('invitations'); }); }); \ No newline at end of file