From 116dc1c8c7ef6b6c08476588d3f9b9d41229becd Mon Sep 17 00:00:00 2001 From: arifal Date: Wed, 19 Feb 2025 06:15:35 +0700 Subject: [PATCH] add dashboard potential --- .../Dashboards/LackOfPotentialController.php | 13 + app/View/Components/CustomCircle.php | 26 ++ database/seeders/UsersRoleMenuSeeder.php | 9 + resources/js/dashboards/bigdata.js | 2 +- resources/js/dashboards/lack-of-potential.js | 119 +++++++++ resources/scss/components/_custom_circle.scss | 53 ++++ .../scss/dashboards/_lack-of-potential.scss | 234 ++++++++++++++++++ resources/scss/style.scss | 2 + resources/views/auth/signin.blade.php | 4 +- .../views/components/custom-circle.blade.php | 30 +++ resources/views/dashboards/bigdata.blade.php | 22 +- .../dashboards/lack_of_potential.blade.php | 108 ++++++++ routes/web.php | 2 + vite.config.js | 5 +- 14 files changed, 614 insertions(+), 15 deletions(-) create mode 100644 app/Http/Controllers/Dashboards/LackOfPotentialController.php create mode 100644 app/View/Components/CustomCircle.php create mode 100644 resources/js/dashboards/lack-of-potential.js create mode 100644 resources/scss/components/_custom_circle.scss create mode 100644 resources/scss/dashboards/_lack-of-potential.scss create mode 100644 resources/views/components/custom-circle.blade.php create mode 100644 resources/views/dashboards/lack_of_potential.blade.php diff --git a/app/Http/Controllers/Dashboards/LackOfPotentialController.php b/app/Http/Controllers/Dashboards/LackOfPotentialController.php new file mode 100644 index 0000000..d69b735 --- /dev/null +++ b/app/Http/Controllers/Dashboards/LackOfPotentialController.php @@ -0,0 +1,13 @@ + $dashboard->id, "sort_order" => 2, ], + [ + "name" => "Lack Of Potentials", + "url" => "dashboard.lack_of_potential", + "icon" => null, + "parent_id" => $dashboard->id, + "sort_order" => 3, + ], [ "name" => "Users", "url" => "users.index", @@ -205,6 +212,7 @@ class UsersRoleMenuSeeder extends Seeder $pariwisata = Menu::where('name', 'Pariwisata')->first(); $laporan_pariwisata = Menu::where('name', 'Lap Pariwisata')->first(); $umkm = Menu::where('name', 'UMKM')->first(); + $lack_of_potentials = Menu::where('name', 'Lack Of Potentials')->first(); // Superadmin gets all menus $superadmin->menus()->sync([ @@ -229,6 +237,7 @@ class UsersRoleMenuSeeder extends Seeder $pariwisata->id => ["allow_show" => true, "allow_create" => true, "allow_update" => true, "allow_destroy" => true], $laporan_pariwisata->id => ["allow_show" => true, "allow_create" => true, "allow_update" => true, "allow_destroy" => true], $umkm->id => ["allow_show" => true, "allow_create" => true, "allow_update" => true, "allow_destroy" => true], + $lack_of_potentials->id => ["allow_show" => true, "allow_create" => true, "allow_update" => true, "allow_destroy" => true], ]); // Admin gets limited menus diff --git a/resources/js/dashboards/bigdata.js b/resources/js/dashboards/bigdata.js index 3055571..d5ad8d3 100644 --- a/resources/js/dashboards/bigdata.js +++ b/resources/js/dashboards/bigdata.js @@ -118,7 +118,7 @@ class BigData { this.dataNonVerification.total ); this.percentageResultNonVerification = - this.bigTotalNonVerification <= 0 || this.bigTotalPotensi + this.bigTotalNonVerification <= 0 || this.bigTotalPotensi <= 0 ? 0 : this.bigTotalNonVerification .div(this.bigTotalPotensi) diff --git a/resources/js/dashboards/lack-of-potential.js b/resources/js/dashboards/lack-of-potential.js new file mode 100644 index 0000000..7a9af57 --- /dev/null +++ b/resources/js/dashboards/lack-of-potential.js @@ -0,0 +1,119 @@ +import Big from "big.js"; +import GlobalConfig, { addThousandSeparators } from "../global-config.js"; + +class LackOfPotential { + async init() { + this.bigTotalLackPotential = 0; + this.totalPotensi = await this.getDataTotalPotensi(2025); + this.totalTargetPAD = await this.getDataSettings("TARGET_PAD"); + + this.bigTargetPAD = new Big(this.totalTargetPAD ?? 0); + this.bigTotalPotensi = new Big(this.totalPotensi.totalData ?? 0); + this.bigTotalLackPotential = this.bigTargetPAD - this.bigTotalPotensi; + this.initChartKekuranganPotensi(); + } + async getDataTotalPotensi(year) { + try { + const response = await fetch( + `${GlobalConfig.apiHost}/api/all-task-documents?year=${year}`, + { + credentials: "include", + headers: { + Authorization: `Bearer ${ + document.querySelector("meta[name='api-token']") + .content + }`, + "Content-Type": "application/json", + }, + } + ); + + if (!response.ok) { + console.error("Network response was not ok", response); + } + + const data = await response.json(); + return { + countData: data.data.count, + totalData: data.data.total, + }; + } catch (error) { + console.error("Error fetching chart data:", error); + return null; + } + } + async getDataSettings(string_key) { + try { + const response = await fetch( + `${GlobalConfig.apiHost}/api/api-data-settings?search=${string_key}`, + { + credentials: "include", + headers: { + Authorization: `Bearer ${ + document.querySelector("meta[name='api-token']") + .content + }`, + "Content-Type": "application/json", + }, + } + ); + + if (!response.ok) { + console.error("Network response was not ok", response); + } + + const data = await response.json(); + return data.data[0].value; + } catch (error) { + console.error("Error fetching chart data:", error); + return 0; + } + } + initChartKekuranganPotensi() { + document + .querySelectorAll(".document-count.chart-lack-of-potential") + .forEach((element) => { + element.innerText = ``; + }); + document + .querySelectorAll(".document-total.chart-lack-of-potential") + .forEach((element) => { + element.innerText = `Rp.${addThousandSeparators( + this.bigTotalLackPotential.toString() + )}`; + }); + document + .querySelectorAll(".small-percentage.chart-lack-of-potential") + .forEach((element) => { + element.innerText = ``; + }); + } +} +document.addEventListener("DOMContentLoaded", async function (e) { + await new LackOfPotential().init(); +}); + +function resizeDashboard() { + let targetElement = document.getElementById("lack-of-potential-wrapper"); + let dashboardElement = document.getElementById( + "lack-of-potential-fixed-container" + ); + + let targetWidth = targetElement.offsetWidth; + let dashboardWidth = 1400; + + let scaleFactor = (targetWidth / dashboardWidth).toFixed(2); + + // Prevent scaling beyond 1 (100%) to avoid overflow + scaleFactor = Math.min(scaleFactor, 1); + + dashboardElement.style.transformOrigin = "left top"; + dashboardElement.style.transition = "transform 0.2s ease-in-out"; + dashboardElement.style.transform = `scale(${scaleFactor})`; + + // Ensure horizontal scrolling is allowed if necessary + document.body.style.overflowX = "auto"; +} + +window.addEventListener("load", resizeDashboard); +window.addEventListener("resize", resizeDashboard); diff --git a/resources/scss/components/_custom_circle.scss b/resources/scss/components/_custom_circle.scss new file mode 100644 index 0000000..8a8502e --- /dev/null +++ b/resources/scss/components/_custom_circle.scss @@ -0,0 +1,53 @@ +// +// custom_circle.scss +// + +.custom-circle-wrapper { + width: 100px; // Default width + height: 100px; // Default height + border: 4px solid white; + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + background-color: rgb(1, 44, 124); + box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); /* Efek bayangan */ + text-align: center; + + &.large { + width: 150px; + height: 150px; + } + + &.small { + width: 95px; + height: 95px; + } +} + +.custom-circle-content { + display: flex; + flex-direction: column; + align-items: center; +} + +.custom-circle-text { + font-size: 14px; + font-weight: bold; + color: white; + padding: 0; + margin: 0; +} + +.custom-circle-data { + font-size: 12px; + color: white; + background-color: #f0195b; + padding: 0 5px; + border-radius: 3px; +} + +.custom-circle-data-type { + font-size: 12px; + color: white; +} diff --git a/resources/scss/dashboards/_lack-of-potential.scss b/resources/scss/dashboards/_lack-of-potential.scss new file mode 100644 index 0000000..03c71bd --- /dev/null +++ b/resources/scss/dashboards/_lack-of-potential.scss @@ -0,0 +1,234 @@ +// +// lack-of-potential.scss +// + +.square { + height: 100px; + width: 100px; + position: absolute; + z-index: -1; +} + +.dia-top-left-bottom-right:after { + content: ""; + width: 100%; + height: 100%; + position: absolute; + + top: 0; + left: 0; + background: linear-gradient( + to top right, + transparent calc(50% - 2px), + black, + transparent calc(50% + 2px) + ); +} + +.dia-top-right-bottom-left:after { + content: ""; + width: 100%; + height: 100%; + position: absolute; + top: 0; + left: 0; + background: linear-gradient( + to top left, + transparent calc(50% - 2px), + black, + transparent calc(50% + 2px) + ); +} + +.lack-of-potential-wrapper { + background-image: url("/public/images/bg-dashboard.jpg"); + background-size: cover; + background-position: center; + background-color: rgba(255, 255, 255, 0.7); + max-width: 100vw; +} + +.lack-of-potential-wrapper::before { + content: ""; + position: absolute; + pointer-events: none; /* Prevents the overlay from blocking interaction */ + top: 0; + left: 0; + width: 100%; + height: 100%; + background-color: rgba(255, 255, 255, 0.7); +} +// #lack-of-potential-fixed-container { +// min-width: 1110px; +// max-width: unset; /* Allow it to grow if needed */ +// } + +// @media (max-width: 768px) { +// #lack-of-potential-fixed-container { +// transform: scale(0.8); /* Adjust the scale as needed */ +// } +// } + +// line degrees +.line { + background-color: black; + position: absolute; + height: 3px; +} +.home-to-non-usaha { + width: 100px; + top: 13%; + left: 38%; + transform: rotate(90deg); +} +.restoran-to-bapenda { + width: 110px; + top: 14%; + left: 60%; + transform: rotate(40deg); +} +.pbb-to-bapenda { + width: 80px; + top: 21%; + left: 80%; +} +.reklame-to-bapenda { + width: 120px; + left: 75%; + top: 30%; + transform: rotateZ(142deg); +} +.non-usaha-to-bapenda { + width: 116px; + left: 18%; + top: 33%; + transform: rotateZ(124deg); +} +.non-usaha-to-pdam { + width: 100px; + left: 38%; + top: 34%; + transform: rotateZ(90deg); +} +.non-usaha-to-kecamatan { + width: 140px; + left: 55%; + top: 33%; + transform: rotateZ(237deg); +} +.bapenda-to-usaha { + width: 114px; + left: 18%; + top: 49%; + transform: rotateZ(56deg); +} +.pdam-to-usaha { + width: 88px; + left: 39%; + top: 49%; + transform: rotateZ(90deg); +} +.kecamatan-to-usaha { + width: 118px; + left: 56%; + top: 50%; + transform: rotateZ(117deg); +} +.usaha-to-villa { + width: 100px; + left: 10%; + top: 63%; + transform: rotateZ(143deg); +} +.usaha-to-pabrik { + width: 150px; + left: 15%; + top: 70%; + transform: rotateZ(143deg); +} +.usaha-to-pariwisata { + width: 150px; + left: 43%; + top: 70%; + transform: rotateZ(38deg); +} +.usaha-to-protocol { + width: 106px; + left: 36%; + top: 71%; + transform: rotateZ(86deg); +} +.pariwisata-to-disbudpar { + width: 86px; + left: 54%; + top: 83%; + transform: rotateZ(150deg); +} +.non-usaha-to-wasdal { + width: 300px; + left: -32%; + top: 34%; + transform: rotateZ(226deg); +} +.usaha-to-wasdal { + width: 300px; + left: -34%; + top: 50%; + transform: rotateZ(129deg); +} +.wasdal-to-upt { + width: 155px; + left: 3%; + top: -67%; + transform: rotateZ(127deg); +} +.wasdal-to-satpol { + width: 155px; + left: 19%; + top: -52%; + transform: rotateZ(76deg); +} +.wasdal-to-kejari { + width: 182px; + left: 25%; + top: -55%; + transform: rotateZ(51deg); +} +.wasdal-to-tni { + width: 260px; + left: 29%; + top: -62%; + transform: rotateZ(30deg); +} +.wasdal-to-potential { + width: 50px; + left: 28%; + top: 41%; +} +.potential-to-tata-ruang { + width: 50px; + left: 72%; + top: 41%; +} +.tata-ruang-to-non-usaha { + width: 220px; + left: 0%; + top: 30%; + transform: rotateZ(144deg); +} +.tata-ruang-to-usaha { + width: 280px; + left: 0%; + top: 52%; + transform: rotateZ(224deg); +} +.tata-ruang-to-peta { + width: 122px; + left: 8%; + top: 41%; +} +.peta-to-tapak { + width: 30px; + left: 47%; + top: 41%; +} diff --git a/resources/scss/style.scss b/resources/scss/style.scss index a0887fe..c70e166 100755 --- a/resources/scss/style.scss +++ b/resources/scss/style.scss @@ -45,6 +45,8 @@ @import "components/tooltip"; @import "components/widgets"; @import "components/circle"; +@import "components/custom_circle"; +@import "dashboards/lack-of-potential"; // Plugin @import "plugins/simplebar"; diff --git a/resources/views/auth/signin.blade.php b/resources/views/auth/signin.blade.php index 2e6be3b..e2d4781 100755 --- a/resources/views/auth/signin.blade.php +++ b/resources/views/auth/signin.blade.php @@ -36,10 +36,10 @@ class="authentication-bg"
- +
- +
diff --git a/resources/views/components/custom-circle.blade.php b/resources/views/components/custom-circle.blade.php new file mode 100644 index 0000000..e735c37 --- /dev/null +++ b/resources/views/components/custom-circle.blade.php @@ -0,0 +1,30 @@ +@props(['title' => 'title component', 'visible_data' => false, 'data' => 'data text', 'visible_data_type' => false, +'data_type' => '','style' => '', 'size' => '', 'line' => []]) + +@section('css') +@vite(['resources/scss/components/_custom_circle.scss']) +@endsection + +
+
+

{{ $title }}

+ @if ($visible_data === "true") +
{{ $data }}
+ @endif + @if ($visible_data_type === "true") +
{{ $data_type }}
+ @endif + @if (!empty($lines)) + + @foreach ($lines as $line) + + @endforeach + + @endif +
+
\ No newline at end of file diff --git a/resources/views/dashboards/bigdata.blade.php b/resources/views/dashboards/bigdata.blade.php index 9950aaf..96da62d 100644 --- a/resources/views/dashboards/bigdata.blade.php +++ b/resources/views/dashboards/bigdata.blade.php @@ -33,7 +33,7 @@
@component('components.circle', [ 'document_title' => 'Kekurangan Potensi', - 'document_color' => '#911701', + 'document_color' => '#ff5757', 'document_type' => '', 'document_id' => 'chart-kekurangan-potensi', 'visible_small_circle' => true, @@ -43,7 +43,7 @@ @component('components.circle', [ 'document_title' => 'Target PAD 2024', - 'document_color' => '#020e42', + 'document_color' => '#204f6b', 'document_type' => '', 'document_id' => 'chart-target-pad', 'visible_small_circle' => true, @@ -61,7 +61,7 @@ @component('components.circle', [ 'document_title' => 'Total Potensi Berkas', - 'document_color' => '#02acfa', + 'document_color' => '#0097b3', 'document_type' => 'Pemohon', 'document_id' => 'chart-total-potensi', 'visible_small_circle' => true, @@ -77,7 +77,7 @@ @component('components.circle', [ 'document_title' => 'Perkiraan Potensi PBG Dari Tata Ruang', - 'document_color' => '#bf04bc', + 'document_color' => '#ed9d2e', 'document_type' => '', 'document_id' => 'chart-potensi-tata-ruang', 'visible_small_circle' => true, @@ -90,7 +90,7 @@ @component('components.circle', [ 'document_title' => 'Non Usaha', - 'document_color' => '#028399', + 'document_color' => '#399787', 'document_type' => 'Berkas', 'document_id' => 'chart-non-business', 'visible_small_circle' => true, @@ -100,7 +100,7 @@ @component('components.circle', [ 'document_title' => 'Usaha', - 'document_color' => '#616b7d', + 'document_color' => '#5e7c89', 'document_type' => 'Berkas', 'document_id' => 'chart-business', 'visible_small_circle' => true, @@ -110,7 +110,7 @@ @component('components.circle', [ 'document_title' => 'Berkas Terverifikasi', - 'document_color' => '#0561f5', + 'document_color' => '#5170ff', 'document_type' => 'Berkas', 'document_id' => 'chart-berkas-terverifikasi', 'visible_small_circle' => true, @@ -126,7 +126,7 @@ @component('components.circle', [ 'document_title' => 'Berkas Belum Terverifikasi', - 'document_color' => '#b973ff', + 'document_color' => '#5170ff', 'document_type' => 'Berkas', 'document_id' => 'chart-berkas-belum-terverifikasi', 'visible_small_circle' => true, @@ -143,7 +143,7 @@ @component('components.circle',[ 'document_title' => 'Realisasi Terbit PBG', - 'document_color' => '#09ab5a', + 'document_color' => '#8cc540', 'document_type' => 'Berkas', 'document_id' => 'chart-realisasi-tebit-pbg', 'visible_small_circle' => true, @@ -156,7 +156,7 @@ @component('components.circle',[ 'document_title' => 'Menunggu Klik DPMPTSP', - 'document_color' => '#0294ad', + 'document_color' => '#00bf61', 'document_type' => 'Berkas', 'document_id' => 'chart-menunggu-klik-dpmptsp', 'visible_small_circle' => true, @@ -169,7 +169,7 @@ @component('components.circle',[ 'document_title' => 'Berproses Di Dinas Teknis', - 'document_color' => '#422519', + 'document_color' => '#737373', 'document_type' => 'Berkas', 'document_id' => 'chart-proses-dinas-teknis', 'visible_small_circle' => true, diff --git a/resources/views/dashboards/lack_of_potential.blade.php b/resources/views/dashboards/lack_of_potential.blade.php new file mode 100644 index 0000000..4094af2 --- /dev/null +++ b/resources/views/dashboards/lack_of_potential.blade.php @@ -0,0 +1,108 @@ +@extends('layouts.vertical', ['subtitle' => 'Dashboards']) + +@section('css') +@vite(['resources/scss/dashboards/_lack-of-potential.scss']) +@endsection + +@section('content') +@include('layouts.partials.page-title', ['title' => 'Dashboards', 'subtitle' => 'Lack Of Potential']) + +
+
+
+

+ ANALISA BIG DATA MELALUI APLIKASI SIBEDAS PBG +

+
+
+
+
+
+
+ +
+ +
+ +
+
+ +
+
+
+ + + + +
+ +
+
+
+
+ + + +
+ +
+ + + + + + + +
+ +
+ + +
+ @component('components.circle', [ + 'document_title' => 'Kekurangan Potensi', + 'document_color' => '#ff5757', + 'document_type' => '', + 'document_id' => 'chart-lack-of-potential', + 'visible_small_circle' => false, + 'style' => 'margin-left:180px;top:-20px;' + ]) + @endcomponent + + + +
+ +
+ + + +
+ + + +
+ + + + +
+ + + +
+ + +
+
+
+ + +
+
+@endsection + +@section('scripts') +@vite(['resources/js/dashboards/lack-of-potential.js']) +@endsection + diff --git a/routes/web.php b/routes/web.php index 98188ff..2ae134c 100755 --- a/routes/web.php +++ b/routes/web.php @@ -1,6 +1,7 @@ 'auth'], function(){ Route::group(['prefix' => '/dashboards'], function(){ Route::get('/bigdata', [BigDataController::class, 'index'])->name('dashboard.home'); Route::get('/dashboard-pbg', [BigDataController::class, 'pbg'])->name('dashboard.pbg'); + Route::get('/lack-of-potential', [LackOfPotentialController::class, 'lack_of_potential'])->name('dashboard.lack_of_potential'); }); // settings diff --git a/vite.config.js b/vite.config.js index 0b6df94..6e3d5ea 100755 --- a/vite.config.js +++ b/vite.config.js @@ -49,11 +49,14 @@ export default defineConfig({ "resources/js/data/advertisements/form-upload.js", //js-additional - "resources/js/dashboards/bigdata.js", "resources/js/settings/syncronize/syncronize.js", "resources/js/pbg-task/index.js", "resources/js/settings/general/general-settings.js", "resources/js/tables/common-table.js", + + // dashboards + "resources/js/dashboards/bigdata.js", + "resources/js/dashboards/lack-of-potential.js", // roles "resources/js/roles/index.js", "resources/js/roles/create.js",