);
diff --git a/src/app/darmasaba/(pages)/lingkungan/konservasi-adat-bali/page.tsx b/src/app/darmasaba/(pages)/lingkungan/konservasi-adat-bali/page.tsx
index 44869d53..c53e1f3d 100644
--- a/src/app/darmasaba/(pages)/lingkungan/konservasi-adat-bali/page.tsx
+++ b/src/app/darmasaba/(pages)/lingkungan/konservasi-adat-bali/page.tsx
@@ -1,93 +1,79 @@
import colors from '@/con/colors';
-import { Box, List, ListItem, Paper, SimpleGrid, Stack, Text } from '@mantine/core';
+import { Box, Center, List, ListItem, Paper, SimpleGrid, Stack, Text } from '@mantine/core';
import BackButton from '../../desa/layanan/_com/BackButto';
const data = [
{
id: 1,
title: 'Filosofi Tri Hita Karana',
- listDeskripsi:
-
- Parahyangan: Hubungan manusia dengan Tuhan
-
-
- Pawongan: Hubungan antar manusia
-
-
- Palemahan: Hubungan manusia dengan alam
-
-
+ listDeskripsi: (
+
+ Parahyangan: Hubungan manusia dengan Tuhan yang dijaga penuh kesadaran spiritual
+ Pawongan: Harmoni dan kerja sama antar manusia dalam masyarakat
+ Palemahan: Pelestarian lingkungan dan hubungan manusia dengan alam
+
+ ),
},
{
id: 2,
title: 'Bentuk Konservasi Berdasarkan Adat',
- listDeskripsi:
-
- Pelestarian Hutan Adat seperti Alas Pala Sangeh atau Wana Kerthi
-
-
- Subak: Sistem pengelolaan irigasi tradisional yang menjunjung kebersamaan dan keberlanjutan
-
-
- Hari Raya Tumpek Uduh: Perayaan khusus untuk menghormati pohon dan tumbuhan
-
-
- Perarem dan Awig-Awig: Aturan adat desa yang mengatur larangan menebang pohon sembarangan, membuang limbah ke sungai, dll.
-
-
- Ritual penyucian alam seperti Melasti, Piodalan Segara, dan lainnya
-
-
+ listDeskripsi: (
+
+ Pelestarian Hutan Adat seperti Alas Pala Sangeh dan Wana Kerthi
+ Subak: Sistem irigasi tradisional yang menekankan kebersamaan dan keberlanjutan
+ Hari Raya Tumpek Uduh: Perayaan untuk menghormati pohon dan tumbuhan
+ Perarem & Awig-Awig: Aturan adat untuk menjaga lingkungan dari kerusakan
+ Ritual penyucian alam seperti Melasti dan Piodalan Segara
+
+ ),
},
{
id: 3,
title: 'Nilai Konservasi Adat',
- listDeskripsi:
-
- Menjaga keseimbangan ekosistem
-
-
- Melestarikan spiritualitas lokal dan kesucian alam
-
-
- Menumbuhkan kesadaran kolektif untuk hidup selaras dengan lingkungan
-
-
- Menjaga keberlangsungan sumber daya alam untuk generasi mendatang
-
-
+ listDeskripsi: (
+
+ Menjaga keseimbangan ekosistem dan lingkungan hidup
+ Melestarikan spiritualitas lokal dan kesucian alam
+ Meningkatkan kesadaran kolektif untuk hidup selaras dengan alam
+ Menjamin keberlanjutan sumber daya alam untuk generasi mendatang
+
+ ),
},
-]
+];
+
function Page() {
return (
-
+
-
-
+
+
Konservasi Adat Bali
-
- Konservasi Adat Bali adalah upaya pelestarian lingkungan yang berpijak pada kearifan lokal masyarakat Bali, di mana alam dan budaya dianggap sebagai satu kesatuan yang harus dijaga secara harmonis.
+
+ Pelestarian lingkungan di Bali yang berpijak pada kearifan lokal, menjaga harmoni antara alam, budaya, dan manusia.
-
-
- {data.map((v, k) => {
- return (
-
-
- {v.title}
- {v.listDeskripsi}
-
-
- )
- })}
+
+
+ {data.map((item) => (
+
+
+
+
+ {item.title}
+
+
+ {item.listDeskripsi}
+
+
+ ))}
diff --git a/src/app/darmasaba/(pages)/lingkungan/pengelolaan-sampah-bank-sampah/page.tsx b/src/app/darmasaba/(pages)/lingkungan/pengelolaan-sampah-bank-sampah/page.tsx
index 17435994..ce38423d 100644
--- a/src/app/darmasaba/(pages)/lingkungan/pengelolaan-sampah-bank-sampah/page.tsx
+++ b/src/app/darmasaba/(pages)/lingkungan/pengelolaan-sampah-bank-sampah/page.tsx
@@ -1,63 +1,60 @@
+'use client'
+import pengelolaanSampahState from '@/app/admin/(dashboard)/_state/lingkungan/pengelolaan-sampah';
import colors from '@/con/colors';
-import { Box, Flex, Paper, SimpleGrid, Stack, Text, TextInput } from '@mantine/core';
-import { IconClipboardTextFilled, IconMapPin, IconRecycle, IconScale, IconSearch, IconTrashFilled, IconTruckFilled } from '@tabler/icons-react';
+import { Box, Flex, Paper, SimpleGrid, Skeleton, Stack, Text, TextInput } from '@mantine/core';
+import { useShallowEffect } from '@mantine/hooks';
+import { Icon, IconChartLine, IconClipboardTextFilled, IconLeaf, IconRecycle, IconScale, IconSearch, IconTent, IconTrashFilled, IconTrophy, IconTruckFilled } from '@tabler/icons-react';
+import React from 'react';
+import { useProxy } from 'valtio/utils';
import BackButton from '../../desa/layanan/_com/BackButto';
+import dynamic from 'next/dynamic';
+
+// Dynamically import the map component to avoid SSR issues with Leaflet
+const LeafletMultiMarkerMap = dynamic(
+ () => import('@/app/admin/(dashboard)/_com/LeafletMultiMarkerMap'),
+ { ssr: false }
+);
-const data = [
- {
- id: 1,
- icon: ,
- deskripsi: '1. Pilah sampah sesuai jenisnya'
- },
- {
- id: 2,
- icon: ,
- deskripsi: '2. Bawa sampah ke Bank Sampah'
- },
- {
- id: 3,
- icon: ,
- deskripsi: '3. Timbang sampah di Bank Sampah'
- },
- {
- id: 4,
- icon: ,
- deskripsi: '4. Catat hasil timbangan di buku tabungan'
- },
- {
- id: 5,
- icon: ,
- deskripsi: '5. Sampah didaur ulang oleh petugas Bank Sampah'
- },
-]
-const bankSampah = [
- {
- id: 1,
- icon: ,
- deskripsi: 'Bank Sampah Sarana Gathi',
- alamat: 'Jl. Ahmad Yani Utara No.453, Peguyangan, Kec. Denpasar Utara, Kota Denpasar, Bali 80115'
- },
- {
- id: 2,
- icon: ,
- deskripsi: 'Bank Sampah BALI WASTU LESTARI',
- alamat: 'Jl. Ahmad Yani Utara Gg. Garuda No.1, Peguyangan, Kec. Denpasar Utara, Kota Denpasar, Bali 80115'
- },
- {
- id: 3,
- icon: ,
- deskripsi: 'Bank Sampah Jempiring Sari',
- alamat: 'Jl. Gn. Lebah I No.9, Tegal Harum, Kec. Denpasar Bar., Kota Denpasar, Bali 80119'
- },
- {
- id: 4,
- icon: ,
- deskripsi: 'Bank Sampah Sarana Gathi',
- alamat: 'Jl. Ahmad Yani Utara No.453, Peguyangan, Kec. Denpasar Utara, Kota Denpasar, Bali 80115'
- },
-]
function Page() {
+ const state = useProxy(pengelolaanSampahState.pengelolaanSampah)
+ const state2 = useProxy(pengelolaanSampahState.keteranganSampah)
+
+ const {
+ data,
+ load
+ } = state.findMany
+
+ const {
+ data: data2,
+ load: load2
+ } = state2.findMany
+
+ useShallowEffect(() => {
+ load()
+ load2()
+ }, [])
+
+ const iconMap: Record = {
+ ekowisata: IconLeaf,
+ kompetisi: IconTrophy,
+ wisata: IconTent,
+ ekonomi: IconChartLine,
+ sampah: IconRecycle,
+ truck: IconTruckFilled,
+ scale: IconScale,
+ clipboard: IconClipboardTextFilled,
+ trash: IconTrashFilled,
+ };
+
+ if (state.findMany.loading || !data) {
+ return (
+
+
+
+ )
+ }
+
return (
@@ -84,10 +81,10 @@ function Page() {
-
- {v.icon}
+
+ {k + 1} {iconMap[v.icon] ? React.createElement(iconMap[v.icon]) : null}
- {v.deskripsi}
+ {v.name}
@@ -96,7 +93,7 @@ function Page() {
-
+
Keterangan Bank Sampah Terdekat
@@ -107,66 +104,64 @@ function Page() {
leftSection={}
placeholder='Cari Bank Sampah Terdekat'
/>
-
+
+
+ {/* Left side - List of bank locations */}
-
- {bankSampah.map((v, k) => {
- return (
-
-
-
-
- {v.icon}
-
-
-
- {v.deskripsi}
-
-
- {v.alamat}
-
-
-
-
-
- )
- })}
-
+
+ Daftar Bank Sampah
+
+ {data2?.map((v, k) => (
+
+ {v.namaTempatMaps}
+ {v.alamat}
+ {v.lat && v.lng ? (
+
+ 📌 Buka di Google Maps
+
+ ) : (
+ Koordinat belum tersedia
+ )}
+
+ ))}
+
+
-
-
+
+ {/* Right side - Single map showing all locations */}
+
+
+ Peta Lokasi
+ {data2?.some(v => v.lat && v.lng) ? (
+
+ v.lat && v.lng)
+ .map(v => ({
+ position: [v.lat, v.lng],
+ popup: v.namaTempatMaps
+ }))}
+ />
+
+ ) : (
+ Tidak ada koordinat yang tersedia
+ )}
+
-
+
);
}
export default Page;
+
diff --git a/src/app/darmasaba/(pages)/lingkungan/program-penghijauan/page.tsx b/src/app/darmasaba/(pages)/lingkungan/program-penghijauan/page.tsx
index ce52f6fc..489eb06d 100644
--- a/src/app/darmasaba/(pages)/lingkungan/program-penghijauan/page.tsx
+++ b/src/app/darmasaba/(pages)/lingkungan/program-penghijauan/page.tsx
@@ -1,71 +1,131 @@
+/* eslint-disable @typescript-eslint/no-explicit-any */
+'use client'
import colors from '@/con/colors';
-import { Box, Button, Center, Group, Paper, SimpleGrid, Stack, Text } from '@mantine/core';
-import { IconChristmasTreeFilled, IconHomeEco, IconShieldFilled, IconTrendingUp } from '@tabler/icons-react';
+import { Box, Button, Center, Group, Pagination, Paper, SimpleGrid, Skeleton, Stack, Text, TextInput, Title, Tooltip } from '@mantine/core';
+import { IconSearch, IconLeaf, IconTrophy, IconTent, IconChartLine, IconRecycle, IconTruckFilled, IconScale, IconClipboardTextFilled, IconTrashFilled, IconHomeEco, IconChristmasTreeFilled, IconTrendingUp, IconShieldFilled } from '@tabler/icons-react';
import BackButton from '../../desa/layanan/_com/BackButto';
+import programPenghijauanState from '@/app/admin/(dashboard)/_state/lingkungan/program-penghijauan';
+import { useProxy } from 'valtio/utils';
+import { useDebouncedValue, useShallowEffect } from '@mantine/hooks';
+import { useState } from 'react';
+import React from 'react';
-const data = [
- {
- id: 1,
- deskripsi: 'Lingkungan Sehat',
- icon: ,
- },
- {
- id: 2,
- deskripsi: 'Sumber Oksigen',
- icon: ,
- },
- {
- id: 3,
- deskripsi: 'Ekonomi Berkelanjutan',
- icon: ,
- },
- {
- id: 4,
- deskripsi: 'Mencegah Bencana',
- icon: ,
- },
-]
function Page() {
+ const state = useProxy(programPenghijauanState);
+ const [search, setSearch] = useState("");
+ const [debouncedSearch] = useDebouncedValue(search, 500);
+ const { data, load, page, totalPages, loading } = state.findMany;
+
+ useShallowEffect(() => {
+ load(page, 10, debouncedSearch);
+ }, [page, debouncedSearch]);
+
+ const iconMap: Record = {
+ ekowisata: IconLeaf,
+ kompetisi: IconTrophy,
+ wisata: IconTent,
+ ekonomi: IconChartLine,
+ sampah: IconRecycle,
+ truck: IconTruckFilled,
+ scale: IconScale,
+ clipboard: IconClipboardTextFilled,
+ trash: IconTrashFilled,
+ lingkunganSehat: IconHomeEco,
+ sumberOksigen: IconChristmasTreeFilled,
+ ekonomiBerkelanjutan: IconTrendingUp,
+ mencegahBencana: IconShieldFilled,
+ };
+
+ if (loading || !data) {
+ return (
+
+
+
+ );
+ }
+
return (
-
+
-
-
- Program Penghijauan Desa
+
+
+
+
+ Program Penghijauan Desa
+
+ }
+ value={search}
+ onChange={(e) => setSearch(e.currentTarget.value)}
+ />
+
+
+
+ Mari berpartisipasi menanam dan merawat pohon untuk menciptakan lingkungan hijau, sehat, dan seimbang bagi seluruh warga desa.
- Program Penghijauan Desa bertujuan untuk meningkatkan kesadaran masyarakat akan pentingnya lingkungan hijau melalui penanaman pohon dan perawatan tanaman.
-
- Manfaat Program Penghijauan
-
-
- {data.map((v, k) => {
- return (
-
-
-
-
);
diff --git a/src/app/darmasaba/(pages)/ppid/profile-ppid/page.tsx b/src/app/darmasaba/(pages)/ppid/profile-ppid/page.tsx
index 536b4bf2..6de605d3 100644
--- a/src/app/darmasaba/(pages)/ppid/profile-ppid/page.tsx
+++ b/src/app/darmasaba/(pages)/ppid/profile-ppid/page.tsx
@@ -3,119 +3,132 @@ import stateProfilePPID from '@/app/admin/(dashboard)/_state/ppid/profile_ppid/p
import colors from '@/con/colors';
import { Box, Center, Divider, Flex, Image, List, Paper, SimpleGrid, Skeleton, Stack, Text } from '@mantine/core';
import { useShallowEffect } from '@mantine/hooks';
+import { IconBuildingCommunity, IconTargetArrow, IconTimeline, IconUser } from '@tabler/icons-react';
import { useProxy } from 'valtio/utils';
import BackButton from '../../desa/layanan/_com/BackButto';
function Page() {
const allList = useProxy(stateProfilePPID)
useShallowEffect(() => {
- allList.profile.load("edit") // Assuming "1" is your default ID, adjust as needed
+ allList.profile.load("edit")
}, [])
- if (!allList.profile.data) return
-
-
-
-
-
-
-
-
- {Array.from({ length: 10 }).map((v, k) =>
-
- )}
-
-
-
+ if (!allList.profile.data) return (
+
+
+
+
+
+
+
+
+
+ {Array.from({ length: 8 }).map((_, i) => (
+
+ ))}
+
+
+
+ )
const dataArray = Array.isArray(allList.profile.data)
? allList.profile.data
- : [allList.profile.data];
+ : [allList.profile.data]
return (
-
+
-
- Profil Singkat PPID Desa Darmasaba
+
+ PPID Desa Darmasaba Profile
{dataArray.map((item) => (
-
+
-
-
- PROFIL PIMPINAN BADAN PUBLIK DESA DARMASABA
+
+
+
+ Public Information Officer
+
-
- {/* biodata perbekel */}
-
-
-
-
-
-
-
-
-
- >
-
+
+
+
+
+
+
+
+
+
+
{item.name}
+
-
- Biodata
-
-
-
- Riwayat Karir
-
-
+
+
+
+
+ Biography
+
+
+
+
+
+
+ Career History
+
+
+
+
-
- Pengalaman Organisasi
-
+
+
+
+
+ Organizational Experience
+
+
-
+
-
- Program Kerja Unggulan
-
+
+
+
+
+ Flagship Programs
+
+
-
+
-
))}
- );
+ )
}
-export default Page;
+export default Page
diff --git a/src/app/darmasaba/(pages)/ppid/struktur-ppid/page.tsx b/src/app/darmasaba/(pages)/ppid/struktur-ppid/page.tsx
index 86d877eb..5e8c40eb 100644
--- a/src/app/darmasaba/(pages)/ppid/struktur-ppid/page.tsx
+++ b/src/app/darmasaba/(pages)/ppid/struktur-ppid/page.tsx
@@ -1,121 +1,395 @@
/* eslint-disable react-hooks/exhaustive-deps */
/* eslint-disable @typescript-eslint/no-explicit-any */
-'use client'
-import stateStrukturPPID from '@/app/admin/(dashboard)/_state/ppid/struktur_ppid/struktur_PPID';
-import colors from '@/con/colors';
-import { Box, Image, Paper, Skeleton, Stack, Text, Title } from '@mantine/core';
-import { OrganizationChart } from 'primereact/organizationchart';
-import { useEffect } from 'react';
-import { useProxy } from 'valtio/utils';
-import BackButton from '../../desa/layanan/_com/BackButto';
+// /* eslint-disable react-hooks/exhaustive-deps */
+// /* eslint-disable @typescript-eslint/no-explicit-any */
+// 'use client'
+// import stateStrukturPPID from '@/app/admin/(dashboard)/_state/ppid/struktur_ppid/struktur_PPID';
+// import colors from '@/con/colors';
+// import { Box, Image, Paper, Skeleton, Stack, Text, Title } from '@mantine/core';
+// import { OrganizationChart } from 'primereact/organizationchart';
+// import { useEffect } from 'react';
+// import { useProxy } from 'valtio/utils';
+// import BackButton from '../../desa/layanan/_com/BackButto';
-function Page() {
- return (
-
-
-
-
- Struktur PPID
-
+// function Page() {
+// return (
+//
+//
+//
+//
+// Struktur PPID
+//
-
- );
+//
+// );
+// }
+
+// function StrukturOrganisasiPPID() {
+// const stateOrganisasi = useProxy(stateStrukturPPID.pegawai)
+
+// useEffect(() => {
+// stateOrganisasi.findMany.load()
+// }, [])
+
+// if (!stateOrganisasi.findMany.data || stateOrganisasi.findMany.data.length === 0) {
+// return (
+//
+//
+//
+// );
+// }
+
+// // Step 1: Group pegawai berdasarkan posisiId
+// const posisiMap = new Map();
+
+// for (const pegawai of stateOrganisasi.findMany.data) {
+// const posisiId = pegawai.posisi.id;
+// if (!posisiMap.has(posisiId)) {
+// posisiMap.set(posisiId, {
+// ...pegawai.posisi,
+// pegawaiList: [],
+// children: []
+// });
+// }
+// posisiMap.get(posisiId)!.pegawaiList.push(pegawai);
+// }
+
+
+// // Step 2: Buat struktur pohon berdasarkan parentId
+// const root: any[] = [];
+
+// posisiMap.forEach((posisi) => {
+// if (posisi.parentId) {
+// const parent = posisiMap.get(posisi.parentId);
+// if (parent) {
+// parent.children.push(posisi);
+// }
+// } else {
+// root.push(posisi);
+// }
+// });
+
+// // Step 3: Ubah struktur ke format OrganizationChart
+// function toOrgChartFormat(node: any): any {
+// return {
+// expanded: true,
+// type: 'person',
+// styleClass: 'p-person',
+// data: {
+// name: node.pegawaiList?.[0]?.namaLengkap || 'Tidak ada pegawai',
+// status: node.nama,
+// image: node.pegawaiList?.[0]?.image?.link || '/img/default.png'
+// },
+// children: node.children.map(toOrgChartFormat)
+// };
+// }
+
+
+// const chartData = root.map(toOrgChartFormat);
+
+// return (
+//
+//
+//
+//
+//
+// );
+// }
+
+
+// function nodeTemplate(node: any) {
+// const imageSrc = node?.data?.image || '/img/default.png';
+// const name = node?.data?.name || 'Tanpa Nama';
+// const status = node?.data?.status || 'Tidak ada deskripsi';
+
+// return (
+//
+//
+//
+// {name}
+// {status}
+//
+//
+// );
+// }
+
+// export default Page;
+
+'use client'
+import stateStrukturPPID from '@/app/admin/(dashboard)/_state/ppid/struktur_ppid/struktur_PPID'
+import {
+ Box,
+ Button,
+ Card,
+ Center,
+ Container,
+ Group,
+ Image,
+ Loader,
+ Paper,
+ Stack,
+ Text,
+ Title,
+ Tooltip,
+ Transition,
+} from '@mantine/core'
+import { IconRefresh, IconSearch, IconUsers } from '@tabler/icons-react'
+import { OrganizationChart } from 'primereact/organizationchart'
+import { useEffect } from 'react'
+import { useProxy } from 'valtio/utils'
+import BackButton from '../../desa/layanan/_com/BackButto'
+import colors from '@/con/colors'
+
+export default function Page() {
+ return (
+
+
+
+
+
+
+
+ Struktur Organisasi PPID
+
+
+ Gambaran visual peran dan pegawai yang ditugaskan. Arahkan kursor
+ untuk melihat detail atau klik node untuk fokus tampilan.
+
+
+
+
+
+
+
+ )
}
function StrukturOrganisasiPPID() {
- const stateOrganisasi = useProxy(stateStrukturPPID.pegawai)
+ const stateOrganisasi: any = useProxy(stateStrukturPPID.pegawai)
useEffect(() => {
- stateOrganisasi.findMany.load()
+ void stateOrganisasi.findMany.load()
}, [])
- if (!stateOrganisasi.findMany.data || stateOrganisasi.findMany.data.length === 0) {
+ const isLoading =
+ !stateOrganisasi.findMany.data &&
+ stateOrganisasi.findMany.loading !== false
+
+ if (isLoading) {
return (
-
-
-
- );
+
+
+
+ Memuat struktur organisasi…
+
+ Mengambil data pegawai dan posisi. Mohon tunggu sebentar.
+
+
+
+ )
}
- // Step 1: Group pegawai berdasarkan posisiId
- const posisiMap = new Map();
+ if (
+ !stateOrganisasi.findMany.data ||
+ stateOrganisasi.findMany.data.length === 0
+ ) {
+ return (
+
+
+
+
+
+
+
+ Data pegawai belum tersedia
+
+
+ Belum ada data pegawai yang tercatat untuk PPID. Silakan coba
+ muat ulang atau periksa sumber data.
+
+
+ }
+ variant="gradient"
+ gradient={{ from: 'indigo', to: 'cyan' }}
+ onClick={() => stateOrganisasi.findMany.load()}
+ >
+ Muat Ulang
+
+ }
+ variant="subtle"
+ onClick={() =>
+ stateOrganisasi.findMany.load({ query: { q: '' } })
+ }
+ >
+ Cari Pegawai
+
+
+
+
+
+ )
+ }
+ const posisiMap = new Map()
for (const pegawai of stateOrganisasi.findMany.data) {
- const posisiId = pegawai.posisi.id;
+ const posisiId = pegawai.posisi.id
if (!posisiMap.has(posisiId)) {
posisiMap.set(posisiId, {
...pegawai.posisi,
pegawaiList: [],
- children: []
- });
+ children: [],
+ })
}
- posisiMap.get(posisiId)!.pegawaiList.push(pegawai);
+ posisiMap.get(posisiId)!.pegawaiList.push(pegawai)
}
-
- // Step 2: Buat struktur pohon berdasarkan parentId
- const root: any[] = [];
-
+ const root: any[] = []
posisiMap.forEach((posisi) => {
if (posisi.parentId) {
- const parent = posisiMap.get(posisi.parentId);
+ const parent = posisiMap.get(posisi.parentId)
if (parent) {
- parent.children.push(posisi);
+ parent.children.push(posisi)
+ } else {
+ root.push(posisi)
}
} else {
- root.push(posisi);
+ root.push(posisi)
}
- });
+ })
- // Step 3: Ubah struktur ke format OrganizationChart
function toOrgChartFormat(node: any): any {
return {
expanded: true,
type: 'person',
styleClass: 'p-person',
data: {
- name: node.pegawaiList?.[0]?.namaLengkap || 'Tidak ada pegawai',
- status: node.nama,
- image: node.pegawaiList?.[0]?.image?.link || '/img/default.png'
+ name: node.pegawaiList?.[0]?.namaLengkap || 'Belum ditugaskan',
+ title: node.nama || 'Tanpa jabatan',
+ image: node.pegawaiList?.[0]?.image?.link || '/img/default.png',
+ description: node.deskripsi || '',
+ positionId: node.id || null,
},
- children: node.children.map(toOrgChartFormat)
- };
+ children: node.children?.map(toOrgChartFormat) || [],
+ }
}
-
- const chartData = root.map(toOrgChartFormat);
+ const chartData = root.map(toOrgChartFormat)
return (
-
-
-
+
+
+
- );
+ )
}
-
function nodeTemplate(node: any) {
- const imageSrc = node?.data?.image || '/img/default.png';
- const name = node?.data?.name || 'Tanpa Nama';
- const status = node?.data?.status || 'Tidak ada deskripsi';
+ const imageSrc = node?.data?.image || '/img/default.png'
+ const name = node?.data?.name || 'Tanpa Nama'
+ const title = node?.data?.title || 'Tanpa Jabatan'
+ const description = node?.data?.description || ''
return (
-
-
-
- {name}
- {status}
-
-
- );
+
+ {(styles) => (
+
+
+ {name}
+
+ {title}
+
+
+ {description || 'Belum ada deskripsi.'}
+
+
+ {
+ const id = node?.data?.positionId
+ if (id && (window as any).scrollTo) {
+ ;(window as any).scrollTo({ top: 0, behavior: 'smooth' })
+ }
+ }}
+ >
+ Detail
+
+
+
+ )}
+
+ )
}
-export default Page;
+
+
diff --git a/src/app/darmasaba/(tambahan)/apbdes/page.tsx b/src/app/darmasaba/(tambahan)/apbdes/page.tsx
index 5712a563..b3d419d4 100644
--- a/src/app/darmasaba/(tambahan)/apbdes/page.tsx
+++ b/src/app/darmasaba/(tambahan)/apbdes/page.tsx
@@ -1,112 +1,97 @@
/* eslint-disable react-hooks/exhaustive-deps */
+/* eslint-disable @typescript-eslint/no-explicit-any */
'use client'
-import colors from '@/con/colors';
-import { ActionIcon, BackgroundImage, Box, Center, Container, Flex, Group, SimpleGrid, Stack, Text } from '@mantine/core';
-import { IconDownload } from '@tabler/icons-react';
-import BackButton from '../../(pages)/desa/layanan/_com/BackButto';
-import apbdes from '@/app/admin/(dashboard)/_state/landing-page/apbdes';
-import { useProxy } from 'valtio/utils';
-import { useEffect, useState } from 'react';
-import { Link } from 'next-view-transitions';
+import apbdes from '@/app/admin/(dashboard)/_state/landing-page/apbdes'
+import colors from '@/con/colors'
+import { ActionIcon, BackgroundImage, Box, Center, Container, Group, Loader, SimpleGrid, Stack, Text, Title } from '@mantine/core'
+import { IconDownload } from '@tabler/icons-react'
+import { Link } from 'next-view-transitions'
+import { useEffect, useState } from 'react'
+import { useProxy } from 'valtio/utils'
+import BackButton from '../../(pages)/desa/layanan/_com/BackButto'
function Page() {
- const state = useProxy(apbdes);
- const [loading, setLoading] = useState(false);
+ const state = useProxy(apbdes)
+ const [loading, setLoading] = useState(false)
useEffect(() => {
const loadData = async () => {
try {
- setLoading(true);
- await state.findMany.load();
+ setLoading(true)
+ await state.findMany.load()
} catch (error) {
- console.error('Error loading data:', error);
+ console.error(error)
} finally {
- setLoading(false);
+ setLoading(false)
}
}
- loadData();
+ loadData()
}, [])
- const data = state.findMany.data || [];
+ const data = state.findMany.data || []
+
return (
-
-
-
-
-
- APBDes
-
-
- Transparansi APBDes Darmasaba adalah langkah nyata menuju tata kelola pemerintahan desa yang bersih dan bertanggung jawab. Adapun APBDes sebagai berikut:
+
+
+
+
+
+
+
+ Anggaran Pendapatan & Belanja Desa (APBDes)
+
+
+ Laporan transparansi APBDes Desa Darmasaba sebagai bentuk keterbukaan dan akuntabilitas pengelolaan anggaran desa.
-
- {loading ? (
-
+
+
+ Data penghargaan tidak tersedia
+
+
+ Silakan kembali dan pilih penghargaan lainnya
+
+
);
}
-
return (
-
+
-
-
-
+
+
+
{state.findUnique.data?.name}
-
+
-
- {new Date(state.findUnique.data?.createdAt).toLocaleDateString()}
-
-
-
-
+
+
+ Diterbitkan: {new Date(state.findUnique.data?.createdAt).toLocaleDateString('id-ID')}
+
+
+
+
+
-
-
+
+
+
+
-
-
+
+
+
+
-
-
+
+
+
+
-
-
+
+
-
+
diff --git a/src/app/darmasaba/(tambahan)/penghargaan/page.tsx b/src/app/darmasaba/(tambahan)/penghargaan/page.tsx
index fd315729..948cadbb 100644
--- a/src/app/darmasaba/(tambahan)/penghargaan/page.tsx
+++ b/src/app/darmasaba/(tambahan)/penghargaan/page.tsx
@@ -3,109 +3,131 @@
import penghargaanState from "@/app/admin/(dashboard)/_state/desa/penghargaan";
import colors from "@/con/colors";
import { Carousel, CarouselSlide } from "@mantine/carousel";
-import { Box, Button, Container, Group, Paper, Stack, Text, useMantineTheme } from "@mantine/core";
+import { Box, Button, Container, Group, Paper, Stack, Text, useMantineTheme, Skeleton } from "@mantine/core";
import { useMediaQuery } from "@mantine/hooks";
import Autoplay from "embla-carousel-autoplay";
+import { IconAward, IconArrowRight } from "@tabler/icons-react";
import { useTransitionRouter } from "next-view-transitions";
import { useEffect, useRef } from "react";
import { useProxy } from "valtio/utils";
import BackButton from "../../(pages)/desa/layanan/_com/BackButto";
export default function Page() {
- return (
-
-
-
-
-
-
-
- Penghargaan
-
-
- Desa Darmasaba telah berhasil meraih berbagai penghargaan bergengsi yang membuktikan dedikasi dan kerja keras seluruh elemen masyarakat dalam membangun desa yang maju dan berkelanjutan. Berikut ini adalah macam-macam penghargaan yang telah diraih oleh Desa Darmasaba:
-
-
-
-
+ return (
+
+
+
+
+
+
+
+
+
+ Penghargaan Desa
+
+
+
+ Desa Darmasaba berhasil meraih beragam penghargaan bergengsi yang mencerminkan dedikasi dan kerja keras masyarakat dalam membangun desa yang maju dan berkelanjutan.
+
+
- )
+
+
+ );
}
+
function Slider() {
- const height = 720;
- const width = 1200;
- const theme = useMantineTheme();
- const mobile = useMediaQuery(`(max-width: ${theme.breakpoints.sm})`);
- const autoplay = useRef(Autoplay({ delay: 2000 }));
- const state = useProxy(penghargaanState);
- const roter = useTransitionRouter()
+ const height = 500;
+ const width = 1200;
+ const theme = useMantineTheme();
+ const mobile = useMediaQuery(`(max-width: ${theme.breakpoints.sm})`);
+ const autoplay = useRef(Autoplay({ delay: 3000 }));
+ const state = useProxy(penghargaanState);
+ const router = useTransitionRouter();
- useEffect(() => {
- const loadData = async () => {
- try {
- await state.findMany.load();
- } catch (error) {
- console.error('Error loading data:', error);
- }
- }
- loadData();
- }, [])
+ useEffect(() => {
+ state.findMany.load();
+ }, []);
- const data = state.findMany.data || [];
-
- const slides = data.map((item) => (
-
-
-
-
-
-
- {item.name}
-
-
- roter.push(`/darmasaba/penghargaan/${item.id}`)} px={46} radius={"100"} size="md" bg={colors["blue-button"]}>
- Detail
-
-
-
-
-
-
- ));
+ const data = state.findMany.data || [];
+ const loading = state.findMany.loading;
+ if (loading) {
return (
-
- {slides}
-
+
+
+
+
+
);
-}
\ No newline at end of file
+ }
+
+ if (!loading && data.length === 0) {
+ return (
+
+
+
+ Belum ada penghargaan yang ditambahkan
+
+
+ );
+ }
+
+ const slides = data.map((item) => (
+
+
+
+
+
+ {item.name}
+
+
+ router.push(`/darmasaba/penghargaan/${item.id}`)}
+ size="md"
+ radius="xl"
+ rightSection={}
+ variant="gradient"
+ gradient={{ from: "#1C6EA4", to: "#69BFF8" }}
+ >
+ Lihat Detail
+
+
+
+
+
+ ));
+
+ return (
+
+ {slides}
+
+ );
+}
diff --git a/src/app/darmasaba/_com/Footer.tsx b/src/app/darmasaba/_com/Footer.tsx
index de6f1360..e25655af 100644
--- a/src/app/darmasaba/_com/Footer.tsx
+++ b/src/app/darmasaba/_com/Footer.tsx
@@ -1,207 +1,118 @@
'use client'
-import colors from '@/con/colors';
-import { ActionIcon, Anchor, Box, Center, Container, Divider, Flex, Group, Image, Paper, SimpleGrid, Stack, Text, TextInput, Title, useMantineTheme } from '@mantine/core';
-import { useMediaQuery } from '@mantine/hooks';
+import { ActionIcon, Anchor, Box, Button, Center, Container, Divider, Flex, Group, Image, Paper, SimpleGrid, Stack, Text, TextInput, Title } from '@mantine/core';
import { IconAt, IconBrandFacebook, IconBrandInstagram, IconBrandTwitter, IconBrandWhatsapp } from '@tabler/icons-react';
function Footer() {
- const theme = useMantineTheme();
- const mobile = useMediaQuery(`(max-width: ${theme.breakpoints.sm})`);
return (
- <>
-
-
-
-
-
-
-
-
- Komitmen Dalam Pelayanan
-
-
- 1. Transparansi:
-
- Kami berkomitmen untuk mengelola dana desa secara terbuka, sehingga masyarakat dapat
- mengetahui penggunaan anggaran secara jelas dan bertanggung jawab.
-
-
-
-
- 2. Profesionalisme:
-
-
- Setiap layanan desa akan dilakukan dengan profesional, cepat, dan tanpa diskriminasi,
- demi memastikan kepuasan masyarakat.
-
-
-
-
- 3. Partisipatif:
-
- Kami percaya bahwa partisipasi aktif masyarakat adalah kunci keberhasilan pembangunan desa.
- Oleh karena itu, kami akan terus melibatkan warga dalam setiap proses pengambilan keputusan.
-
-
-
-
- 4. Inovasi:
-
- Kami berkomitmen untuk terus berinovasi dalam memberikan solusi bagi permasalahan desa,
- termasuk melalui pemanfaatan teknologi untuk mempermudah akses layanan.
-
-
-
-
- 5. Berkeadilan:
-
- Setiap kebijakan dan program desa akan dirancang untuk memberikan manfaat yang merata
- bagi seluruh lapisan masyarakat, tanpa memandang status sosial atau ekonomi.
-
-
-
-
- 6. Pemberdayaan:
-
- Kami berkomitmen untuk memberdayakan masyarakat melalui pelatihan, pendampingan,
- dan dukungan terhadap usaha-usaha lokal agar desa semakin mandiri.
-
-
-
-
- 7. Ramah Lingkungan:
-
- Seluruh kegiatan pembangunan dan pelayanan desa akan memperhatikan keberlanjutan lingkungan,
- demi menjaga keseimbangan alam dan kenyamanan hidup warga.
-
-
-
-
-
-
-
-
- Tujuan Akhir
-
- Dengan visi, misi dan komitmen ini, kami bertekad untuk menjadikan desa sebagai tempat tinggal
- yang nyaman, aman dan sejahtera bagi seluruh warganya.
-
-
- Kami percaya bahwa kemajuan desa dimulai dari kerjasama antara pemerintah desa dan masyarakat,
- serta didukung oleh tata kelola yang baik dan berorientasi pada kepentingan bersama. Jika ada
- masukan untuk lembaga desa, silahkan hubungi pada nomor pengaduan di bawah, terima kasih.
-
-
-
-
- {"Desa Kuat, Masyarakat Sejahtera!"}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Tentang Darmasaba
- Desa Darmasaba adalah desa
- budaya yang kaya akan tradisi dan
- nilai-nilai luhur masyarakat Bali.
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ Komitmen Layanan Kami
+
+ {[
+ { title: "Transparansi", text: "Pengelolaan dana desa dilakukan secara terbuka agar masyarakat dapat memahami dan memantau penggunaan anggaran." },
+ { title: "Profesionalisme", text: "Layanan desa diberikan secara cepat, adil, dan profesional demi kepuasan masyarakat." },
+ { title: "Partisipasi", text: "Masyarakat dilibatkan aktif dalam pengambilan keputusan demi pembangunan desa yang berhasil." },
+ { title: "Inovasi", text: "Kami terus berinovasi, termasuk melalui teknologi, agar layanan semakin mudah diakses." },
+ { title: "Keadilan", text: "Kebijakan dan program disusun untuk memberi manfaat yang merata bagi seluruh warga." },
+ { title: "Pemberdayaan", text: "Masyarakat didukung melalui pelatihan, pendampingan, dan pengembangan usaha lokal." },
+ { title: "Ramah Lingkungan", text: "Seluruh kegiatan pembangunan memperhatikan keberlanjutan demi menjaga alam dan kesehatan warga." }
+ ].map((item, i) => (
+
+ {i + 1}. {item.title}:
+ {item.text}
+
+ ))}
+
+
+
+
+
+ Visi Kami
+
+ Dengan visi ini, kami berkomitmen menjadikan desa sebagai tempat yang aman, sejahtera, dan nyaman bagi seluruh warga.
+
+
+ Kami percaya kemajuan dimulai dari kerja sama antara pemerintah desa dan masyarakat, didukung tata kelola yang baik demi kepentingan bersama. Saran maupun keluhan dapat disampaikan melalui kontak di bawah ini.
+
+
+
+
+ "Desa Kuat, Warga Sejahtera!"
+
+
+
+
-
-
-
- Layanan
-
- Administrasi Kependudukan
-
-
- Pelayanan Sosial
-
-
- Pengaduan Masyarakat
-
-
- Informasi Publik
-
-
-
-
-
- Tautan Penting
-
- Portal Badung
-
-
- E-Government
-
-
- Transparansi
-
-
- Unduhan
-
-
-
-
-
- Newsletter
- Dapatkan informasi terbaru
- tentang kegiatan dan program
- desa
+
)}
- Sampaikan saran dan masukan guna kemajuan dalam pembangunan. Semua lebih mudah melalui fitur interaktif
+
+
+ Bagikan ide, kritik, atau saran Anda untuk mendukung pembangunan desa.
+ Semua lebih mudah dengan fitur interaktif yang kami sediakan.
+
-
+
{isLoading ? (
-
+
) : profile ? (
) : (
-
No profile available
+
+ Informasi profil belum tersedia
+
)}
-
+
);
}
diff --git a/src/app/darmasaba/_com/main-page/penghargaan/index.tsx b/src/app/darmasaba/_com/main-page/penghargaan/index.tsx
index 554472c2..995984b3 100644
--- a/src/app/darmasaba/_com/main-page/penghargaan/index.tsx
+++ b/src/app/darmasaba/_com/main-page/penghargaan/index.tsx
@@ -1,34 +1,33 @@
/* eslint-disable react-hooks/exhaustive-deps */
'use client';
import penghargaanState from "@/app/admin/(dashboard)/_state/desa/penghargaan";
-import colors from "@/con/colors";
-import { Stack, Box, Container, Button, Text } from "@mantine/core";
-import { useTransitionRouter } from 'next-view-transitions'
+import { Stack, Box, Container, Button, Text, Loader, Paper } from "@mantine/core";
+import { IconAward, IconArrowRight } from "@tabler/icons-react";
+import { useTransitionRouter } from 'next-view-transitions';
import { useEffect, useState } from "react";
import { useProxy } from "valtio/utils";
function Penghargaan() {
- const router = useTransitionRouter()
- const state = useProxy(penghargaanState)
- const [loading, setLoading] = useState(false)
+ const router = useTransitionRouter();
+ const state = useProxy(penghargaanState);
+ const [loading, setLoading] = useState(false);
useEffect(() => {
const loadData = async () => {
try {
- setLoading(true)
- await state.findMany.load()
- } catch (error) {
- console.error('Error loading data:', error)
+ setLoading(true);
+ await state.findMany.load();
} finally {
- setLoading(false)
+ setLoading(false);
}
- }
- loadData()
- }, [])
+ };
+ loadData();
+ }, []);
+
+ const data = state.findMany.data?.slice(0, 3);
- const data = state.findMany.data?.slice(0, 3)
return (
-
+
+ )}
+
- router.push("/darmasaba/desa/potensi")} color={colors["blue-button"]} variant="outline" radius={100} size="md">
- Selengkapnya
+ router.push("/darmasaba/desa/potensi")}
+ color={colors["blue-button"]}
+ variant="gradient"
+ gradient={{ from: "#26667F", to: "#124170", }}
+ radius="xl"
+ size="md"
+ rightSection={}
+ >
+ Lihat Semua Potensi
+
);
diff --git a/src/app/darmasaba/_com/main-page/prestasi/index.tsx b/src/app/darmasaba/_com/main-page/prestasi/index.tsx
index 1b7fed31..d9222063 100644
--- a/src/app/darmasaba/_com/main-page/prestasi/index.tsx
+++ b/src/app/darmasaba/_com/main-page/prestasi/index.tsx
@@ -2,104 +2,124 @@
'use client'
import prestasiState from "@/app/admin/(dashboard)/_state/landing-page/prestasi-desa";
import colors from "@/con/colors";
-import { BackgroundImage, Box, Button, Center, Container, Group, SimpleGrid, Stack, Text } from "@mantine/core";
+import { BackgroundImage, Box, Button, Center, Container, Group, Loader, SimpleGrid, Stack, Text } from "@mantine/core";
import { useProxy } from "valtio/utils";
import { useEffect, useState } from "react";
import { useRouter } from "next/navigation";
import Link from "next/link";
+import { IconTrophy } from "@tabler/icons-react";
function Prestasi() {
- const state = useProxy(prestasiState.prestasiDesa);
- const [loading, setLoading] = useState(false);
- const router = useRouter()
+ const state = useProxy(prestasiState.prestasiDesa);
+ const [loading, setLoading] = useState(false);
+ const router = useRouter();
- useEffect(() => {
- prestasiState.kategoriPrestasi.findMany.load()
- const loadData = async () => {
- try {
- setLoading(true);
- await state.findMany.load();
- } catch (error) {
- console.error('Error loading data:', error);
- } finally {
- setLoading(false);
- }
- }
- loadData();
- }, [])
+ useEffect(() => {
+ prestasiState.kategoriPrestasi.findMany.load();
+ const loadData = async () => {
+ try {
+ setLoading(true);
+ await state.findMany.load();
+ } finally {
+ setLoading(false);
+ }
+ };
+ loadData();
+ }, []);
- const data = (state.findMany.data || []).slice(0, 3);
- return (
- <>
-
-
- Prestasi Desa
- Kami bangga dengan apa yang telah dicapai desa kita hingga saat ini. Semoga prestasi ini menjadi inspirasi untuk terus berkarya dan berinovasi demi kemajuan bersama.
-
- Selengkapnya
-
-
-
-
- {loading ? (
-
- Memuat Data...
-
- ) : (
- data.map((v, k) => {
- return (
-
-
-
-
-
- {v.kategori.name}
-
-
-
-
- router.push(`/darmasaba/prestasi-desa/${v.id}`)} px={46} radius={"100"} size="md" bg={colors["blue-button"]}>
- Lihat Detail
-
-
-
-
- )
- })
- )}
-
-
+ const data = (state.findMany.data || []).slice(0, 3);
+
+ return (
+
+
+
+
+
+
+ Prestasi Desa
+
+
+
+ Kami bangga dengan pencapaian desa hingga saat ini. Semoga prestasi ini menjadi inspirasi untuk terus berkarya dan berinovasi demi kemajuan bersama.
+
+
+ Lihat Semua Prestasi
+
+
+
+
+
+ {loading ? (
+
+
+
+ ) : data.length === 0 ? (
+
+
+
+
+ Belum ada prestasi yang ditampilkan
+
- >
- )
+
+ ) : (
+
+ {data.map((v, k) => (
+
+
+
+
+
+ {v.kategori.name}
+
+
+
+
+ router.push(`/darmasaba/prestasi-desa/${v.id}`)}
+ radius="xl"
+ size="md"
+ color={colors["blue-button"]}
+ >
+ Detail Prestasi
+
+
+
+
+ ))}
+
+ )}
+
+
+ );
}
-export default Prestasi;
\ No newline at end of file
+
+export default Prestasi;
diff --git a/src/app/darmasaba/_com/main-page/sdgs/index.tsx b/src/app/darmasaba/_com/main-page/sdgs/index.tsx
index af2b564b..7588ae96 100644
--- a/src/app/darmasaba/_com/main-page/sdgs/index.tsx
+++ b/src/app/darmasaba/_com/main-page/sdgs/index.tsx
@@ -1,143 +1,142 @@
'use client'
-import colors from "@/con/colors";
-import { Box, Button, Center, Container, Image, Paper, SimpleGrid, Stack, Text, Title, useMantineTheme } from "@mantine/core";
-import { useMediaQuery } from "@mantine/hooks";
-import { Prisma } from "@prisma/client";
-import Link from "next/link";
-import { useEffect, useState } from "react";
+import { useEffect, useState } from "react"
+import { Box, Button, Center, Container, Image, Paper, SimpleGrid, Stack, Text, Title, useMantineTheme } from "@mantine/core"
+import { useMediaQuery } from "@mantine/hooks"
+import { Prisma } from "@prisma/client"
+import Link from "next/link"
+import { IconMoodSad } from "@tabler/icons-react"
export default function SDGS() {
- const theme = useMantineTheme();
- const mobile = useMediaQuery(`(max-width: ${theme.breakpoints.sm})`);
- const [sdgsDesa, setSdgsDesa] = useState[] | null>(null);
+ const theme = useMantineTheme()
+ const mobile = useMediaQuery(`(max-width: ${theme.breakpoints.sm})`)
+ const [sdgsDesa, setSdgsDesa] = useState[] | null>(null)
- useEffect(() => {
- const fetchSdgsDesa = async () => {
- try {
- const response = await fetch('/api/landingpage/sdgsdesa/findMany');
- if (!response.ok) {
- throw new Error(`HTTP error! status: ${response.status}`);
- }
- const result = await response.json();
- // Ensure the data is an array before setting it
- let data = [];
- if (Array.isArray(result.data)) {
- data = result.data;
- } else if (Array.isArray(result)) {
- // In case the API returns the array directly
- data = result;
- } else {
- console.error('Unexpected API response format:', result);
- setSdgsDesa([]);
- return;
- }
+ useEffect(() => {
+ const fetchSdgsDesa = async () => {
+ try {
+ const response = await fetch("/api/landingpage/sdgsdesa/findMany")
+ if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`)
+ const result = await response.json()
+ let data = []
+ if (Array.isArray(result.data)) data = result.data
+ else if (Array.isArray(result)) data = result
+ else {
+ setSdgsDesa([])
+ return
+ }
+ const top3Sdgs = [...data].sort((a, b) => parseInt(b.jumlah) - parseInt(a.jumlah)).slice(0, 3)
+ setSdgsDesa(top3Sdgs)
+ } catch {
+ setSdgsDesa([])
+ }
+ }
+ fetchSdgsDesa()
+ }, [])
- // Sort by jumlah in descending order and take top 3
- const top3Sdgs = [...data]
- .sort((a, b) => parseInt(b.jumlah) - parseInt(a.jumlah))
- .slice(0, 3);
+ return (
+
+
+
+
+ SDGs Desa
+
+
+
+ SDGs Desa adalah penerapan 17 Tujuan Pembangunan Berkelanjutan di tingkat desa. Fokus pada pengentasan kemiskinan,
+ pendidikan, kesehatan, kesetaraan gender, dan pelestarian lingkungan untuk menciptakan desa yang maju, inklusif, dan berkelanjutan.
+
- setSdgsDesa(top3Sdgs);
- } catch (error) {
- console.error('Error fetching sdgs desa:', error);
- setSdgsDesa([]);
- }
- };
-
- fetchSdgsDesa();
- }, []);
- return (
-
-
-
- SDGs Desa
-
- SDGs Desa adalah upaya menerapkan 17 Tujuan Pembangunan Berkelanjutan di tingkat desa.
- Dengan fokus pada pengentasan kemiskinan, pendidikan, kesehatan, kesetaraan gender, dan pelestarian lingkungan, kami berkomitmen untuk menciptakan desa yang lebih baik bagi semua
-
-
- {sdgsDesa && sdgsDesa.length > 0 ? (
-
- {sdgsDesa.map((item) => (
-
-
-
-
-
- {item.name}
-
-
- {item.jumlah}
-
-
- ))}
-
- ) : (
- Tidak ada data SDGs Desa
- )}
-
-