first commit

This commit is contained in:
='fauz
2025-06-29 23:00:50 +07:00
commit 3e2b383e87
42 changed files with 35941 additions and 0 deletions
+11
View File
@@ -0,0 +1,11 @@
from flask import Flask
from app.routes import main
import os
def create_app():
base_dir = os.path.abspath(os.path.dirname(__file__))
template_path = os.path.join(base_dir, '..', 'templates')
static_path = os.path.join(base_dir, '..','static')
app = Flask(__name__, template_folder=template_path, static_folder=static_path)
app.register_blueprint(main)
return app
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+1051
View File
File diff suppressed because it is too large Load Diff
+111
View File
@@ -0,0 +1,111 @@
import json
from app.apiController import apiController
def swap_latlon(coords):
# return [[lon, lat] for lat, lon in coords]
# print(coords)
# return [
# [ [lon, lat] for lat, lon in ring ]
# for ring in coords
# ]
return coords
return [
[ # Polygon
[ # Ring
[lon, lat] for lat, lon in ring
] for ring in polygon
] for polygon in coords
]
#MAP DATA
#=========================================================
def fetch_geojson(conn, level, parent_code=None):
# cur = conn.cursor()
# cur.execute(f"SELECT id, kode, nama, lat, lng, path, iso FROM {table_name} WHERE id = 1 LIMIT 1")
cur = conn.cursor()
if level == 'provinsi':
old_sql = """
SELECT id, kode, nama, lat, lng,
CONCAT(
REPEAT('[', 4 - (LENGTH(path) - LENGTH(REPLACE(path, '[', '')))),
path,
REPEAT(']', 4 - (LENGTH(path) - LENGTH(REPLACE(path, ']', ''))))
) AS path
FROM wil_provinsi
"""
cur.execute(old_sql)
elif level == 'kabupaten':
cur.execute(""" SELECT id, kode, nama,lat,lng,
CONCAT(
REPEAT('[', 4 - (LENGTH(path) - LENGTH(REPLACE(path, '[', '')))),
path,
REPEAT(']', 4 - (LENGTH(path) - LENGTH(REPLACE(path, ']', ''))))
) AS path
FROM wil_kabupatenkota WHERE provinsi_id = %s""", (parent_code,))
elif level == 'kecamatan':
cur.execute("""
SELECT id, kode, nama,lat,lng,
CONCAT(
REPEAT('[', 4 - (LENGTH(path) - LENGTH(REPLACE(path, '[', '')))),
path,
REPEAT(']', 4 - (LENGTH(path) - LENGTH(REPLACE(path, ']', ''))))
) AS path
FROM wil_kecamatan WHERE kabupatenkota_id = %s""", (parent_code,))
elif level == 'desa':
cur.execute("""
SELECT id, kode, nama, null as lat, null as lng,
CONCAT(
REPEAT('[', 4 - (LENGTH(path) - LENGTH(REPLACE(path, '[', '')))),
path,
REPEAT(']', 4 - (LENGTH(path) - LENGTH(REPLACE(path, ']', ''))))
) AS path
FROM wil_desa WHERE kecamatan_id = %s""", (parent_code,))
else:
return {"type": "FeatureCollection", "features": []}
features = []
for row in cur.fetchall():
path = row[5]
# path = swap_latlon(path)
# if not path:
# continue
# geometry = {
# "type": "Polygon",
# "coordinates": json.loads(path)
# }
#Multi poligons
try:
parsed_path = json.loads(path)
corrected_path = swap_latlon(parsed_path)
except Exception as e:
print(f"Error parsing path for row {row[0]}: {e}")
continue
if not corrected_path:
continue
geometry = {
"type": "MultiPolygon", # karena bentuk datamu seperti itu
"coordinates": corrected_path
}
feature = {
"type": "Feature",
"geometry": geometry,
"properties": {
"id": row[0],
"kode": row[1],
"nama": row[2],
"lat": row[3],
"lng": row[4]
}
}
features.append(feature)
return {
"type": "FeatureCollection",
"features": features
}
+285
View File
@@ -0,0 +1,285 @@
from flask import Blueprint, jsonify, render_template
import psycopg2
from app import mapController
from app.apiController import apiController
from app.utils import toRupiah
import mysql.connector
from contextlib import contextmanager
main = Blueprint('main', __name__)
# conn = mysql.connector.connect(
# host="192.168.91.102",
# database="dbwarehouse",
# user="dwhadmin",
# password="K3m3nd3s4@2025"
# )
@contextmanager
def get_connection():
conn = None
try:
conn = mysql.connector.connect(
# 192.168.91.102
host="localhost",
database="dbwarehouse",
# dwhadmin
user="root",
# K3m3nd3s4@2025
password="asalada123"
)
yield conn
finally:
if conn is not None and conn.is_connected():
conn.close()
#========================================================
# MAIN ROUTE
#========================================================
@main.route('/')
def index():
return render_template('index.html')
@main.route("/geojson/provinsi")
def get_provinsi():
with get_connection() as conn:
data = mapController.fetch_geojson(conn,'provinsi')
return jsonify(data)
@main.route("/geojson/kabupaten/<kode_provinsi>")
def get_kabupaten(kode_provinsi):
with get_connection() as conn:
print("PRovinsi kode: ", kode_provinsi)
data = mapController.fetch_geojson(conn,'kabupaten', kode_provinsi)
return jsonify(data)
@main.route("/geojson/kecamatan/<kode_kabupaten>")
def get_kecamatan(kode_kabupaten):
with get_connection() as conn:
data = mapController.fetch_geojson(conn,'kecamatan', kode_kabupaten)
return jsonify(data)
@main.route("/geojson/desa/<kode_kecamatan>")
def get_desa(kode_kecamatan):
with get_connection() as conn:
data = mapController.fetch_geojson(conn,'desa', kode_kecamatan)
return jsonify(data)
#=========================================================
# API DATA
#=============================================================
@main.route('/api/desa/total-dana-desa')
def get_total_dd():
with get_connection() as conn:
datas = apiController.getTotalPersentaseSerapan(conn)
data = datas['jumlah_per_m']
return jsonify(data)
@main.route("/api/desa/total-serapan-dana")
def get_total_Serapan():
with get_connection() as conn:
data = apiController.getTotalPersentaseSerapan(conn)
return jsonify(data)
@main.route('/api/geojson/<level>')
def get_geojson(level):
print(level)
allowed = ['wil_provinsi', 'wil_kabupaten_kota', 'wil_kecamatan', 'wil_kelurahan_desa']
if level not in allowed:
return jsonify({"error": "Invalid level"}), 400
geojson_data = mapController.fetch_geojson(conn,level)
return jsonify(geojson_data)
#Informasi desa per provinsi
@main.route('/api/status-provinsi/<kode_provinsi>')
def get_status_provinsi(kode_provinsi):
with get_connection() as conn:
data = apiController.getStatusProvinsi(conn,kode_provinsi)
return jsonify(data)
#informasi desa per kabupaten/kota
@main.route('/api/status-kabupatenkota/<kode_prov>/<kode_kabkota>')
def get_status_kabkota(kode_prov, kode_kabkota):
with get_connection() as conn:
data = apiController.getStatusKabkota(conn,kode_prov, kode_kabkota)
return jsonify(data)
#informasi desa per kecamatan
@main.route('/api/status-kecamatan/<kode_provinsi>/<kode_kabupatenkota>/<kode_kecamatan>')
def get_status_kecamatan(kode_provinsi, kode_kabupatenkota, kode_kecamatan):
print(kode_provinsi, kode_kabupatenkota, kode_kecamatan)
with get_connection() as conn:
data = apiController.getStatusKecamatan(conn,kode_provinsi, kode_kabupatenkota, kode_kecamatan)
data = jsonify(data)
return data
@main.route("/api/status-bumdes")
def get_status_bumdes():
with get_connection() as conn:
data = apiController.getBumdes(conn)
return jsonify(data[0])
#informasi bumdes Bersama
@main.route("/api/status-bumdes-bersama")
def get_status_bumdes_bersma():
with get_connection() as conn:
data = apiController.getBumdes(conn)
return jsonify(data[1])
#informasi pendamping
@main.route('/api/pendamping-desa')
def get_pendamping():
with get_connection() as conn:
data = apiController.getPendamping(conn)
return jsonify(data[1])
#informasi pendamping per desa
@main.route('/api/pendamping-per-desa')
def get_pendamping_perdesa():
with get_connection() as conn:
data = apiController.getPendampingPerDesa(conn)
return jsonify(data[0])
#=======================================================================
#=======================================================================
#informasi Koperasi
@main.route('/api/provinsi/koperasi/<kode_prov>')
def get_koperasi_by_provinsi(kode_prov):
with get_connection() as conn:
data = apiController.getDesaDenganAtauTanpaKopmerKab(conn, kode_prov)
return jsonify(data)
@main.route('/api/provinsi/pendamping/<kode_prov>')
def get_pendamping_per_provinsi(kode_prov):
with get_connection() as conn:
data = apiController.getPendampingPerProv(conn, kode_prov)
return jsonify(data)
#informasi bumdes per provinsi
@main.route("/api/provinsi/bumdes/<kode_provinsi>")
def get_status_bumdes_prov(kode_provinsi):
with get_connection() as conn:
data = apiController.getBumdesProv(conn,kode_provinsi)
return jsonify(data)
#informasi serapan per provinsi
@main.route("/api/provinsi/serapan/<kode_provinsi>")
def get_provinsi_serapan(kode_provinsi):
with get_connection() as conn:
data = apiController.getTotalSerapanProv(conn,kode_provinsi)
return jsonify(data)
#=======================================================================
#=======================================================================
#informasi Koperasi
@main.route('/api/kabkota/koperasi/<kode_kabkota>')
def get_koperasi_by_kabkota(kode_kabkota):
with get_connection() as conn:
data = apiController.getDesaDenganAtauTanpaKopmerKab(conn, kode_kabkota)
return jsonify(data)
@main.route('/api/kabkota/pendamping/<kode_kabkota>')
def get_pendamping_per_kabkota(kode_kabkota):
with get_connection() as conn:
data = apiController.getPendampingPerKab(conn, kode_kabkota)
return jsonify(data)
#informasi bumdes
@main.route("/api/kabkota/bumdes/<kode_kabkota>")
def get_status_bumdes_kabkota(kode_kabkota):
with get_connection() as conn:
data = apiController.getBumdesKab(conn,kode_kabkota)
return jsonify(data)
#informasi serapan
@main.route("/api/kabkota/serapan/<kode_kabkota>")
def get_kabkota_serapan(kode_kabkota):
with get_connection() as conn:
data = apiController.getTotalSerapanKab(conn,kode_kabkota)
return jsonify(data)
#=======================================================================
#=======================================================================
#informasi Koperasi
@main.route('/api/kecamatan/koperasi/<kode_kecamatan>')
def get_koperasi_by_kecamatan(kode_kecamatan):
with get_connection() as conn:
data = apiController.getDesaDenganAtauTanpaKopmerKec(conn, kode_kecamatan)
return jsonify(data)
@main.route('/api/kecamatan/pendamping/<kode_kecamatan>')
def get_pendamping_per_kecamatan(kode_kecamatan):
with get_connection() as conn:
data = apiController.getPendampingPerKec(conn, kode_kecamatan)
return jsonify(data)
#informasi bumdes
@main.route("/api/kecamatan/bumdes/<kode_kecamatan>")
def get_status_bumdes_kecamatan(kode_kecamatan):
with get_connection() as conn:
data = apiController.getBumdesKec(conn,kode_kecamatan)
return jsonify(data)
#informasi serapan
@main.route("/api/kecamatan/serapan/<kode_kecamatan>")
def get_kecamatan_serapan(kode_kecamatan):
with get_connection() as conn:
data = apiController.getTotalSerapanKec(conn,kode_kecamatan)
return jsonify(data)
#=======================================================================
#=======================================================================
#informasi Koperasi
@main.route('/api/desa/status/<kode_prov>/<kode_kabkota>/<kode_kecamatan>/<kode_desa>')
def get_status_by_desa(kode_prov, kode_kabkota, kode_kecamatan, kode_desa):
with get_connection() as conn:
data = apiController.getStatusDesaByDesa(conn, kode_prov, kode_kabkota, kode_kecamatan, kode_desa)
return jsonify(data)
@main.route('/api/desa/koperasi/<kode_desa>')
def get_koperasi_by_desa(kode_desa):
data = apiController.getDesaDenganAtauTanpaKopmerDesa(conn, kode_desa)
return jsonify(data)
@main.route('/api/desa/pendamping/<kode_desa>')
def get_pendamping_per_desa(kode_desa):
with get_connection() as conn:
data = apiController.getPendampingPerDesa(conn, kode_desa)
return jsonify(data)
#informasi bumdes
@main.route("/api/desa/bumdes/<kode_desa>")
def get_status_bumdes_desa(kode_desa):
data = apiController.getBumdesDesa(conn,kode_desa)
return jsonify(data)
#informasi serapan
@main.route("/api/desa/serapan/<kode_desa>")
def get_pdesa_serapan(kode_desa):
data = apiController.getTotalSerapanDesa(conn,kode_desa)
return jsonify(data)
#==================
# MASTER
#===============
@main.route('/app/master/provinsi')
def get_master_provinsi():
with get_connection() as conn:
data = apiController.provinsi(conn)
return data
@main.route('/api/master/kabkota')
def get_master_kabkota():
with get_connection() as conn:
data = apiController.kabkota
return jsonify(data)
@main.route('/api/master/kecamatan')
def get_master_kecamatan():
with get_connection() as conn:
data = apiController.kecamatan(conn)
return jsonify(data)
+3
View File
@@ -0,0 +1,3 @@
from babel.numbers import format_currency
def toRupiah(money):
return format_currency(money, 'IDR', locale='id_ID')
+15
View File
@@ -0,0 +1,15 @@
from app import create_app
app = create_app()
def swap_latlon(coords):
return [
[ # Polygon
[ # Ring
[lon, lat] for lat, lon in ring
] for ring in polygon
] for polygon in coords
]
if __name__ == '__main__':
app.run(debug=True, port=5000)
BIN
View File
Binary file not shown.
+1912
View File
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+331
View File
@@ -0,0 +1,331 @@
/*!
* Bootstrap Reboot v4.1.3 (https://getbootstrap.com/)
* Copyright 2011-2018 The Bootstrap Authors
* Copyright 2011-2018 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
* Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md)
*/
*,
*::before,
*::after {
box-sizing: border-box;
}
html {
font-family: sans-serif;
line-height: 1.15;
-webkit-text-size-adjust: 100%;
-ms-text-size-adjust: 100%;
-ms-overflow-style: scrollbar;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}
@-ms-viewport {
width: device-width;
}
article, aside, figcaption, figure, footer, header, hgroup, main, nav, section {
display: block;
}
body {
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
font-size: 1rem;
font-weight: 400;
line-height: 1.5;
color: #212529;
text-align: left;
background-color: #fff;
}
[tabindex="-1"]:focus {
outline: 0 !important;
}
hr {
box-sizing: content-box;
height: 0;
overflow: visible;
}
h1, h2, h3, h4, h5, h6 {
margin-top: 0;
margin-bottom: 0.5rem;
}
p {
margin-top: 0;
margin-bottom: 1rem;
}
abbr[title],
abbr[data-original-title] {
text-decoration: underline;
-webkit-text-decoration: underline dotted;
text-decoration: underline dotted;
cursor: help;
border-bottom: 0;
}
address {
margin-bottom: 1rem;
font-style: normal;
line-height: inherit;
}
ol,
ul,
dl {
margin-top: 0;
margin-bottom: 1rem;
}
ol ol,
ul ul,
ol ul,
ul ol {
margin-bottom: 0;
}
dt {
font-weight: 700;
}
dd {
margin-bottom: .5rem;
margin-left: 0;
}
blockquote {
margin: 0 0 1rem;
}
dfn {
font-style: italic;
}
b,
strong {
font-weight: bolder;
}
small {
font-size: 80%;
}
sub,
sup {
position: relative;
font-size: 75%;
line-height: 0;
vertical-align: baseline;
}
sub {
bottom: -.25em;
}
sup {
top: -.5em;
}
a {
color: #007bff;
text-decoration: none;
background-color: transparent;
-webkit-text-decoration-skip: objects;
}
a:hover {
color: #0056b3;
text-decoration: underline;
}
a:not([href]):not([tabindex]) {
color: inherit;
text-decoration: none;
}
a:not([href]):not([tabindex]):hover, a:not([href]):not([tabindex]):focus {
color: inherit;
text-decoration: none;
}
a:not([href]):not([tabindex]):focus {
outline: 0;
}
pre,
code,
kbd,
samp {
font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
font-size: 1em;
}
pre {
margin-top: 0;
margin-bottom: 1rem;
overflow: auto;
-ms-overflow-style: scrollbar;
}
figure {
margin: 0 0 1rem;
}
img {
vertical-align: middle;
border-style: none;
}
svg {
overflow: hidden;
vertical-align: middle;
}
table {
border-collapse: collapse;
}
caption {
padding-top: 0.75rem;
padding-bottom: 0.75rem;
color: #6c757d;
text-align: left;
caption-side: bottom;
}
th {
text-align: inherit;
}
label {
display: inline-block;
margin-bottom: 0.5rem;
}
button {
border-radius: 0;
}
button:focus {
outline: 1px dotted;
outline: 5px auto -webkit-focus-ring-color;
}
input,
button,
select,
optgroup,
textarea {
margin: 0;
font-family: inherit;
font-size: inherit;
line-height: inherit;
}
button,
input {
overflow: visible;
}
button,
select {
text-transform: none;
}
button,
html [type="button"],
[type="reset"],
[type="submit"] {
-webkit-appearance: button;
}
button::-moz-focus-inner,
[type="button"]::-moz-focus-inner,
[type="reset"]::-moz-focus-inner,
[type="submit"]::-moz-focus-inner {
padding: 0;
border-style: none;
}
input[type="radio"],
input[type="checkbox"] {
box-sizing: border-box;
padding: 0;
}
input[type="date"],
input[type="time"],
input[type="datetime-local"],
input[type="month"] {
-webkit-appearance: listbox;
}
textarea {
overflow: auto;
resize: vertical;
}
fieldset {
min-width: 0;
padding: 0;
margin: 0;
border: 0;
}
legend {
display: block;
width: 100%;
max-width: 100%;
padding: 0;
margin-bottom: .5rem;
font-size: 1.5rem;
line-height: inherit;
color: inherit;
white-space: normal;
}
progress {
vertical-align: baseline;
}
[type="number"]::-webkit-inner-spin-button,
[type="number"]::-webkit-outer-spin-button {
height: auto;
}
[type="search"] {
outline-offset: -2px;
-webkit-appearance: none;
}
[type="search"]::-webkit-search-cancel-button,
[type="search"]::-webkit-search-decoration {
-webkit-appearance: none;
}
::-webkit-file-upload-button {
font: inherit;
-webkit-appearance: button;
}
output {
display: inline-block;
}
summary {
display: list-item;
cursor: pointer;
}
template {
display: none;
}
[hidden] {
display: none !important;
}
/*# sourceMappingURL=bootstrap-reboot.css.map */
File diff suppressed because one or more lines are too long
+8
View File
@@ -0,0 +1,8 @@
/*!
* Bootstrap Reboot v4.1.3 (https://getbootstrap.com/)
* Copyright 2011-2018 The Bootstrap Authors
* Copyright 2011-2018 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
* Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md)
*/*,::after,::before{box-sizing:border-box}html{font-family:sans-serif;line-height:1.15;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%;-ms-overflow-style:scrollbar;-webkit-tap-highlight-color:transparent}@-ms-viewport{width:device-width}article,aside,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}body{margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-size:1rem;font-weight:400;line-height:1.5;color:#212529;text-align:left;background-color:#fff}[tabindex="-1"]:focus{outline:0!important}hr{box-sizing:content-box;height:0;overflow:visible}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem}p{margin-top:0;margin-bottom:1rem}abbr[data-original-title],abbr[title]{text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;border-bottom:0}address{margin-bottom:1rem;font-style:normal;line-height:inherit}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}dfn{font-style:italic}b,strong{font-weight:bolder}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:#007bff;text-decoration:none;background-color:transparent;-webkit-text-decoration-skip:objects}a:hover{color:#0056b3;text-decoration:underline}a:not([href]):not([tabindex]){color:inherit;text-decoration:none}a:not([href]):not([tabindex]):focus,a:not([href]):not([tabindex]):hover{color:inherit;text-decoration:none}a:not([href]):not([tabindex]):focus{outline:0}code,kbd,pre,samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;font-size:1em}pre{margin-top:0;margin-bottom:1rem;overflow:auto;-ms-overflow-style:scrollbar}figure{margin:0 0 1rem}img{vertical-align:middle;border-style:none}svg{overflow:hidden;vertical-align:middle}table{border-collapse:collapse}caption{padding-top:.75rem;padding-bottom:.75rem;color:#6c757d;text-align:left;caption-side:bottom}th{text-align:inherit}label{display:inline-block;margin-bottom:.5rem}button{border-radius:0}button:focus{outline:1px dotted;outline:5px auto -webkit-focus-ring-color}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,input{overflow:visible}button,select{text-transform:none}[type=reset],[type=submit],button,html [type=button]{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{padding:0;border-style:none}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=date],input[type=datetime-local],input[type=month],input[type=time]{-webkit-appearance:listbox}textarea{overflow:auto;resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;max-width:100%;padding:0;margin-bottom:.5rem;font-size:1.5rem;line-height:inherit;color:inherit;white-space:normal}progress{vertical-align:baseline}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:none}[type=search]::-webkit-search-cancel-button,[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}summary{display:list-item;cursor:pointer}template{display:none}[hidden]{display:none!important}
/*# sourceMappingURL=bootstrap-reboot.min.css.map */
File diff suppressed because one or more lines are too long
+9030
View File
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
+7
View File
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+595
View File
@@ -0,0 +1,595 @@
.select2-container {
box-sizing: border-box;
display: inline-block;
margin: 0;
position: relative;
vertical-align: middle;
}
.select2-container .select2-selection--single {
box-sizing: border-box;
cursor: pointer;
display: block;
height: 28px;
user-select: none;
-webkit-user-select: none;
}
.select2-container .select2-selection--single .select2-selection__rendered {
display: block;
padding-left: 8px;
padding-right: 20px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.select2-container .select2-selection--single .select2-selection__clear {
background-color: transparent;
border: none;
font-size: 1em;
}
.select2-container[dir=rtl] .select2-selection--single .select2-selection__rendered {
padding-right: 8px;
padding-left: 20px;
}
.select2-container .select2-selection--multiple {
box-sizing: border-box;
cursor: pointer;
display: block;
min-height: 32px;
user-select: none;
-webkit-user-select: none;
}
.select2-container .select2-selection--multiple .select2-selection__rendered {
display: inline;
list-style: none;
padding: 0;
}
.select2-container .select2-selection--multiple .select2-selection__clear {
background-color: transparent;
border: none;
font-size: 1em;
}
.select2-container .select2-search--inline .select2-search__field {
box-sizing: border-box;
border: none;
font-size: 100%;
margin-top: 5px;
margin-left: 5px;
padding: 0;
max-width: 100%;
resize: none;
height: 18px;
vertical-align: bottom;
font-family: sans-serif;
overflow: hidden;
word-break: keep-all;
}
.select2-container .select2-search--inline .select2-search__field::-webkit-search-cancel-button {
-webkit-appearance: none;
}
.select2-dropdown {
background-color: white;
border: 1px solid #aaa;
border-radius: 4px;
box-sizing: border-box;
display: block;
position: absolute;
left: -100000px;
width: 100%;
z-index: 1051;
}
.select2-results {
display: block;
}
.select2-results__options {
list-style: none;
margin: 0;
padding: 0;
}
.select2-results__option {
padding: 6px;
user-select: none;
-webkit-user-select: none;
}
.select2-results__option--selectable {
cursor: pointer;
}
.select2-container--open .select2-dropdown {
left: 0;
}
.select2-container--open .select2-dropdown--above {
border-bottom: none;
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
}
.select2-container--open .select2-dropdown--below {
border-top: none;
border-top-left-radius: 0;
border-top-right-radius: 0;
}
.select2-search--dropdown {
display: block;
padding: 4px;
}
.select2-search--dropdown .select2-search__field {
padding: 4px;
width: 100%;
box-sizing: border-box;
}
.select2-search--dropdown .select2-search__field::-webkit-search-cancel-button {
-webkit-appearance: none;
}
.select2-search--dropdown.select2-search--hide {
display: none;
}
.select2-close-mask {
border: 0;
margin: 0;
padding: 0;
display: block;
position: fixed;
left: 0;
top: 0;
min-height: 100%;
min-width: 100%;
height: auto;
width: auto;
opacity: 0;
z-index: 99;
background-color: #fff;
filter: alpha(opacity=0);
}
.select2-hidden-accessible {
border: 0 !important;
clip: rect(0 0 0 0) !important;
-webkit-clip-path: inset(50%) !important;
clip-path: inset(50%) !important;
height: 1px !important;
overflow: hidden !important;
padding: 0 !important;
position: absolute !important;
width: 1px !important;
white-space: nowrap !important;
}
.select2-container--default .select2-selection--single {
background-color: #fff;
border: 1px solid #aaa;
border-radius: 4px;
}
.select2-container--default .select2-selection--single .select2-selection__rendered {
color: #444;
line-height: 28px;
}
.select2-container--default .select2-selection--single .select2-selection__clear {
cursor: pointer;
float: right;
font-weight: bold;
height: 26px;
margin-right: 20px;
padding-right: 0px;
}
.select2-container--default .select2-selection--single .select2-selection__placeholder {
color: #999;
}
.select2-container--default .select2-selection--single .select2-selection__arrow {
height: 26px;
position: absolute;
top: 1px;
right: 1px;
width: 20px;
}
.select2-container--default .select2-selection--single .select2-selection__arrow b {
border-color: #888 transparent transparent transparent;
border-style: solid;
border-width: 5px 4px 0 4px;
height: 0;
left: 50%;
margin-left: -4px;
margin-top: -2px;
position: absolute;
top: 50%;
width: 0;
}
.select2-container--default[dir=rtl] .select2-selection--single .select2-selection__clear {
float: left;
}
.select2-container--default[dir=rtl] .select2-selection--single .select2-selection__arrow {
left: 1px;
right: auto;
}
.select2-container--default.select2-container--disabled .select2-selection--single {
background-color: #eee;
cursor: default;
}
.select2-container--default.select2-container--disabled .select2-selection--single .select2-selection__clear {
display: none;
}
.select2-container--default.select2-container--open .select2-selection--single .select2-selection__arrow b {
border-color: transparent transparent #888 transparent;
border-width: 0 4px 5px 4px;
}
.select2-container--default .select2-selection--multiple {
background-color: white;
border: 1px solid #aaa;
border-radius: 4px;
cursor: text;
padding-bottom: 5px;
padding-right: 5px;
position: relative;
}
.select2-container--default .select2-selection--multiple.select2-selection--clearable {
padding-right: 25px;
}
.select2-container--default .select2-selection--multiple .select2-selection__clear {
cursor: pointer;
font-weight: bold;
height: 20px;
margin-right: 10px;
margin-top: 5px;
position: absolute;
right: 0;
padding: 1px;
}
.select2-container--default .select2-selection--multiple .select2-selection__choice {
background-color: #e4e4e4;
border: 1px solid #aaa;
border-radius: 4px;
box-sizing: border-box;
display: inline-block;
margin-left: 5px;
margin-top: 5px;
padding: 0;
padding-left: 20px;
position: relative;
max-width: 100%;
overflow: hidden;
text-overflow: ellipsis;
vertical-align: bottom;
white-space: nowrap;
}
.select2-container--default .select2-selection--multiple .select2-selection__choice__display {
cursor: default;
padding-left: 2px;
padding-right: 5px;
}
.select2-container--default .select2-selection--multiple .select2-selection__choice__remove {
background-color: transparent;
border: none;
border-right: 1px solid #aaa;
border-top-left-radius: 4px;
border-bottom-left-radius: 4px;
color: #999;
cursor: pointer;
font-size: 1em;
font-weight: bold;
padding: 0 4px;
position: absolute;
left: 0;
top: 0;
}
.select2-container--default .select2-selection--multiple .select2-selection__choice__remove:hover, .select2-container--default .select2-selection--multiple .select2-selection__choice__remove:focus {
background-color: #f1f1f1;
color: #333;
outline: none;
}
.select2-container--default[dir=rtl] .select2-selection--multiple .select2-selection__choice {
margin-left: 5px;
margin-right: auto;
}
.select2-container--default[dir=rtl] .select2-selection--multiple .select2-selection__choice__display {
padding-left: 5px;
padding-right: 2px;
}
.select2-container--default[dir=rtl] .select2-selection--multiple .select2-selection__choice__remove {
border-left: 1px solid #aaa;
border-right: none;
border-top-left-radius: 0;
border-bottom-left-radius: 0;
border-top-right-radius: 4px;
border-bottom-right-radius: 4px;
}
.select2-container--default[dir=rtl] .select2-selection--multiple .select2-selection__clear {
float: left;
margin-left: 10px;
margin-right: auto;
}
.select2-container--default.select2-container--focus .select2-selection--multiple {
border: solid black 1px;
outline: 0;
}
.select2-container--default.select2-container--disabled .select2-selection--multiple {
background-color: #eee;
cursor: default;
}
.select2-container--default.select2-container--disabled .select2-selection__choice__remove {
display: none;
}
.select2-container--default.select2-container--open.select2-container--above .select2-selection--single, .select2-container--default.select2-container--open.select2-container--above .select2-selection--multiple {
border-top-left-radius: 0;
border-top-right-radius: 0;
}
.select2-container--default.select2-container--open.select2-container--below .select2-selection--single, .select2-container--default.select2-container--open.select2-container--below .select2-selection--multiple {
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
}
.select2-container--default .select2-search--dropdown .select2-search__field {
border: 1px solid #aaa;
}
.select2-container--default .select2-search--inline .select2-search__field {
background: transparent;
border: none;
outline: 0;
box-shadow: none;
-webkit-appearance: textfield;
}
.select2-container--default .select2-results > .select2-results__options {
max-height: 200px;
overflow-y: auto;
}
.select2-container--default .select2-results__option .select2-results__option {
padding-left: 1em;
}
.select2-container--default .select2-results__option .select2-results__option .select2-results__group {
padding-left: 0;
}
.select2-container--default .select2-results__option .select2-results__option .select2-results__option {
margin-left: -1em;
padding-left: 2em;
}
.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option {
margin-left: -2em;
padding-left: 3em;
}
.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option {
margin-left: -3em;
padding-left: 4em;
}
.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option {
margin-left: -4em;
padding-left: 5em;
}
.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option {
margin-left: -5em;
padding-left: 6em;
}
.select2-container--default .select2-results__option--group {
padding: 0;
}
.select2-container--default .select2-results__option--disabled {
color: #999;
}
.select2-container--default .select2-results__option--selected {
background-color: #ddd;
}
.select2-container--default .select2-results__option--highlighted.select2-results__option--selectable {
background-color: #5897fb;
color: white;
}
.select2-container--default .select2-results__group {
cursor: default;
display: block;
padding: 6px;
}
.select2-container--classic .select2-selection--single {
background-color: #f7f7f7;
border: 1px solid #aaa;
border-radius: 4px;
outline: 0;
background-image: -webkit-linear-gradient(top, white 50%, #eeeeee 100%);
background-image: -o-linear-gradient(top, white 50%, #eeeeee 100%);
background-image: linear-gradient(to bottom, white 50%, #eeeeee 100%);
background-repeat: repeat-x;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr="#FFFFFFFF", endColorstr="#FFEEEEEE", GradientType=0);
}
.select2-container--classic .select2-selection--single:focus {
border: 1px solid #5897fb;
}
.select2-container--classic .select2-selection--single .select2-selection__rendered {
color: #444;
line-height: 28px;
}
.select2-container--classic .select2-selection--single .select2-selection__clear {
cursor: pointer;
float: right;
font-weight: bold;
height: 26px;
margin-right: 20px;
}
.select2-container--classic .select2-selection--single .select2-selection__placeholder {
color: #999;
}
.select2-container--classic .select2-selection--single .select2-selection__arrow {
background-color: #ddd;
border: none;
border-left: 1px solid #aaa;
border-top-right-radius: 4px;
border-bottom-right-radius: 4px;
height: 26px;
position: absolute;
top: 1px;
right: 1px;
width: 20px;
background-image: -webkit-linear-gradient(top, #eeeeee 50%, #cccccc 100%);
background-image: -o-linear-gradient(top, #eeeeee 50%, #cccccc 100%);
background-image: linear-gradient(to bottom, #eeeeee 50%, #cccccc 100%);
background-repeat: repeat-x;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr="#FFEEEEEE", endColorstr="#FFCCCCCC", GradientType=0);
}
.select2-container--classic .select2-selection--single .select2-selection__arrow b {
border-color: #888 transparent transparent transparent;
border-style: solid;
border-width: 5px 4px 0 4px;
height: 0;
left: 50%;
margin-left: -4px;
margin-top: -2px;
position: absolute;
top: 50%;
width: 0;
}
.select2-container--classic[dir=rtl] .select2-selection--single .select2-selection__clear {
float: left;
}
.select2-container--classic[dir=rtl] .select2-selection--single .select2-selection__arrow {
border: none;
border-right: 1px solid #aaa;
border-radius: 0;
border-top-left-radius: 4px;
border-bottom-left-radius: 4px;
left: 1px;
right: auto;
}
.select2-container--classic.select2-container--open .select2-selection--single {
border: 1px solid #5897fb;
}
.select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow {
background: transparent;
border: none;
}
.select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow b {
border-color: transparent transparent #888 transparent;
border-width: 0 4px 5px 4px;
}
.select2-container--classic.select2-container--open.select2-container--above .select2-selection--single {
border-top: none;
border-top-left-radius: 0;
border-top-right-radius: 0;
background-image: -webkit-linear-gradient(top, white 0%, #eeeeee 50%);
background-image: -o-linear-gradient(top, white 0%, #eeeeee 50%);
background-image: linear-gradient(to bottom, white 0%, #eeeeee 50%);
background-repeat: repeat-x;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr="#FFFFFFFF", endColorstr="#FFEEEEEE", GradientType=0);
}
.select2-container--classic.select2-container--open.select2-container--below .select2-selection--single {
border-bottom: none;
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
background-image: -webkit-linear-gradient(top, #eeeeee 50%, white 100%);
background-image: -o-linear-gradient(top, #eeeeee 50%, white 100%);
background-image: linear-gradient(to bottom, #eeeeee 50%, white 100%);
background-repeat: repeat-x;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr="#FFEEEEEE", endColorstr="#FFFFFFFF", GradientType=0);
}
.select2-container--classic .select2-selection--multiple {
background-color: white;
border: 1px solid #aaa;
border-radius: 4px;
cursor: text;
outline: 0;
padding-bottom: 5px;
padding-right: 5px;
}
.select2-container--classic .select2-selection--multiple:focus {
border: 1px solid #5897fb;
}
.select2-container--classic .select2-selection--multiple .select2-selection__clear {
display: none;
}
.select2-container--classic .select2-selection--multiple .select2-selection__choice {
background-color: #e4e4e4;
border: 1px solid #aaa;
border-radius: 4px;
display: inline-block;
margin-left: 5px;
margin-top: 5px;
padding: 0;
}
.select2-container--classic .select2-selection--multiple .select2-selection__choice__display {
cursor: default;
padding-left: 2px;
padding-right: 5px;
}
.select2-container--classic .select2-selection--multiple .select2-selection__choice__remove {
background-color: transparent;
border: none;
border-top-left-radius: 4px;
border-bottom-left-radius: 4px;
color: #888;
cursor: pointer;
font-size: 1em;
font-weight: bold;
padding: 0 4px;
}
.select2-container--classic .select2-selection--multiple .select2-selection__choice__remove:hover {
color: #555;
outline: none;
}
.select2-container--classic[dir=rtl] .select2-selection--multiple .select2-selection__choice {
margin-left: 5px;
margin-right: auto;
}
.select2-container--classic[dir=rtl] .select2-selection--multiple .select2-selection__choice__display {
padding-left: 5px;
padding-right: 2px;
}
.select2-container--classic[dir=rtl] .select2-selection--multiple .select2-selection__choice__remove {
border-top-left-radius: 0;
border-bottom-left-radius: 0;
border-top-right-radius: 4px;
border-bottom-right-radius: 4px;
}
.select2-container--classic.select2-container--open .select2-selection--multiple {
border: 1px solid #5897fb;
}
.select2-container--classic.select2-container--open.select2-container--above .select2-selection--multiple {
border-top: none;
border-top-left-radius: 0;
border-top-right-radius: 0;
}
.select2-container--classic.select2-container--open.select2-container--below .select2-selection--multiple {
border-bottom: none;
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
}
.select2-container--classic .select2-search--dropdown .select2-search__field {
border: 1px solid #aaa;
outline: 0;
}
.select2-container--classic .select2-search--inline .select2-search__field {
outline: 0;
box-shadow: none;
}
.select2-container--classic .select2-dropdown {
background-color: white;
border: 1px solid transparent;
}
.select2-container--classic .select2-dropdown--above {
border-bottom: none;
}
.select2-container--classic .select2-dropdown--below {
border-top: none;
}
.select2-container--classic .select2-results > .select2-results__options {
max-height: 200px;
overflow-y: auto;
}
.select2-container--classic .select2-results__option--group {
padding: 0;
}
.select2-container--classic .select2-results__option--disabled {
color: grey;
}
.select2-container--classic .select2-results__option--highlighted.select2-results__option--selectable {
background-color: #3875d7;
color: white;
}
.select2-container--classic .select2-results__group {
cursor: default;
display: block;
padding: 6px;
}
.select2-container--classic.select2-container--open .select2-dropdown {
border-color: #5897fb;
}
+1
View File
File diff suppressed because one or more lines are too long
+6461
View File
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+3944
View File
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
+7
View File
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+10716
View File
File diff suppressed because it is too large Load Diff
+2
View File
File diff suppressed because one or more lines are too long
+2
View File
File diff suppressed because one or more lines are too long
+196
View File
@@ -0,0 +1,196 @@
/* responsive.css*/
@media screen and (max-width: 950px) {
.nav-img {
height: 25px;
}
.nav-option {
gap: 30px;
}
.nav-option h3 {
font-size: 15px;
}
.report-topic-heading,
.item1,
.items {
width: 800px;
}
}
@media screen and (max-width: 850px) {
.nav-img {
height: 30px;
}
.nav-option {
gap: 30px;
}
.nav-option h3 {
font-size: 20px;
}
.report-topic-heading,
.item1,
.items {
width: 700px;
}
.navcontainer {
width: 100vw;
position: absolute;
transition: all 0.6s ease-in-out;
top: 0;
left: -100vw;
}
.nav {
width: 100%;
position: absolute;
}
.navclose {
left: 00px;
}
.searchbar {
display: none;
}
.main {
padding: 40px 30px 30px 30px;
}
.searchbar2 {
width: 100%;
display: flex;
margin: 0 0 40px 0;
justify-content: center;
}
.searchbar2 input {
width: 250px;
height: 42px;
border-radius: 50px 0 0 50px;
background-color: var(--background-color3);
padding: 0 20px;
font-size: 15px;
border: 2px solid var(--secondary-color);
}
}
@media screen and (max-width: 490px) {
.message {
display: none;
}
.logosec {
width: 100%;
justify-content: space-between;
}
.logo {
font-size: 20px;
}
.menuicn {
height: 25px;
}
.nav-img {
height: 25px;
}
.nav-option {
gap: 25px;
}
.nav-option h3 {
font-size: 12px;
}
.nav-upper-options {
gap: 15px;
}
.recent-Articles {
font-size: 20px;
}
.report-topic-heading,
.item1,
.items {
width: 550px;
}
}
@media screen and (max-width: 400px) {
.recent-Articles {
font-size: 17px;
}
.view {
width: 60px;
font-size: 10px;
height: 27px;
}
.report-header {
height: 60px;
padding: 10px 10px 5px 10px;
}
.searchbtn img {
height: 20px;
}
}
@media screen and (max-width: 320px) {
.recent-Articles {
font-size: 12px;
}
.view {
width: 50px;
font-size: 8px;
height: 27px;
}
.report-header {
height: 60px;
padding: 10px 5px 5px 5px;
}
.t-op {
font-size: 12px;
}
.t-op-nextlvl {
font-size: 10px;
}
.report-topic-heading,
.item1,
.items {
width: 300px;
}
.report-body {
padding: 10px;
}
.label-tag {
width: 70px;
}
.searchbtn {
width: 40px;
}
.searchbar2 input {
width: 180px;
}
}
+8
View File
@@ -0,0 +1,8 @@
//index.js
// let menuicn = document.querySelector(".menuicn");
// let nav = document.querySelector(".navcontainer");
// menuicn.addEventListener("click", () => {
// nav.classList.toggle("navclose");
// })
+401
View File
@@ -0,0 +1,401 @@
/*style.css*/
@import url("https://fonts.googleapis.com/css2?family=Poppins:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap");
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: "Poppins", sans-serif;
}
:root {
--background-color1: #fafaff;
--background-color2: #ffffff;
--background-color3: #ededed;
--background-color4: #cad7fda4;
--primary-color: #4b49ac;
--secondary-color: #0c007d;
--Border-color: #3f0097;
--one-use-color: #3f0097;
--two-use-color: #5500cb;
}
body {
background-color: var(--background-color4);
max-width: 100%;
overflow-x: hidden;
}
header {
height: 70px;
width: 100vw;
padding: 0 30px;
background-color: var(--background-color1);
position: fixed;
z-index: 100;
box-shadow: 1px 1px 15px rgba(161, 182, 253, 0.825);
display: flex;
justify-content: space-between;
align-items: center;
}
.logo {
font-size: 27px;
font-weight: 600;
color: rgb(47, 141, 70);
}
.icn {
height: 30px;
}
.menuicn {
cursor: pointer;
}
.searchbar,
.message,
.logosec {
display: flex;
align-items: center;
justify-content: center;
}
.searchbar2 {
display: none;
}
.logosec {
gap: 60px;
}
.searchbar input {
width: 250px;
height: 42px;
border-radius: 50px 0 0 50px;
background-color: var(--background-color3);
padding: 0 20px;
font-size: 15px;
outline: none;
border: none;
}
.searchbtn {
width: 50px;
height: 42px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 0px 50px 50px 0px;
background-color: var(--secondary-color);
cursor: pointer;
}
.message {
gap: 40px;
position: relative;
cursor: pointer;
}
.circle {
height: 7px;
width: 7px;
position: absolute;
background-color: #fa7bb4;
border-radius: 50%;
left: 19px;
top: 8px;
}
.dp {
height: 40px;
width: 40px;
background-color: #626262;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
overflow: hidden;
}
.main-container {
display: flex;
width: 100vw;
position: relative;
top: 70px;
z-index: 1;
}
.dpicn {
height: 42px;
}
.main {
height: calc(100vh - 70px);
width: 100%;
overflow-y: scroll;
overflow-x: hidden;
padding: 40px 30px 30px 30px;
}
.main::-webkit-scrollbar-thumb {
background-image:
linear-gradient(to bottom, rgb(0, 0, 85), rgb(0, 0, 50));
}
.main::-webkit-scrollbar {
width: 5px;
}
.main::-webkit-scrollbar-track {
background-color: #9e9e9eb2;
}
.box-container {
display: flex;
justify-content: space-evenly;
align-items: center;
flex-wrap: wrap;
gap: 50px;
}
.nav {
min-height: 91vh;
width: 250px;
background-color: var(--background-color2);
position: absolute;
top: 0px;
left: 00;
box-shadow: 1px 1px 10px rgba(198, 189, 248, 0.825);
display: flex;
flex-direction: column;
justify-content: space-between;
overflow: hidden;
padding: 30px 0 20px 10px;
}
.navcontainer {
height: calc(100vh - 70px);
width: 250px;
position: relative;
overflow-y: scroll;
overflow-x: hidden;
transition: all 0.5s ease-in-out;
}
.navcontainer::-webkit-scrollbar {
display: none;
}
.navclose {
width: 80px;
}
.nav-option {
width: 250px;
height: 60px;
display: flex;
align-items: center;
padding: 0 30px 0 20px;
gap: 20px;
transition: all 0.1s ease-in-out;
}
.nav-option:hover {
border-left: 5px solid #a2a2a2;
background-color: #dadada;
cursor: pointer;
}
.nav-img {
height: 30px;
}
.nav-upper-options {
display: flex;
flex-direction: column;
align-items: center;
gap: 30px;
}
.option1 {
border-left: 5px solid #010058af;
background-color: var(--Border-color);
color: white;
cursor: pointer;
}
.option1:hover {
border-left: 5px solid #010058af;
background-color: var(--Border-color);
}
.box {
height: 130px;
width: 430px;
border-radius: 20px;
box-shadow: 3px 3px 10px rgba(0, 30, 87, 0.751);
padding: 20px;
display: flex;
align-items: center;
justify-content: space-around;
cursor: pointer;
transition: transform 0.3s ease-in-out;
}
.box:hover {
transform: scale(1.08);
}
.box:nth-child(1) {
background-color: var(--one-use-color);
}
.box:nth-child(2) {
background-color: var(--two-use-color);
}
.box:nth-child(3) {
background-color: var(--one-use-color);
}
.box:nth-child(4) {
background-color: var(--two-use-color);
}
.box img {
height: 50px;
}
.box .text {
color: white;
}
.topic {
font-size: 13px;
font-weight: 400;
letter-spacing: 1px;
}
.topic-heading {
font-size: 30px;
letter-spacing: 3px;
}
.report-container {
min-height: 90vh;
/*max-width: 1200px; */
margin: 10px auto 0px auto;
background-color:rgb(188, 188, 188);
border-radius: 30px;
box-shadow: 3px 3px 10px rgb(188, 188, 188);
padding: 0px 20px 20px 20px;
}
#map {
width: 100%;
height: 100%;
}
.report-header {
height: 130px;
width: 100%;
display: flex;
align-items: center;
justify-content: space-between;
padding: 20px 20px 10px 20px;
border-bottom: 2px solid rgba(0, 20, 151, 0.59);
}
.header_container {
height: 100%;
width: 100%;
display: flex;
align-items: center;
}
.map-container{
flex: 3; /* 3 bagian dari 4 */
background-color: lightblue;
padding: 1rem;
}
.side_container {
flex: 1; /* 1 bagian dari 4 */
background-color: rgb(226, 226, 226);
padding: 20px;
align-items: center;
justify-content: left;
}
.recent-Articles {
font-size: 30px;
font-weight: 600;
color: #5500cb;
}
.view {
height: 35px;
width: 90px;
border-radius: 8px;
background-color: #5500cb;
color: white;
font-size: 15px;
border: none;
cursor: pointer;
}
.report-body {
max-width: 1160px;
overflow-x: auto;
padding: 20px;
}
.report-topic-heading,
.item1 {
width: 1120px;
display: flex;
justify-content: space-between;
align-items: center;
}
.t-op {
font-size: 18px;
letter-spacing: 0px;
}
.items {
width: 1120px;
margin-top: 15px;
}
.item1 {
margin-top: 20px;
}
.t-op-nextlvl {
font-size: 14px;
letter-spacing: 0px;
font-weight: 600;
}
.label-tag {
width: 100px;
text-align: center;
background-color: rgb(0, 177, 0);
color: white;
border-radius: 4px;
}
#map {
/* position: absolute; */
top: 0;
left: 0;
bottom: 0;
right: 0;
height: 100%;
width: 100%;
}
+85
View File
@@ -0,0 +1,85 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Peta Wilayah</title>
<link rel="stylesheet" href="https://unpkg.com/leaflet/dist/leaflet.css" />
<style>#map { height: 100vh; }</style>
</head>
<body>
<div id="map"></div>
<script src="https://unpkg.com/leaflet/dist/leaflet.js"></script>
<script>
const map = L.map('map').setView([4.2, 96.9], 7);
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png').addTo(map);
// Ganti endpoint berdasarkan level: wil_provinsi, wil_kabupaten_kota, dll
// fetch('http://localhost:5000/api/geojson/wil_provinsi')
// .then(res => res.json())
// .then(data => {
// L.geoJSON(data, {
// style: { color: 'blue' },
// onEachFeature: function (feature, layer) {
// const p = feature.properties;
// layer.bindPopup(`<strong>${p.nama}</strong><br>Kode: ${p.kode}`);
// }
// }).addTo(map);
// });
</script>
<script>
let currentLayer = null;
function loadLayer(url, onClickCallback) {
fetch(url)
.then(res => res.json())
.then(data => {
if (currentLayer) {
map.removeLayer(currentLayer);
}
currentLayer = L.geoJSON(data, {
style: { color: "blue", weight: 2 },
onEachFeature: function (feature, layer) {
let clickTimer = null;
layer.on('click', function (e) {
let kode = feature.properties.id;
// onClickCallback(kode);
if (clickTimer) {
// Double click detected
clearTimeout(clickTimer);
clickTimer = null;
// Aksi double click → Pindah layer
let kode = feature.properties.id;
onClickCallback(kode);
} else {
// Single click → Tampilkan popup
clickTimer = setTimeout(() => {
clickTimer = null;
layer.bindPopup(feature.properties.nama).openPopup(e.latlng);
}, 250); // waktu tunggu untuk deteksi double click
layer.bindPopup(feature.properties.nama);
}
});
// layer.bindPopup(feature.properties.nama);
}
}).addTo(map);
map.fitBounds(currentLayer.getBounds());
});
}
// Load provinsi Aceh awal
loadLayer('/geojson/provinsi', function (kode_provinsi) {
loadLayer(`/geojson/kabupaten/${kode_provinsi}`, function (kode_kabupaten) {
loadLayer(`/geojson/kecamatan/${kode_kabupaten}`, function (kode_kecamatan) {
loadLayer(`/geojson/desa/${kode_kecamatan}`, function () {
// Desa tidak turun level lagi
});
});
});
});
</script>
</body>
</html>
+735
View File
@@ -0,0 +1,735 @@
<html>
<head>
<title>Peta Wilayah</title>
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}" />
<link rel="stylesheet" href="{{ url_for('static', filename='css/bootstrap.min.css') }}" />
<link rel="stylesheet" href="{{ url_for('static', filename='css/select2.min.css') }}" />
<link rel="stylesheet" href="{{ url_for('static', filename='responsive.css') }}" />
<link rel="stylesheet" href="https://unpkg.com/leaflet/dist/leaflet.css" />
<style>
.select2-selection__arrow {
display: block !important;
}
</style>
</head>
<body>
<div class="main-container">
<div class="main">
<div class="searchbar2">
<input type="text" name="" id="" placeholder="Search" />
<div class="searchbtn">
<img src="https://media.geeksforgeeks.org/wp-content/uploads/20221210180758/Untitled-design-(28).png"
class="icn srchicn" alt="search-button" />
</div>
</div>
<!-- <div class="box-container">
<div class="box box1">
<div class="text">
<h2 class="topic-heading">60.5k</h2>
<h2 class="topic">Article Views</h2>
</div>
<img src="https://media.geeksforgeeks.org/wp-content/uploads/20221210184645/Untitled-design-(31).png"
alt="Views" />
</div>
<div class="box box2">
<div class="text">
<h2 class="topic-heading">150</h2>
<h2 class="topic">Likes</h2>
</div>
<img src="https://media.geeksforgeeks.org/wp-content/uploads/20221210185030/14.png" alt="likes" />
</div>
<div class="box box3">
<div class="text">
<h2 class="topic-heading">320</h2>
<h2 class="topic">Comments</h2>
</div>
<img src="https://media.geeksforgeeks.org/wp-content/uploads/20221210184645/Untitled-design-(32).png"
alt="comments" />
</div>
<div class="box box4">
<div class="text">
<h2 class="topic-heading">70</h2>
<h2 class="topic">Published</h2>
</div>
<img src="https://media.geeksforgeeks.org/wp-content/uploads/20221210185029/13.png"
alt="published" />
</div>
</div> -->
<div class="report-container">
<div class="report-header">
<!-- <h1 class="recent-Articles">Recent Articles</h1>
<button class="view">View All</button> -->
<div class="box-container">
<div class="box box1">
<div class="text">
<h2 class="topic-heading" id="tot_dd">Total Dana Desa</h2>
<h2 class="topic">Total Dana Desa</h2>
<h2></h2>
</div>
<img src="https://media.geeksforgeeks.org/wp-content/uploads/20221210184645/Untitled-design-(31).png"
alt="Views" />
</div>
<div class="box box2">
<div class="text">
<h2 class="topic-heading" id="tot_sr">150</h2>
<h2 class="topic">Total Serapan</h2>
</div>
<img src="https://media.geeksforgeeks.org/wp-content/uploads/20221210185030/14.png" alt="likes" />
</div>
<div class="box box3">
<div class="text">
<h2 class="topic-heading" id="pr_sr">320</h2>
<h2 class="topic">Persentase Serapan</h2>
</div>
<img src="https://media.geeksforgeeks.org/wp-content/uploads/20221210184645/Untitled-design-(32).png"
alt="comments" />
</div>
<div class="box box4">
<div class="text">
<h2 class="topic-heading">70</h2>
<h2 class="topic">Published</h2>
</div>
<img src="https://media.geeksforgeeks.org/wp-content/uploads/20221210185029/13.png"
alt="published" />
</div>
</div>
</div>
<div class="header_container">
<div class="map-container" id="map"></div>
<div class="side_container" style="height:100%">
<div class="row form-group">
<div class="col-md-12">
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text" style="width: 150px;">
Provinsi
</span>
</div>
<select class="form-control select2 border border-primary" name="provinsiDropdown" id="provinsiDropdown"
data-placeholder="Provinsi ......">
<option></option>
<option value="1">Option 1</option>
<option value="2">Option 2</option>
</select>
</div>
</div>
</div>
<div class="row form-group">
<div class="col-md-12">
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text" style="width: 150px;">
Kabupaten/Kota
</span>
</div>
<select class="form-control select2" name="kabkotaDropdown" id="kabkotaDropdown"
data-placeholder="Kabupaten/Kota ....." >
<option></option>
<option value="1">Option 1</option>
<option value="2">Option 2</option>
</select>
</div>
</div>
</div>
<div class="row form-group">
<div class="col-md-12">
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text" style="width: 150px;">
Kecamatan
</span>
</div>
<select class="form-control select2" name="kecamatanDropdown" id="kecamatanDropdown"
data-placeholder="Kecamatan .....">
<option></option>
<option value="1">Option 1</option>
<option value="2">Option 2</option>
</select>
</div>
</div>
</div>
<div class="row">
<div class="col-md-12">
<canvas id="canvas" style="width=100%"></canvas>
</div>
</div>
<!-- <canvas id="myChart" style="width:80%;max-width:400px; margin-left: 20px;"></canvas> -->
</div>
</div>
</div>
</div>
</div>
<script src="{{ url_for('static', filename='script.js')}}"></script>
<script src="{{ url_for('static', filename='js/jquery-3.7.1.js')}}"></script>
<script src="{{ url_for('static', filename='js/bootstrap.min.js')}}"></script>
<script src="{{ url_for('static', filename='js/select2.min.js')}}"></script>
<script src="https://unpkg.com/leaflet/dist/leaflet.js"></script>
<script>
// const map = L.map('map').setView([4.2, 96.9], 7);
const indonesiaBounds = L.latLngBounds(
L.latLng(-11, 94), // Southwest corner (approx Sabang - Rote)
L.latLng(6.5, 141) // Northeast corner (approx Papua)
);
const map = L.map('map', {
center: [-2, 118], // Pusat Indonesia
// zoom: 5,
maxBounds: indonesiaBounds,
maxBoundsViscosity: 1.0,
zoomSnap: 0.5,
zoomDelta: 0.5
});
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '© OpenStreetMap',
maxZoom: 12
}).addTo(map);
map.fitBounds(indonesiaBounds);
const optimalZoom = map.getZoom();
map.setMinZoom(optimalZoom);
</script>
<script>
let currentLayer = null;
function loadLayer(url, onClickCallback, level = 'provinsi') {
currentLevel = level;
fetch(url)
.then(res => res.json())
.then(data => {
// 1. Fungsi validasi dan pembersih
function isValidCoord(coord) {
return Array.isArray(coord) &&
coord.length === 2 &&
typeof coord[0] === "number" &&
typeof coord[1] === "number" &&
!isNaN(coord[0]) &&
!isNaN(coord[1]);
}
function cleanCoordinates(multiPolygon) {
return multiPolygon.map(polygon =>
polygon.map(ring =>
ring.filter(coord => isValidCoord(coord))
).filter(ring => ring.length >= 4) // valid ring minimal 4 titik
).filter(polygon => polygon.length > 0);
}
// 2. Bersihkan data sebelum digunakan
data.features.forEach(feature => {
if (feature.geometry.type === "MultiPolygon") {
feature.geometry.coordinates = cleanCoordinates(feature.geometry.coordinates);
}
});
if (currentLayer) {
map.removeLayer(currentLayer);
}
currentLayer = L.geoJSON(data, {
style: { color: "blue", weight: 2 },
onEachFeature: function (feature, layer) {
console.log(feature,layer)
let clickTimer = null;
layer.on('click', function (e) {
let kode = feature.properties.id;
console.log(kode)
// onClickCallback(kode);
if (clickTimer) {
// Double click detected
clearTimeout(clickTimer);
clickTimer = null;
// Aksi double click → Pindah layer
let kode = feature.properties.id;
onClickCallback(kode);
if (url.includes("/provinsi")) {
localStorage.setItem('kode_provinsi', feature.properties.kode)
} else if (currentLevel === 'kabupatenkota') {
localStorage.setItem('kode_kabupatenkota',feature.properties.kode)
}else if(currentLevel === 'kecamatan'){
localStorage.setItem('kode_kecamatan',feature.properties.kode)
}
} else {
// Single click → Tampilkan popup
clickTimer = setTimeout(async () => {
clickTimer = null;
if (url.includes("/provinsi")) {
localStorage.setItem('kode_provinsi', feature.properties.kode)
const status = await fetchStatusDesaByProvinsi(feature.properties.kode);
let klasifikasiHTML = "<li>Tidak ada data</li>";
if (Array.isArray(status?.[0])) {
indexDesaHTML = status[0]
.map(d => `${d[1]}: ${d[4]} / `)
.join("");
bumdesHTML = status[1]
.map(dt => `${dt[0]}:${dt[1]} / `)
.join("");
danadesaHTML = `Dana :${status[2].jumlah_per_m}, Persentase : ${status[2].persentage}%`;
serapanHTML = status[3]
.map(([jabatan, nilai]) => {
const alias = jabatan === 'Pendamping Lokal Desa' ? 'PLD' :
jabatan === 'Pendamping Desa' ? 'PD' :
jabatan;
return `${alias}: ${nilai}`;
}).join("");
koperasiHTML = status[4]
.map(dt => `${dt[0]}: ${dt[1]} / `)
.join("");
}
const popupContent = `
<strong>${feature.properties.nama}</strong><br/>
<strong>Status Desa:</strong>
<li>IDM - ${indexDesaHTML}</li>
<li>BUM - ${bumdesHTML}</li>
<li>DD - ${danadesaHTML}</li>
<li>SERAPAN - ${serapanHTML} </li>
<li>KOPERASI - ${koperasiHTML} </li>
`;
layer.bindPopup(popupContent).openPopup(e.latlng);
} else if (currentLevel === 'kabupatenkota') {
const province_code = localStorage.getItem('kode_provinsi');
localStorage.setItem('kode_kabupatenkota',feature.properties.kode)
const status = await fetchStatusDesaByKabupatenkota(province_code, feature.properties.kode);
let klasifikasiHTML = "<li>Tidak ada data</li>";
if (Array.isArray(status?.[0])) {
indexDesaHTML = status[0]
.map(d => `${d[1]}: ${d[5]} / `)
.join("");
bumdesHTML = status[1]
.map(dt => `${dt[0]}:${dt[1]} / `)
.join("");
danadesaHTML = `Dana :${status[2].jumlah_per_m}, Persentase : ${status[2].persentage}%`;
serapanHTML = status[3]
.map(([jabatan, nilai]) => {
const alias = jabatan === 'Pendamping Lokal Desa' ? 'PLD' :
jabatan === 'Pendamping Desa' ? 'PD' :
jabatan;
return `${alias}: ${nilai} /`;
}).join("");
koperasiHTML = status[4]
.map(dt => `${dt[0]}: ${dt[1]} / `)
.join("");
}
const popupContent = `
<strong>${feature.properties.nama}</strong><br/>
<strong>Status Desa (Kabupaten):</strong>
<li>IDM - ${indexDesaHTML}</li>
<li>BUM - ${bumdesHTML}</li>
<li>DD - ${danadesaHTML}</li>
<li>SERAPAN - ${serapanHTML} </li>
<li>KOPERASI - ${koperasiHTML} </li>
`;
layer.bindPopup(popupContent).openPopup(e.latlng);
} else if (currentLevel === 'kecamatan'){
const province_code = localStorage.getItem('kode_provinsi')
const region_code = localStorage.getItem('kode_kabupatenkota')
localStorage.setItem('kode_kecamatan',feature.properties.kode)
const status = await fetchStatusDesaByKecamatan(province_code, region_code, feature.properties.kode)
let klasifikasiHTML = "<li>Tidak ada data</li>";
if (Array.isArray(status?.[0])) {
indexDesaHTML = status[0]
.map(d => `${d[1]}: ${d[6]} / `)
.join("");
bumdesHTML = status[1]
.map(dt => `${dt[0]}:${dt[1]} / `)
.join("");
danadesaHTML = `Dana :${status[2].jumlah_per_m}, Persentase : ${status[2].persentage}%`;
serapanHTML = status[3]
.map(([jabatan, nilai]) => {
const alias = jabatan === 'Pendamping Lokal Desa' ? 'PLD' :
jabatan === 'Pendamping Desa' ? 'PD' :
jabatan;
return `${alias}: ${nilai} /`;
}).join("");
koperasiHTML = status[4]
.map(dt => `${dt[0]}: ${dt[1]} / `)
.join("");
}
const popupContent =
`
<strong> ${feature.properties.nama}</strong>
<strong>Status Desa (Kecamatan):</strong>
<strong>Status Desa:</strong>
<li>IDM - ${indexDesaHTML}</li>
<li>BUM - ${bumdesHTML}</li>
<li>DD - ${danadesaHTML}</li>
<li>SERAPAN - ${serapanHTML} </li>
<li>KOPERASI - ${koperasiHTML} </li>
`
layer.bindPopup(popupContent).openPopup(e.latlng);
}else {
// Desa
const province_code = localStorage.getItem('kode_provinsi')
const region_code = localStorage.getItem('kode_kabupatenkota')
const district_code = localStorage.getItem('kode_kecamatan')
const status = await fetchStatusDesaByDesa(province_code, region_code , district_code, feature.properties.kode);
let klasifikasiHTML = "<li>Tidak ada data</li>";
if (Array.isArray(status?.[0])) {
indexDesaHTML = status[0]
.map(d => `${d[1]}: ${d[5]} / `)
.join("");
bumdesHTML = status[1]
.map(dt => `${dt[0]}:${dt[1]} / `)
.join("");
danadesaHTML = `Dana :${status[2].jumlah_per_m}, Persentase : ${status[2].persentage}%`;
serapanHTML = status[3]
.map(([jabatan, nilai]) => {
const alias = jabatan === 'Pendamping Lokal Desa' ? 'PLD' :
jabatan === 'Pendamping Desa' ? 'PD' :
jabatan;
return `${alias}: ${nilai} /`;
}).join("");
koperasiHTML = status[4]
.map(dt => `${dt[0]}: ${dt[1]} / `)
.join("");
}
const popupContent = `
<strong>${feature.properties.nama}</strong><br/>
<strong>Status Desa (Desa):</strong>
<li>IDM - ${indexDesaHTML}</li>
<li>BUM - ${bumdesHTML}</li>
<li>DD - ${danadesaHTML}</li>
<li>SERAPAN - ${serapanHTML} </li>
<li>KOPERASI - ${koperasiHTML} </li>
`;
layer.bindPopup(popupContent).openPopup(e.latlng);
}
}, 250);
layer.bindPopup(feature.properties.nama);
}
console.log(currentLevel)
});
layer.bindPopup(feature.properties.nama);
}
}).addTo(map);
map.fitBounds(currentLayer.getBounds());
setTimeout(() => {
map.invalidateSize();
}, 200);
});
}
async function fetchStatusDesaByProvinsi(kodeProvinsi) {
const url = `http://localhost:5000/api/status-provinsi/${kodeProvinsi}`;
const urldd = `http://localhost:5000/api/provinsi/serapan/${kodeProvinsi}`;
const urlpd = `http://localhost:5000//api/provinsi/pendamping/${kodeProvinsi}`
const urlkop = `http://localhost:5000//api/provinsi/koperasi/${kodeProvinsi}`
const urlbd = `http://localhost:5000/api/provinsi/bumdes/${kodeProvinsi}`;
try {
const res = await fetch(url);
const bumdes = await fetch(urlbd)
const dd = await fetch(urldd)
const pd = await fetch(urlpd)
const kop = await fetch(urlkop)
if (!res.ok && !bumdes.ok && !dd.ok) throw new Error(`HTTP ${res.status}`);
const IPD = await res.json()
const bd = await bumdes.json()
const danadesa = await dd.json()
const dtpd = await pd.json()
const dtkop = await kop.json()
return [IPD,bd, danadesa, dtpd, dtkop];
} catch (err) {
console.error("Gagal ambil status desa:", err);
return null;
}
}
async function fetchStatusDesaByKabupatenkota(kode_prov, kode_kabkota) {
const url = `http://localhost:5000/api/status-kabupatenkota/${kode_prov}/${kode_kabkota}`
const urldd = `http://localhost:5000/api/kabkota/serapan/${kode_kabkota}`;
const urlpd = `http://localhost:5000//api/kabkota/pendamping/${kode_kabkota}`
const urlkop = `http://localhost:5000//api/kabkota/koperasi/${kode_kabkota}`
const urlbd = `http://localhost:5000/api/kabkota/bumdes/${kode_kabkota}`;
try{
const res = await fetch(url)
const bumdes = await fetch(urlbd)
const dd = await fetch(urldd)
const pd = await fetch(urlpd)
const kop = await fetch(urlkop)
if (!res.ok && !bumdes.ok && !dd.ok) throw new Error(`HTTP ${res.status}`);
const IPD = await res.json()
const bd = await bumdes.json()
const danadesa = await dd.json()
const dtpd = await pd.json()
const dtkop = await kop.json()
return [IPD,bd, danadesa, dtpd, dtkop];
}catch(err){
console.log(err)
return null;
}
}
async function fetchStatusDesaByKecamatan(province_code, region_code, district_code){
const url = `http://localhost:5000/api/status-kecamatan/${province_code}/${region_code}/${district_code}`
const urldd = `http://localhost:5000/api/kecamatan/serapan/${district_code}`;
const urlpd = `http://localhost:5000//api/kecamatan/pendamping/${district_code}`
const urlkop = `http://localhost:5000//api/kecamatan/koperasi/${district_code}`
const urlbd = `http://localhost:5000/api/kecamatan/bumdes/${district_code}`;
try {
const res = await fetch(url)
const bumdes = await fetch(urlbd)
const dd = await fetch(urldd)
const pd = await fetch(urlpd)
const kop = await fetch(urlkop)
if (!res.ok && !bumdes.ok && !dd.ok) throw new Error(`HTTP ${res.status}`);
const IPD = await res.json()
const bd = await bumdes.json()
const danadesa = await dd.json()
const dtpd = await pd.json()
const dtkop = await kop.json()
return [IPD,bd, danadesa, dtpd, dtkop];;
} catch (error) {
console.log(error)
return null
}
}
async function fetchStatusDesaByDesa(province_code, region_code, district_code, village_code){
const url = `http://localhost:5000//api/desa/status/${province_code}/${region_code}/${district_code}/${village_code}`
const urldd = `http://localhost:5000/api/desa/serapan/${village_code}`;
const urlpd = `http://localhost:5000//api/desa/pendamping/${village_code}`
const urlkop = `http://localhost:5000//api/desa/koperasi/${village_code}`
const urlbd = `http://localhost:5000/api/desa/bumdes/${village_code}`;
try {
const res = await fetch(url)
const bumdes = await fetch(urlbd)
const dd = await fetch(urldd)
const pd = await fetch(urlpd)
const kop = await fetch(urlkop)
if (!res.ok && !bumdes.ok && !dd.ok) throw new Error(`HTTP ${res.status}`);
const IPD = await res.json()
const bd = await bumdes.json()
const danadesa = await dd.json()
const dtpd = await pd.json()
const dtkop = await kop.json()
return [IPD,bd, danadesa, dtpd, dtkop];;
} catch (error) {
console.log(error)
return null
}
}
// Load provinsi Aceh awal
loadLayer('/geojson/provinsi', function (kode_provinsi) {
loadLayer(`/geojson/kabupaten/${kode_provinsi}`, function (kode_kabupaten) {
loadLayer(`/geojson/kecamatan/${kode_kabupaten}`, function (kode_kecamatan) {
loadLayer(`/geojson/desa/${kode_kecamatan}`, function () {
// Desa tidak turun level lagi
}, 'desa');
}, 'kecamatan');
}, 'kabupatenkota');
}, 'provinsi');
function goToLevel(level) {
const prov = localStorage.getItem('kode_provinsi');
const kab = localStorage.getItem('kode_kabupatenkota');
const kec = localStorage.getItem('kode_kecamatan');
switch (level) {
case 'provinsi':
loadLayer(`/geojson/provinsi`, () => {}, 'provinsi');
break;
case 'kabupatenkota':
loadLayer(`/geojson/kabupaten/${prov}`, () => {}, 'kabupatenkota');
break;
case 'kecamatan':
loadLayer(`/geojson/kecamatan/${kab}`, () => {}, 'kecamatan');
break;
}
}
$('#provinsiDropdown').on('change', function (e) {
const kodeProvinsi = $(this).val(); // lebih aman daripada e.target.value
console.log("Provinsi dipilih:", kodeProvinsi);
if (!kodeProvinsi) {
console.warn("Tidak ada kode provinsi yang dipilih!");
return;
}
localStorage.setItem('kode_provinsi', kodeProvinsi);
console.log(`Memuat kabupaten dari /geojson/kabupaten/${kodeProvinsi}`);
loadLayer(`/geojson/kabupaten/${kodeProvinsi}`, () => {
console.log("Layer kabupaten dimuat.");
}, 'kabupatenkota');
});
$('#kabkotaDropdown').on('change', function (e) {
const kodeKabupaten = e.target.value;
localStorage.setItem('kode_kabupatenkota', kodeKabupaten);
loadLayer(`/geojson/kecamatan/${kodeKabupaten}`, () => {}, 'kecamatan');
}).select2();
document.getElementById('kecamatanDropdown').addEventListener('change', function (e) {
const kodeKecamatan = e.target.value;
localStorage.setItem('kode_kecamatan', kodeKecamatan);
loadLayer(`/geojson/desa/${kodeKecamatan}`, () => {}, 'desa');
});
$(document).ready(function () {
console.log("ready for fetching data")
const provinsiURL = "{{ url_for('main.get_master_provinsi') }}";
$('#provinsiDropdown').select2({
placeholder: 'Pilih Desa',
allowClear: true,
ajax: {
url: provinsiURL,
dataType: 'json',
delay: 250,
data: function (params) {
return {
q: params.term
};
},
processResults: function (data) {
console.log(data)
return {
results: data.map(provinsi => ({
id: provinsi[0],
text: provinsi[1]
}))
};
},
cache: true
},
minimumInputLength: 0
});
});
</script>
<script>
document.addEventListener("DOMContentLoaded", (event) => {
$( '.select2' ).select2( {
theme: 'bootstrap-4'
} );
let total_dd_container = document.getElementById('tot_dd')
fetchTotDana('http://localhost:5000/api/desa/total-dana-desa')
fethTotSerapan('http://localhost:5000/api/desa/total-serapan-dana')
function fetchTotDana(url){
fetch(url)
.then(res => res.json())
.then(data => {
total_dd_container.textContent = parseDanBulatkanKeMiliar(data)
})
}
function fethTotSerapan(url){
fetch(url)
.then(res => res.json())
.then(data => {
console.log(data)
document.getElementById('tot_sr').textContent = parseDanBulatkanKeMiliar(data['serapan_per_m'])
document.getElementById('pr_sr').textContent = data['persentage'] + "%"
})
}
function parseDanBulatkanKeMiliar(input) {
// 1. Bersihkan input: hapus "Rp", ".", ganti koma dengan titik
let cleaned = input
.replace(/Rp/g, "")
.replace(/\./g, "")
.replace(",", ".");
// 2. Konversi ke angka
let angka = parseFloat(cleaned);
// 3. Bulatkan ke satuan miliar
let hasilBulat = Math.round(angka / 1e9);
// 4. Tambahkan format "x Miliar"
return "Rp" + hasilBulat.toLocaleString("id-ID") + " M";
}
})
</script>
<!-- Chart Script -->
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script>
var getRandomDataArray = function () {
var dataArray = [];
for (var i = 0; i < 7; i++) dataArray.push(Math.round(Math.random() * 100));
return dataArray;
}
window.onload = function(){
var chartOptions = { responsive : true };
var chartData = {
labels : ["January","February","March","April","May","June","July"],
datasets : [
{
fillColor : "#ffa500",
strokeColor : "rgba(220,220,220,0.8)",
highlightFill: "rgba(220,220,220,0.75)",
highlightStroke: "rgba(220,220,220,1)",
data : getRandomDataArray()
},
{
fillColor : "rgba(151,187,205,0.5)",
strokeColor : "rgba(151,187,205,0.8)",
highlightFill : "rgba(151,187,205,0.75)",
highlightStroke : "rgba(151,187,205,1)",
data : getRandomDataArray()
}
]
}
var chart = document.getElementById("canvas").getContext("2d");
window.myBar = new Chart(chart, {
type: "bar", // <- gunakan type di sini, bukan .Bar()
data: chartData,
options: chartOptions
});
}
</script>
</body>
</html>