diff --git a/app/Http/Controllers/Api/BigDataResumeController.php b/app/Http/Controllers/Api/BigDataResumeController.php index 88c2391..1b89679 100644 --- a/app/Http/Controllers/Api/BigDataResumeController.php +++ b/app/Http/Controllers/Api/BigDataResumeController.php @@ -13,12 +13,23 @@ class BigDataResumeController extends Controller /** * Display a listing of the resource. */ - public function index() + public function index(Request $request) { try{ - $big_data_resume = BigdataResume::latest()->first(); - if(!$big_data_resume){ - return response()->json(['message' => 'No Big Data resume found']); + $filterDate = $request->get("filterByDate"); + + // If filterByDate is "latest" or empty, get the most recent record + if (!$filterDate || $filterDate === "latest") { + $big_data_resume = BigdataResume::latest()->first(); + } else { + // Filter by specific date + $big_data_resume = BigdataResume::whereDate('created_at', $filterDate) + ->orderBy('id', 'desc') + ->first(); + + if (!$big_data_resume) { + return $this->response_empty_resume(); + } } $data_settings = DataSetting::all(); @@ -168,4 +179,63 @@ class BigDataResumeController extends Controller { // } + + private function response_empty_resume(){ + $result = [ + 'target_pad' => [ + 'sum' => 0, + 'percentage' => 100, + ], + 'tata_ruang' => [ + 'sum' => 0, + 'percentage' => 0, + ], + 'kekurangan_potensi' => [ + 'sum' => 0, + 'percentage' => 0 + ], + 'total_potensi' => [ + 'sum' => 0, + 'count' => 0, + 'percentage' => 0 + ], + 'verified_document' => [ + 'sum' => 0, + 'count' => 0, + 'percentage' => 0 + ], + 'non_verified_document' => [ + 'sum' => 0, + 'count' => 0, + 'percentage' => 0 + ], + 'business_document' => [ + 'sum' => 0, + 'count' => 0, + 'percentage' => 0 + ], + 'non_business_document' => [ + 'sum' => 0, + 'count' => 0, + 'percentage' => 0 + ], + 'realisasi_terbit' => [ + 'sum' => 0, + 'count' => 0, + 'percentage' => 0 + ], + 'menunggu_klik_dpmptsp' => [ + 'sum' => 0, + 'count' => 0, + 'percentage' => 0 + ], + 'proses_dinas_teknis' => [ + 'sum' => 0, + 'count' => 0, + 'percentage' => 0 + ] + ]; + + return response()->json($result); + } } diff --git a/app/Services/ServiceSIMBG.php b/app/Services/ServiceSIMBG.php index 212d10d..64bc2dc 100644 --- a/app/Services/ServiceSIMBG.php +++ b/app/Services/ServiceSIMBG.php @@ -230,18 +230,17 @@ class ServiceSIMBG } } - $uuids = array_column($tasksCollective, 'uuid'); - - $this->syncIndexIntegration($uuids, $token); - PbgTask::upsert($tasksCollective, ['uuid'], [ 'name', 'owner_name', 'application_type', 'application_type_name', 'condition', 'registration_number', 'document_number', 'address', 'status', 'status_name', 'slf_status', 'slf_status_name', 'function_type', 'consultation_type', 'due_date', 'land_certificate_phase', 'task_created_at', 'updated_at' ]); + + $uuids = array_column($tasksCollective, 'uuid'); + $this->syncIndexIntegration($uuids, $token); } - + $importDatasource->update([ 'status' => ImportDatasourceStatus::Success->value, 'message' => "Successfully processed: $savedCount, Failed: $failedCount" @@ -336,5 +335,4 @@ class ServiceSIMBG } } -} - +} \ No newline at end of file diff --git a/resources/js/app.js b/resources/js/app.js index 5ce79bd..f44fffc 100755 --- a/resources/js/app.js +++ b/resources/js/app.js @@ -2,6 +2,30 @@ import bootstrap from "bootstrap/dist/js/bootstrap"; window.bootstrap = bootstrap; import "iconify-icon"; import "simplebar/dist/simplebar"; +// import flatpickr from "flatpickr"; +// import "flatpickr/dist/flatpickr.min.css"; + +// class InitDatePicker { +// constructor(selector = ".datepicker") { +// this.selector = selector; +// } +// init() { +// const elements = document.querySelectorAll(this.selector); +// if (elements.length === 0) return; // Skip if no elements found + +// const today = new Date(); +// const minYear = today.getFullYear() - 5; + +// elements.forEach((element) => { +// flatpickr(element, { +// enableTime: false, +// dateFormat: "Y-m-d", +// minDate: `${minYear}-01-01`, +// maxDate: today, +// }); +// }); +// } +// } class Components { initBootstrapComponents() { @@ -107,6 +131,7 @@ class FormValidation { } document.addEventListener("DOMContentLoaded", function (e) { new Components().init(), new FormValidation().init(); + // new InitDatePicker().init(); }); class ThemeLayout { constructor() { diff --git a/resources/js/dashboards/bigdata.js b/resources/js/dashboards/bigdata.js index b89ef0f..5c90a18 100644 --- a/resources/js/dashboards/bigdata.js +++ b/resources/js/dashboards/bigdata.js @@ -1,55 +1,30 @@ import Big from "big.js"; import GlobalConfig, { addThousandSeparators } from "../global-config.js"; -import flatpickr from "flatpickr"; -import "flatpickr/dist/flatpickr.min.css"; +import InitDatePicker from "../utils/InitDatePicker.js"; class BigData { async init() { try { - this.filterYear = new Date().getFullYear(); // Set initial year - - let yearSelect = document.querySelector("#yearPicker"); - let filterButton = document.querySelector("#btnFilterYear"); - - if (!yearSelect || !filterButton) { - console.error( - "Element #yearPicker or #btnFilterYear not found." - ); - return; - } - - // Set default value for input - yearSelect.value = this.filterYear; - - yearSelect.addEventListener("change", () => { - this.updateYear(yearSelect.value); - }); - - // Handle button click - filterButton.addEventListener("click", () => { - this.updateYear(yearSelect.value); - }); - - console.log("init filter this year", this.filterYear); + new InitDatePicker( + "#datepicker-dashboard-bigdata", + this.handleChangeDate.bind(this) + ).init(); // Load initial data - await this.updateData(this.filterYear); + this.updateData("latest"); } catch (error) { console.error("Error initializing data:", error); } } - updateYear(value) { - let inputYear = parseInt(value, 10); - if (!isNaN(inputYear)) { - this.filterYear = inputYear; - this.updateData(this.filterYear); - } else { - console.error("Invalid year input"); - } + + handleChangeDate(filterDate) { + if (!filterDate) return; + this.updateData(filterDate); } - async updateData(year) { + async updateData(filterDate) { try { - this.resumeBigData = await this.getBigDataResume(); + console.log("Filtering data for date:", filterDate); + this.resumeBigData = await this.getBigDataResume(filterDate); // this.totalTargetPAD = await this.getDataSettings("TARGET_PAD"); // this.resultDataTotal = await this.getDataTotalPotensi(year); // this.dataVerification = await this.getDataVerfication(year); @@ -178,10 +153,10 @@ class BigData { } } - async getBigDataResume() { + async getBigDataResume(filterByDate) { try { const response = await fetch( - `${GlobalConfig.apiHost}/api/bigdata-resume`, + `${GlobalConfig.apiHost}/api/bigdata-resume?filterByDate=${filterByDate}`, { credentials: "include", headers: { @@ -199,8 +174,6 @@ class BigData { } const data = await response.json(); - console.log("big data resume", JSON.stringify(data)); - console.log("big data resume", data); return data; } catch (error) { console.error("Error fetching chart data:", error); diff --git a/resources/js/dashboards/lack-of-potential.js b/resources/js/dashboards/lack-of-potential.js index 51c0751..df5d9b4 100644 --- a/resources/js/dashboards/lack-of-potential.js +++ b/resources/js/dashboards/lack-of-potential.js @@ -1,10 +1,15 @@ import Big from "big.js"; import GlobalConfig, { addThousandSeparators } from "../global-config.js"; +import InitDatePicker from "../utils/InitDatePicker.js"; class LackOfPotential { async init() { + new InitDatePicker( + "#datepicker-lack-of-potential", + this.handleChangedDate.bind(this) + ).init(); this.bigTotalLackPotential = 0; - this.totalPotensi = await this.getDataTotalPotensi(2025); + this.totalPotensi = await this.getDataTotalPotensi("latest"); this.totalTargetPAD = await this.getDataSettings("TARGET_PAD"); this.allCountData = await this.getValueDashboard(); this.reklameCount = this.allCountData.total_reklame ?? 0; @@ -12,15 +17,26 @@ class LackOfPotential { this.tataRuangCount = this.allCountData.total_tata_ruang ?? 0; this.bigTargetPAD = new Big(this.totalTargetPAD ?? 0); - this.bigTotalPotensi = new Big(this.totalPotensi.totalData ?? 0); - this.bigTotalLackPotential = this.bigTargetPAD - this.bigTotalPotensi; + this.bigTotalPotensi = new Big(this.totalPotensi.total ?? 0); + this.bigTotalLackPotential = this.bigTargetPAD.minus( + this.bigTotalPotensi + ); this.initChartKekuranganPotensi(); this.initDataValueDashboard(); } - async getDataTotalPotensi(year) { + async handleChangedDate(filterDate) { + const totalPotensi = await this.getDataTotalPotensi(filterDate); + this.bigTotalPotensi = new Big(totalPotensi.total ?? 0); + this.bigTotalLackPotential = this.bigTargetPAD.minus( + this.bigTotalPotensi + ); + + this.initChartKekuranganPotensi(); + } + async getDataTotalPotensi(filterDate) { try { const response = await fetch( - `${GlobalConfig.apiHost}/api/all-task-documents?year=${year}`, + `${GlobalConfig.apiHost}/api/bigdata-resume?filterByDate=${filterDate}`, { credentials: "include", headers: { @@ -39,8 +55,7 @@ class LackOfPotential { const data = await response.json(); return { - countData: data.data.count, - totalData: data.data.total, + total: data.total_potensi.sum, }; } catch (error) { console.error("Error fetching chart data:", error); @@ -50,7 +65,7 @@ class LackOfPotential { async getDataSettings(string_key) { try { const response = await fetch( - `${GlobalConfig.apiHost}/api/api-data-settings?search=${string_key}`, + `${GlobalConfig.apiHost}/api/data-settings?search=${string_key}`, { credentials: "include", headers: { diff --git a/resources/js/utils/InitDatePicker.js b/resources/js/utils/InitDatePicker.js new file mode 100644 index 0000000..505cc20 --- /dev/null +++ b/resources/js/utils/InitDatePicker.js @@ -0,0 +1,34 @@ +import flatpickr from "flatpickr"; +import "flatpickr/dist/flatpickr.min.css"; + +class InitDatePicker { + constructor(selector = ".datepicker", onChangeCallback = null) { + this.selector = selector; + this.onChangeCallback = onChangeCallback; + } + + init() { + const today = new Date(); + + document.querySelectorAll(this.selector).forEach((element) => { + flatpickr(element, { + enableTime: false, + dateFormat: "Y-m-d", + maxDate: today, + onChange: (selectedDates, dateStr) => { + if (this.onChangeCallback) { + this.onChangeCallback(dateStr); // Call callback with selected date + } + }, + onReady: (selectedDates, dateStr, instance) => { + // Call the callback with the default date when initialized + if (this.onChangeCallback && dateStr) { + this.onChangeCallback(dateStr); + } + }, + }); + }); + } +} + +export default InitDatePicker; diff --git a/resources/views/dashboards/bigdata.blade.php b/resources/views/dashboards/bigdata.blade.php index 96da62d..ada0f84 100644 --- a/resources/views/dashboards/bigdata.blade.php +++ b/resources/views/dashboards/bigdata.blade.php @@ -20,13 +20,8 @@