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"
{{ $title }}
+ @if ($visible_data === "true") +