diff --git a/bun.lockb b/bun.lockb
index 0618a3a7..775d4131 100755
Binary files a/bun.lockb and b/bun.lockb differ
diff --git a/foldergambar/desa/name.png b/foldergambar/desa/name.png
new file mode 100644
index 00000000..8f31f48e
Binary files /dev/null and b/foldergambar/desa/name.png differ
diff --git a/foldergambar/desa/ppid/profile-ppid/name.png b/foldergambar/desa/ppid/profile-ppid/name.png
new file mode 100644
index 00000000..97ffac9e
Binary files /dev/null and b/foldergambar/desa/ppid/profile-ppid/name.png differ
diff --git a/package.json b/package.json
index 3f5f3a58..c9a52ec1 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "desa-darmasaba",
- "version": "0.1.1",
+ "version": "0.1.2",
"private": true,
"scripts": {
"dev": "next dev --turbopack",
@@ -16,6 +16,7 @@
"@cubejs-client/core": "^0.31.0",
"@elysiajs/cors": "^1.2.0",
"@elysiajs/eden": "^1.2.0",
+ "@elysiajs/static": "^1.3.0",
"@elysiajs/stream": "^1.1.0",
"@elysiajs/swagger": "^1.2.0",
"@mantine/carousel": "^7.16.2",
@@ -47,14 +48,16 @@
"elysia": "^1.2.12",
"embla-carousel-autoplay": "^8.5.2",
"embla-carousel-react": "^7.1.0",
+ "form-data": "^4.0.2",
"framer-motion": "^12.4.1",
"get-port": "^7.1.0",
"jotai": "^2.12.3",
"lodash": "^4.17.21",
"motion": "^12.4.1",
- "nanoid": "^5.1.0",
+ "nanoid": "^5.1.5",
"next": "15.1.6",
"next-view-transitions": "^0.3.4",
+ "node-fetch": "^3.3.2",
"p-limit": "^6.2.0",
"prisma": "^6.3.1",
"react": "^19.0.0",
@@ -64,6 +67,7 @@
"readdirp": "^4.1.1",
"recharts": "^2.15.3",
"swr": "^2.3.2",
+ "uuid": "^11.1.0",
"valtio": "^2.1.3",
"zod": "^3.24.3"
},
diff --git a/prisma/data/desa/profile/profil_perbekel.json b/prisma/data/desa/profile/profil_perbekel.json
new file mode 100644
index 00000000..3f846693
--- /dev/null
+++ b/prisma/data/desa/profile/profil_perbekel.json
@@ -0,0 +1,9 @@
+[
+ {
+ "id": "1",
+ "biodata": "
I.B Surya Prabhawa Manuaba, S.H., M.H., adalah Perbekel Darmasaba periode 2021-2027, seorang advokat, pendiri Mantra Legal Consultants & Advocates, serta aktif di bidang musik dan akademis. Dia menempuh pendidikan hukum di Universitas Udayana dan Universitas Mahasaraswati Denpasar serta memiliki pengalaman luas di berbagai organisasi dan kepemimpinan.
",
+ "pengalaman": "2021 - 2027: Perbekel Desa Darmasaba 2015 - Sekarang: Founder & Managing Director Mantra Legal Consultants & Advocates 2020 - Sekarang: Founder Ugawa Record Music Studio 2010 - 2016: Dosen Fakultas Hukum Universitas Mahasaraswati Denpasar ",
+ "pengalamanOrganisasi": " 1996 – 1997: Ketua OSIS SMP Negeri 1 Abiansemal 1999 – 2000: Ketua OSIS SMA Negeri 1 Mengwi 2008 – 2009: Ketua BEM Universitas Mahasaraswati Denpasar 2008 – 2010: Ketua Sekaa Taruna Sila Dharma, Banjar Tengah, Desa Adat Tegal, Darmasaba 2020 – Sekarang: Pengurus Young Lawyer Committee Peradi Denpasar 2021 – Sekarang: Dewan Kehormatan Himpunan Pengusaha Muda Indonesia (HIPMI) Badung 2023 – 2028: Komite Tetap Advokasi – Bidang Hukum dan Regulasi Kamar Dagang dan Industri Badung ",
+ "programUnggulan": "Pemberdayaan Ekonomi dan UMKM Pelatihan dan pendampingan UMKM lokal Program bantuan modal usaha bagi pelaku usaha kecil Digitalisasi UMKM untuk meningkatkan pemasaran produk lokal "
+ }
+]
\ No newline at end of file
diff --git a/prisma/data/desa/profile/profile_desa.json b/prisma/data/desa/profile/profile_desa.json
new file mode 100644
index 00000000..29ed4d8a
--- /dev/null
+++ b/prisma/data/desa/profile/profile_desa.json
@@ -0,0 +1,11 @@
+[
+ {
+ "id": "1",
+ "sejarah" : "Asal – usul nama Darmasaba tertuang dalam lontar Usada Bali. Seperti di tulis dalam monografi Desa Darmasaba tahun 1980 silam, nama Darmasaba berkaitan dengan keturunan Danghyang Nirarta diceritakan, Sang kawi-wiku asal Daha (Jawa Timur) itu memiliki cucu bernama Ida Pedanda Sakti Manuaba yang tigggal di Desa Kendran Tegalalang Gianyar. Merasa tidak disenangi sang ayah, Ida Pedanda Sakti Manuaba pergi mengembara bersama dua orang pengiringnya. Pengembaraan sang pendeta sampai di pura Sarin Buana di Jimbaran. Saat mengadakan semedi di tempat ini sang pendeta melihat sinar api. Yang sangat jauh di utara. Timbul keinginan Ida Pedanda Manuaba untuk mengunjungi tempat itu. Sampailah sang Pedanda di pura Batan Bila Peguyangan. Disini Ida Pedanda Manuaba singgah menghadap Ida Pedanda Budha yang tinggal disana. Selanjutnya, kedua pendeta bersama-sama menuju arah utara dan singgah di Taman Cang Ana, sebuah taman milik Arya Lanang Blusung. Di tempat ini kedua pendeta bersama-sama melaksanakan semedi dan menetap untuk sementara waktu.
",
+ "visi" : "Mewujudkan Desa Darmasaba yang sejahtera, unggul, religius, berbudaya, dan aman dengan berlandaskan Tri Hita Karana
",
+ "misi" : "Memperkokoh kerukunan hidup masyarakat dalam jalinan adat, budaya, olahraga, dan agama. Meningkatkan kualitas pelayanan publik dengan menerapkan teknologi informasi dan komunikasi terintegrasi. Meningkatkan tata kelola pemerintah desa dengan menerapkan prinsip good governance dan good clean government. Meningkatkan kualitas pendidikan, kesehatan, Keluarga Berencana serta pengelolaan kependudukan. Memperkuat usaha mikro kecil dan menengah (UMKM) dan BUMDesa sebagai pilar ekonomi masyarakat. Mewujudkan tatanan kehidupan bermasyarakat yang menjunjung tinggi penegakan hukum dan HAM. Meningkatkan perlindungan dan pengelolaan terhadap sumber daya alam dan lingkungan hidup. Memperkuat daya saing desa melalui peningkatan mutu sumber daya manusia dan infrastruktur desa berbasis potensi desa. Meningkatkan sinergisitas potensi budaya, pertanian dalam arti luas dan pariwisata. ",
+ "lambang" : "Memperkokoh kerukunan hidup masyarakat dalam jalinan adat, budaya, olahraga, dan agama. Meningkatkan kualitas pelayanan publik dengan menerapkan teknologi informasi dan komunikasi terintegrasi. Meningkatkan tata kelola pemerintah desa dengan menerapkan prinsip good governance dan good clean government. Meningkatkan kualitas pendidikan, kesehatan, Keluarga Berencana serta pengelolaan kependudukan. Memperkuat usaha mikro kecil dan menengah (UMKM) dan BUMDesa sebagai pilar ekonomi masyarakat. Mewujudkan tatanan kehidupan bermasyarakat yang menjunjung tinggi penegakan hukum dan HAM. Meningkatkan perlindungan dan pengelolaan terhadap sumber daya alam dan lingkungan hidup. Memperkuat daya saing desa melalui peningkatan mutu sumber daya manusia dan infrastruktur desa berbasis potensi desa. Meningkatkan sinergisitas potensi budaya, pertanian dalam arti luas dan pariwisata. Memperkuat daya saing desa melalui peningkatan mutu sumber daya manusia dan infrastruktur desa berbasis potensi desa. Meningkatkan sinergisitas potensi budaya, pertanian dalam arti luas dan pariwisata. ",
+ "maskot" : "Pudak adalah bunga dari tanaman sejenis pandan (Pandanaceae). Bentuk bunga ini tersusun dalam beberapa lapisan, terbungkus oleh kelopak warna putih (semacam daun lonjong) yang ujungnya meruncing.
Bunga Pudak berwarna kuning dan akan terlihat jika kelopak atau pelepahnya telah mekar. Kekhasan dari bunga pudak, yaitu mempunyai aroma wangi yang semerbak nan lembut (tidak menyengat), dan dapat menebar keharuman sepanjang pagi atau pun sore hari. Tanaman ini dapat tumbuh di sepanjang pantai, aliran sungai, di atas batu-batu karang, dan juga di tanah ladang.
Dalam Kamus Jawa Kuna- Indonesia kata “Pudak” berarti bunga pandan atau Pandanus Moschatus (Mardiwarsito: 1981: 442). Selain itu bunga pudak juga dapat disebut ketaka atau ketaki (Mardiwarsito, 1981: 276). Sedangkan kata “Sategal” berasal dari kata dasar “Tegal” yang berarti ladang (Mardiwarsito, 1981: 593). Jadi Pudak Sategal dapat diartikan sebagai satu ladang luas yang dipenuhi bunga pudak dan menabar keharuman.
Pada sebuah kesempatan, Ida Pedanda Putu Pemaron menjelaskan mengenai makna dari istilah Pudak Sategal dengan sebuah analogi bahwa, sekuntum bunga pudak memiliki aroma wangi atau keharuman yang sangat kuat, apalagi jika satu ladang penuh bunga pudak, maka dapat dipastikan aroma keharumannya akan membumbung menyebar ke segala penjuru (Wawancara, 18 Mei 2019 di Geria Putra Mandara Kenderan, Tegallalang). “Pudak” ialah sebuah bunga yang memiliki aroma wangi atau keharuman yang semerbak, lembut, dan khas.
Garapan Tari Maskot Desa Darmasaba Sekar Pudak diwujudkan ke dalam bentuk tari kreasi yang ditarikan secara berkelompok dengan jumlah lima orang penari perempuan (putri).
Pemilihan penari perempuan dimaksudkan untuk mempresentasikan keindahan, keluwesan, dan keharuman dari bunga pudak. Sedangkan penetapan jumlah penari lima orang didasarkan atas pertimbangan kebutuhan koreografi agar dapat membentuk desain-desain komposisi lantai yang menarik dan dinamis, baik ketika ditarikan di area panggung yang luas atau pun area panggung yang kecil. Penyajian tari maskot ini dirancang dengan durasi waktu 9 menit.
",
+ "profilPerbekelId" : "1"
+ }
+]
\ No newline at end of file
diff --git a/prisma/data/katagory-berita.json b/prisma/data/kategori-berita.json
similarity index 100%
rename from prisma/data/katagory-berita.json
rename to prisma/data/kategori-berita.json
diff --git a/prisma/data/list-caraMemperolehInformasi.json b/prisma/data/list-caraMemperolehInformasi.json
new file mode 100644
index 00000000..c3f7fdad
--- /dev/null
+++ b/prisma/data/list-caraMemperolehInformasi.json
@@ -0,0 +1,5 @@
+[
+ {"name": "Melihat/Membaca/Mendengarkan/Mencatat"},
+ {"name": "Mendapatkan Salinan Informasi (Hardcopy)"},
+ {"name": "Mendapatkan Salinan Informasi (Softcopy)"}
+]
\ No newline at end of file
diff --git a/prisma/data/list-caraMemperolehSalinanInformasi.json b/prisma/data/list-caraMemperolehSalinanInformasi.json
new file mode 100644
index 00000000..6587f648
--- /dev/null
+++ b/prisma/data/list-caraMemperolehSalinanInformasi.json
@@ -0,0 +1,5 @@
+[
+ { "name": "Mengambil Langsung" },
+ { "name": "Dikirim Via Post" },
+ { "name": "Dikirim Via Email" }
+]
diff --git a/prisma/data/list-jenisInfromasi.json b/prisma/data/list-jenisInfromasi.json
new file mode 100644
index 00000000..393523e8
--- /dev/null
+++ b/prisma/data/list-jenisInfromasi.json
@@ -0,0 +1,6 @@
+[
+ { "name": "Keuangan Desa" },
+ { "name": "Pembangunan Desa" },
+ { "name": "Data Demografi" },
+ { "name": "Lainnya" }
+]
diff --git a/prisma/data/ppid/daftar-informasi-publik-desa-darmasaba/daftarInformasi.json b/prisma/data/ppid/daftar-informasi-publik-desa-darmasaba/daftarInformasi.json
new file mode 100644
index 00000000..a3209314
--- /dev/null
+++ b/prisma/data/ppid/daftar-informasi-publik-desa-darmasaba/daftarInformasi.json
@@ -0,0 +1,8 @@
+[
+ {
+ "id": "1",
+ "jenisInformasi": "Peraturan Desa",
+ "deskripsi": "Dokumen yang berisi kebijakan dan regulasi desa",
+ "tanggal": "15 Januari 2024"
+ }
+]
\ No newline at end of file
diff --git a/prisma/data/ppid/dasar-hukum-ppid/dasarhukumPPID.json b/prisma/data/ppid/dasar-hukum-ppid/dasarhukumPPID.json
new file mode 100644
index 00000000..a81befaf
--- /dev/null
+++ b/prisma/data/ppid/dasar-hukum-ppid/dasarhukumPPID.json
@@ -0,0 +1,7 @@
+[
+ {
+ "id": "1",
+ "judul": "DASAR HUKUM PEMBENTUKAN PPID DESA DARMASABA",
+ "content" : "UU Nomor 14 Tahun 2008 tentang Keterbukaan Informasi Publik PP Nomor 61 Tahun 2010 tentang Pelaksanaan UU 14 Tahun 2008 tentang Keterbukaan Informasi Publik Permendagri Nomor 3 Tahun 2017 tentang Pedoman Pengelolaan Pelayanan Informasi dan Dokumentasi di Lingkungan Kemendagri dan Pemerintah Daerah Peraturan Komisi Informasi Nomor 1 Tahun 2010 tentang Standar Layanan Informasi Publik Peraturan Komisi Informasi Nomor 1 Tahun 2010 tentang Standar Layanan Informasi Publik Peraturan Bupati Badung No. 42 Tahun 2017 tentang Pedoman Pengelolaan Pelayanan Informasi Publik dan Dokumentasi di Lingkungan Pemerintah Kabupaten Badung Keputusan Bupati Badung Nomor 99/049/HK/2019 tentang Pengelola Layanan Informasi dan Dokumentasi Kabupaten Badung Keputusan Perbekel Darmasaba Nomor 101 Tahun 2019 tentang Penetapan Pelaksana Teknis/Administrasi Pengelola Layanan Informasi Dan Dokumentasi di Desa Punggul Peraturan Perbekel Darmasaba Nomor 12 Tahun 2019 tentang Pedoman Pengelolaan Pelayanan Informasi Publik dan Dokumentasi di Lingkungan Pemerintah Desa Darmasaba "
+ }
+]
\ No newline at end of file
diff --git a/prisma/data/ppid/profile-ppid/profilePPid.json b/prisma/data/ppid/profile-ppid/profilePPid.json
new file mode 100644
index 00000000..3727382c
--- /dev/null
+++ b/prisma/data/ppid/profile-ppid/profilePPid.json
@@ -0,0 +1,11 @@
+[
+ {
+ "id": "1",
+ "name": "I.B Surya Prabhawa Manuaba, S.H., M.H.",
+ "biodata": "I.B Surya Prabhawa Manuaba, S.H., M.H., adalah Perbekel Darmasaba periode 2021-2027, seorang advokat, pendiri Mantra Legal Consultants & Advocates, serta aktif di bidang musik dan akademis. Dia menempuh pendidikan hukum di Universitas Udayana dan Universitas Mahasaraswati Denpasar, serta memiliki pengalaman luas di berbagai organisasi dan kepemimpinan.
",
+ "riwayat": " 2021 - 2027: Perbekel Desa Darmasaba 2015 - Sekarang: Founder & Managing Director Mantra Legal Consultants & Advocates 2020 - Sekarang: Founder Ugawa Record Music Studio 2010 - 2016: Dosen Fakultas Hukum Universitas Mahasaraswati Denpasar ",
+ "pengalaman": " 1996 – 1997: Ketua OSIS SMP Negeri 1 Abiansemal 1999 – 2000: Ketua OSIS SMA Negeri 1 Mengwi 2008 – 2009: Ketua BEM Universitas Mahasaraswati Denpasar 2008 – 2010: Ketua Sekaa Taruna Sila Dharma, Banjar Tengah, Desa Adat Tegal, Darmasaba 2020 – Sekarang: Pengurus Young Lawyer Committee Peradi Denpasar 2021 – Sekarang: Dewan Kehormatan Himpunan Pengusaha Muda Indonesia (HIPMI) Badung 2023 – 2028: Komite Tetap Advokasi – Bidang Hukum dan Regulasi Kamar Dagang dan Industri Badung ",
+ "unggulan": "Pemberdayaan Ekonomi dan UMKM Pelatihan dan pendampingan UMKM lokal Program bantuan modal usaha bagi pelaku usaha kecil Digitalisasi UMKM untuk meningkatkan pemasaran produk lokal ",
+ "imageUrl": "/uploads/seeded-images/profile-ppid/perbekel.png"
+ }
+]
diff --git a/prisma/data/ppid/visi-misi-ppid/visimisiPPID.json b/prisma/data/ppid/visi-misi-ppid/visimisiPPID.json
new file mode 100644
index 00000000..a0eb4ab3
--- /dev/null
+++ b/prisma/data/ppid/visi-misi-ppid/visimisiPPID.json
@@ -0,0 +1,8 @@
+[
+ {
+ "id": "1",
+ "misi": "Meningkatkan pengelolaan dan pelayanan informasi yang berkualitas, benar dan bertanggung jawab. Membangun dan mengembangkan sistem penyediaan dan layanan informasi. Meningkatkan dan mengembangkan kompetensi dan kualitas SDM dalam bidang pelayanan informasi. Mewujudkan keterbukaan informasi Pemerintah Desa Punggul dengan proses yang cepat, tepat, mudah dan sederhana. ",
+ "visi": "Memberikan pelayanan informasi yanng transparan dan akuntabel untuk memenuhi hak pemohon informasi sesuai dengan ketentuan peraturan perundang-undangan yang berlaku."
+
+ }
+]
\ No newline at end of file
diff --git a/prisma/schema.prisma b/prisma/schema.prisma
index 4bce5939..4c0d39cb 100644
--- a/prisma/schema.prisma
+++ b/prisma/schema.prisma
@@ -47,23 +47,213 @@ model AppMenuChild {
appMenuId String?
}
+//========================================= MENU PPID ========================================= //
+// ========================================= VISI MISI PPID ========================================= //
+model VisiMisiPPID {
+ id String @id @default(cuid())
+ visi String @db.Text
+ misi String @db.Text
+ createdAt DateTime @default(now())
+ updatedAt DateTime @updatedAt
+ deletedAt DateTime @default(now())
+ isActive Boolean @default(true)
+}
+
+// ========================================= DASAR HUKUM PPID ========================================= //
+model DasarHukumPPID {
+ id String @id @default(cuid())
+ judul String @db.Text
+ content String @db.Text
+ createdAt DateTime @default(now())
+ updatedAt DateTime @updatedAt
+ deletedAt DateTime @default(now())
+ isActive Boolean @default(true)
+}
+
+// ========================================= PROFILE PPID ========================================= //
+model ProfilePPID {
+ id String @id @default(cuid())
+ name String @db.Text
+ biodata String @db.Text
+ riwayat String @db.Text
+ pengalaman String @db.Text
+ unggulan String @db.Text
+ imageUrl String?
+ createdAt DateTime @default(now())
+ updatedAt DateTime @updatedAt
+ deletedAt DateTime @default(now())
+ isActive Boolean @default(true)
+}
+
+// ========================================= DAFTAR INFORMASI PUBLIK ========================================= //
+model DaftarInformasiPublik {
+ id String @id @default(cuid())
+ nomor Int @default(autoincrement())
+ jenisInformasi String
+ deskripsi String
+ tanggal String
+ createdAt DateTime @default(now())
+ updatedAt DateTime @updatedAt
+ deletedAt DateTime @default(now())
+ isActive Boolean @default(true)
+}
+
+//=========================================PERMOHONAN INFORMASI PUBLIK========================= //
+model PermohonanInformasiPublik {
+ id String @id @default(cuid())
+ nomor Int @default(autoincrement())
+ name String
+ nik String
+ notelp String
+ alamat String
+ email String
+ jenisInformasiDiminta JenisInformasiDiminta? @relation(fields: [jenisInformasiDimintaId], references: [id])
+ jenisInformasiDimintaId String?
+ caraMemperolehInformasi CaraMemperolehInformasi? @relation(fields: [caraMemperolehInformasiId], references: [id])
+ caraMemperolehInformasiId String?
+ caraMemperolehSalinanInformasi CaraMemperolehSalinanInformasi? @relation(fields: [caraMemperolehSalinanInformasiId], references: [id])
+ caraMemperolehSalinanInformasiId String?
+ createdAt DateTime @default(now())
+ updatedAt DateTime @updatedAt
+ deletedAt DateTime @default(now())
+ isActive Boolean @default(true)
+}
+
+model JenisInformasiDiminta {
+ id String @id @default(cuid())
+ name String @unique
+ createdAt DateTime @default(now())
+ updatedAt DateTime @updatedAt
+ deletedAt DateTime @default(now())
+ isActive Boolean @default(true)
+ PermohonanInformasiPublik PermohonanInformasiPublik[]
+}
+
+model CaraMemperolehInformasi {
+ id String @id @default(cuid())
+ name String @unique
+ createdAt DateTime @default(now())
+ updatedAt DateTime @updatedAt
+ deletedAt DateTime @default(now())
+ isActive Boolean @default(true)
+ PermohonanInformasiPublik PermohonanInformasiPublik[]
+}
+
+model CaraMemperolehSalinanInformasi {
+ id String @id @default(cuid())
+ name String @unique
+ createdAt DateTime @default(now())
+ updatedAt DateTime @updatedAt
+ deletedAt DateTime @default(now())
+ isActive Boolean @default(true)
+ PermohonanInformasiPublik PermohonanInformasiPublik[]
+}
+
+//=========================================PERMOHONAN INFORMASI KEBERATAN PUBLIK========================= //
+model FormulirPermohonanKeberatan {
+ id String @id @default(cuid())
+ name String
+ email String
+ notelp String
+ alasan String
+ createdAt DateTime @default(now())
+ updatedAt DateTime @updatedAt
+ deletedAt DateTime @default(now())
+ isActive Boolean @default(true)
+}
+
+// ========================================= IKM ========================================= //
+model IndeksKepuasanMasyarakat {
+ id Int @id @default(autoincrement())
+ label String
+ kepuasan String
+ createdAt DateTime @default(now())
+ updatedAt DateTime @updatedAt
+ deletedAt DateTime @default(now())
+ isActive Boolean @default(true)
+}
+
+model GrafikBerdasarkanJenisKelamin {
+ id String @id @default(cuid())
+ perempuan String
+ laki String
+ createdAt DateTime @default(now())
+ updatedAt DateTime @updatedAt
+ deletedAt DateTime @default(now())
+ isActive Boolean @default(true)
+}
+
+model GrafikBerdasarkanResponden {
+ id String @id @default(cuid())
+ sangatbaik String
+ baik String
+ kurangbaik String
+ tidakbaik String
+ createdAt DateTime @default(now())
+ updatedAt DateTime @updatedAt
+ deletedAt DateTime @default(now())
+ isActive Boolean @default(true)
+}
+
+model GrafikBerdasarkanUmur {
+ id String @id @default(cuid())
+ remaja String
+ dewasa String
+ orangtua String
+ lansia String
+ createdAt DateTime @default(now())
+ updatedAt DateTime @updatedAt
+ deletedAt DateTime @default(now())
+ isActive Boolean @default(true)
+}
+
// ========================================= MENU DESA ========================================= //
+// ========================================= PROFILE DESA ========================================= //
+model ProfileDesa {
+ id String @id @default(cuid())
+ sejarah String @db.Text
+ visi String @db.Text
+ misi String @db.Text
+ lambang String @db.Text
+ maskot String @db.Text
+ ProfilPerbekel ProfilPerbekel? @relation(fields: [profilPerbekelId], references: [id])
+ profilPerbekelId String?
+ createdAt DateTime @default(now())
+ updatedAt DateTime @updatedAt
+ deletedAt DateTime @default(now())
+ isActive Boolean @default(true)
+}
+
+model ProfilPerbekel {
+ id String @id @default(cuid())
+ biodata String @db.Text
+ pengalaman String @db.Text
+ pengalamanOrganisasi String @db.Text
+ programUnggulan String @db.Text
+ ProfileDesa ProfileDesa[]
+ createdAt DateTime @default(now())
+ updatedAt DateTime @updatedAt
+ deletedAt DateTime @default(now())
+ isActive Boolean @default(true)
+}
+
// ========================================= BERITA ========================================= //
model Berita {
id String @id @default(cuid())
judul String
deskripsi String
- image String
+ image FileStorage @relation(fields: [imageId], references: [id])
+ imageId String
content String @db.Text
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
deletedAt DateTime @default(now())
isActive Boolean @default(true)
- KatagoryBerita KatagoryBerita? @relation(fields: [katagoryBeritaId], references: [id])
- katagoryBeritaId String?
+ kategoriBerita KategoriBerita? @relation(fields: [kategoriBeritaId], references: [id])
+ kategoriBeritaId String?
}
-model KatagoryBerita {
+model KategoriBerita {
id String @id @default(cuid())
name String @unique
beritas Berita[]
@@ -323,3 +513,89 @@ model GrafikKepuasan {
deletedAt DateTime @default(now())
isActive Boolean @default(true)
}
+
+// ========================================= ARTIKEL KESEHATAN ========================================= //
+model ArtikelKesehatan {
+ id Int @id @default(autoincrement())
+ title String
+ content String
+ createdAt DateTime @default(now())
+ updatedAt DateTime @updatedAt
+ deletedAt DateTime @default(now())
+ isActive Boolean @default(true)
+}
+
+model Introduction {
+ id Int @id @default(autoincrement())
+ content String
+ createdAt DateTime @default(now())
+ updatedAt DateTime @updatedAt
+ deletedAt DateTime @default(now())
+ isActive Boolean @default(true)
+}
+
+model Symptom {
+ id Int @id @default(autoincrement())
+ title String
+ content String
+ createdAt DateTime @default(now())
+ updatedAt DateTime @updatedAt
+ deletedAt DateTime @default(now())
+ isActive Boolean @default(true)
+}
+
+model Prevention {
+ id Int @id @default(autoincrement())
+ title String
+ content String
+ createdAt DateTime @default(now())
+ updatedAt DateTime @updatedAt
+ deletedAt DateTime @default(now())
+ isActive Boolean @default(true)
+}
+
+model FirstAid {
+ id Int @id @default(autoincrement())
+ title String
+ content String
+ createdAt DateTime @default(now())
+ updatedAt DateTime @updatedAt
+ deletedAt DateTime @default(now())
+ isActive Boolean @default(true)
+}
+
+model MythVsFact {
+ id Int @id @default(autoincrement())
+ title String
+ mitos String
+ fakta String
+ createdAt DateTime @default(now())
+ updatedAt DateTime @updatedAt
+ deletedAt DateTime @default(now())
+ isActive Boolean @default(true)
+}
+
+model DoctorSign {
+ id Int @id @default(autoincrement())
+ content String
+ createdAt DateTime @default(now())
+ updatedAt DateTime @updatedAt
+ deletedAt DateTime @default(now())
+ isActive Boolean @default(true)
+}
+
+// === BARU
+
+model FileStorage {
+ id String @id @default(cuid())
+ name String @unique
+ realName String
+ path String
+ mimeType String
+ createdAt DateTime @default(now())
+ updatedAt DateTime @updatedAt
+ deletedAt DateTime?
+ isActive Boolean @default(true)
+ link String
+ Berita Berita[]
+}
diff --git a/prisma/seed-images/perbekel.png b/prisma/seed-images/perbekel.png
new file mode 100644
index 00000000..ed1cbd10
Binary files /dev/null and b/prisma/seed-images/perbekel.png differ
diff --git a/prisma/seed.ts b/prisma/seed.ts
index 5f296d13..6cd35bf2 100644
--- a/prisma/seed.ts
+++ b/prisma/seed.ts
@@ -1,82 +1,277 @@
-import layanan from './data/list-layanan.json'
-import potensi from './data/list-potensi.json'
-import katagoryBerita from './data/katagory-berita.json'
-import categoryPengumuman from './data/category-pengumuman.json'
-import prisma from '@/lib/prisma';
+import prisma from "@/lib/prisma";
+import categoryPengumuman from "./data/category-pengumuman.json";
+import kategoriBerita from "./data/kategori-berita.json";
+import caraMemperolehInformasi from "./data/list-caraMemperolehInformasi.json";
+import caraMemperolehSalinanInformasi from "./data/list-caraMemperolehSalinanInformasi.json";
+import jenisInformasiDiminta from "./data/list-jenisInfromasi.json";
+import layanan from "./data/list-layanan.json";
+import potensi from "./data/list-potensi.json";
+import visiMisiPPID from "./data/ppid/visi-misi-ppid/visimisiPPID.json";
+import dasarHukumPPID from "./data/ppid/dasar-hukum-ppid/dasarhukumPPID.json";
+import profileDesa from "./data/desa/profile/profile_desa.json";
+import profilePerbekel from "./data/desa/profile/profil_perbekel.json";
+import profilePPID from "./data/ppid/profile-ppid/profilePPid.json";
+import path from "path";
+import fs from "fs";
+import { mkdir, writeFile } from "fs/promises";
+import { v4 as uuid } from "uuid";
+
(async () => {
- for (const l of layanan) {
- await prisma.layanan.upsert({
- where: {
- name: l.name
- },
- update: {
- name: l.name
- },
- create: {
- name: l.name
- }
- })
+ for (const l of layanan) {
+ await prisma.layanan.upsert({
+ where: {
+ name: l.name,
+ },
+ update: {
+ name: l.name,
+ },
+ create: {
+ name: l.name,
+ },
+ });
+ }
+
+ console.log("layanan success ...");
+
+ for (const p of potensi) {
+ await prisma.potensi.upsert({
+ where: {
+ name: p.name,
+ },
+ update: {
+ name: p.name,
+ },
+ create: {
+ name: p.name,
+ },
+ });
+ }
+
+ console.log("potensi success ...");
+
+ for (const k of kategoriBerita) {
+ await prisma.kategoriBerita.upsert({
+ where: {
+ name: k.name,
+ },
+ update: {
+ name: k.name,
+ },
+ create: {
+ name: k.name,
+ },
+ });
+ }
+
+ console.log("kategori berita success ...");
+
+ for (const c of categoryPengumuman) {
+ await prisma.categoryPengumuman.upsert({
+ where: {
+ name: c.name,
+ },
+ update: {
+ name: c.name,
+ },
+ create: {
+ name: c.name,
+ },
+ });
+ }
+
+ console.log("category pengumuman success ...");
+
+ for (const j of jenisInformasiDiminta) {
+ await prisma.jenisInformasiDiminta.upsert({
+ where: {
+ name: j.name,
+ },
+ update: {
+ name: j.name,
+ },
+ create: {
+ name: j.name,
+ },
+ });
+ }
+ console.log("jenis informasi diminta success ...");
+
+ for (const c of caraMemperolehInformasi) {
+ await prisma.caraMemperolehInformasi.upsert({
+ where: {
+ name: c.name,
+ },
+ update: {
+ name: c.name,
+ },
+ create: {
+ name: c.name,
+ },
+ });
+ }
+ console.log("cara memperoleh informasi success ...");
+
+ for (const c of caraMemperolehSalinanInformasi) {
+ await prisma.caraMemperolehSalinanInformasi.upsert({
+ where: {
+ name: c.name,
+ },
+ update: {
+ name: c.name,
+ },
+ create: {
+ name: c.name,
+ },
+ });
+ }
+ console.log("cara memperoleh salinan informasi success ...");
+
+ const seedProfilePPID = async () => {
+ const targetDir = path.resolve("public", "uploads", "seeded-images", "profile-ppid")
+
+ // Buat folder hanya jika belum ada
+ if (!fs.existsSync(targetDir)) {
+ await mkdir(targetDir, { recursive: true })
}
-
- console.log("layanan success ...")
-
- for (const p of potensi) {
- await prisma.potensi.upsert({
- where: {
- name: p.name
- },
- update: {
- name: p.name
- },
- create: {
- name: p.name
- }
- })
+
+ for (const c of profilePPID) {
+ let finalImageUrl = c.imageUrl
+
+ if (c.imageUrl.startsWith("/uploads/seeded-images/")) {
+ const filename = path.basename(c.imageUrl)
+ const seedImagePath = path.resolve("prisma", "seed-images", filename)
+
+ const targetFilename = `${uuid()}_${filename}`
+ const targetPath = path.join(targetDir, targetFilename)
+
+ const buffer = fs.readFileSync(seedImagePath)
+ await writeFile(targetPath, buffer)
+
+ finalImageUrl = `/uploads/seeded-images/profile-ppid/${targetFilename}`
+ }
+
+ await prisma.profilePPID.upsert({
+ where: { id: c.id },
+ update: {
+ name: c.name,
+ biodata: c.biodata,
+ riwayat: c.riwayat,
+ pengalaman: c.pengalaman,
+ unggulan: c.unggulan,
+ imageUrl: finalImageUrl,
+ },
+ create: {
+ id: c.id,
+ name: c.name,
+ biodata: c.biodata,
+ riwayat: c.riwayat,
+ pengalaman: c.pengalaman,
+ unggulan: c.unggulan,
+ imageUrl: finalImageUrl,
+ },
+ })
}
+
+ console.log("✅ profilePPID seeded from JSON with image copying")
+ }
+
+ await seedProfilePPID()
- console.log("potensi success ...")
+ for (const v of visiMisiPPID) {
+ await prisma.visiMisiPPID.upsert({
+ where: {
+ id: v.id,
+ },
+ update: {
+ misi: v.misi,
+ visi: v.visi,
+ },
+ create: {
+ id: v.id,
+ misi: v.misi,
+ visi: v.visi,
+ },
+ });
+ }
+ console.log("visi misi PPID success ...");
- for (const k of katagoryBerita) {
- await prisma.katagoryBerita.upsert({
- where: {
- name: k.name
- },
- update: {
- name: k.name
- },
- create: {
- name: k.name
- }
- })
- }
+ for (const v of dasarHukumPPID) {
+ await prisma.dasarHukumPPID.upsert({
+ where: {
+ id: v.id,
+ },
+ update: {
+ judul: v.judul,
+ content: v.content,
+ },
+ create: {
+ id: v.id,
+ judul: v.judul,
+ content: v.content,
+ },
+ });
+ }
+ console.log("dasar hukum PPID success ...");
- console.log("katagory berita success ...")
+ for (const v of profileDesa) {
+ await prisma.profileDesa.upsert({
+ where: {
+ id: v.id,
+ },
+ update: {
+ sejarah: v.sejarah,
+ visi: v.visi,
+ misi: v.misi,
+ lambang: v.lambang,
+ maskot: v.maskot,
+ profilPerbekelId: v.profilPerbekelId,
+ },
+ create: {
+ id: v.id,
+ sejarah: v.sejarah,
+ visi: v.visi,
+ misi: v.misi,
+ lambang: v.lambang,
+ maskot: v.maskot,
+ profilPerbekelId: v.profilPerbekelId,
+ },
+ });
+ }
+ console.log("profile desa success ...");
- for (const c of categoryPengumuman) {
- await prisma.categoryPengumuman.upsert({
- where: {
- name: c.name
- },
- update: {
- name: c.name
- },
- create: {
- name: c.name
- }
- })
- }
+ for (const v of profilePerbekel) {
+ await prisma.profilPerbekel.upsert({
+ where: {
+ id: v.id,
+ },
+ update: {
+ biodata: v.biodata,
+ pengalaman: v.pengalaman,
+ pengalamanOrganisasi: v.pengalamanOrganisasi,
+ programUnggulan: v.programUnggulan,
+ },
+ create: {
+ id: v.id,
+ biodata: v.biodata,
+ pengalaman: v.pengalaman,
+ pengalamanOrganisasi: v.pengalamanOrganisasi,
+ programUnggulan: v.programUnggulan,
+ },
+ });
+ }
+ console.log("profile perbekel success ...");
+})()
+ .then(() => prisma.$disconnect())
+ .catch((e) => {
+ console.error(e);
+ prisma.$disconnect();
+ });
- console.log("category pengumuman success ...")
-})().then(() => prisma.$disconnect()).catch((e) => {
- console.error(e)
- prisma.$disconnect()
+process.on("exit", () => {
+ prisma.$disconnect();
});
-process.on('exit', () => {
- prisma.$disconnect()
-})
-
-process.on('SIGINT', () => {
- prisma.$disconnect()
- process.exit(0)
-})
\ No newline at end of file
+process.on("SIGINT", () => {
+ prisma.$disconnect();
+ process.exit(0);
+});
diff --git a/public/assets/images/ppid/profile-ppid/1585618b-aec2-4b6c-a8a6-08e9c6eefa79_perbekel.png b/public/assets/images/ppid/profile-ppid/1585618b-aec2-4b6c-a8a6-08e9c6eefa79_perbekel.png
new file mode 100644
index 00000000..ed1cbd10
Binary files /dev/null and b/public/assets/images/ppid/profile-ppid/1585618b-aec2-4b6c-a8a6-08e9c6eefa79_perbekel.png differ
diff --git a/public/assets/images/ppid/profile-ppid/1_1747623028993_berita-pemerintahan.jpg b/public/assets/images/ppid/profile-ppid/1_1747623028993_berita-pemerintahan.jpg
new file mode 100644
index 00000000..6b0e5be3
Binary files /dev/null and b/public/assets/images/ppid/profile-ppid/1_1747623028993_berita-pemerintahan.jpg differ
diff --git a/public/assets/images/ppid/profile-ppid/1_1747820179116_berita-pemerintahan.jpg b/public/assets/images/ppid/profile-ppid/1_1747820179116_berita-pemerintahan.jpg
new file mode 100644
index 00000000..6b0e5be3
Binary files /dev/null and b/public/assets/images/ppid/profile-ppid/1_1747820179116_berita-pemerintahan.jpg differ
diff --git a/public/assets/images/ppid/profile-ppid/1_1747835389645_capybara.png b/public/assets/images/ppid/profile-ppid/1_1747835389645_capybara.png
new file mode 100644
index 00000000..16a01d4c
Binary files /dev/null and b/public/assets/images/ppid/profile-ppid/1_1747835389645_capybara.png differ
diff --git a/public/assets/images/ppid/profile-ppid/1_1747836129969_bgDesktop.jpg b/public/assets/images/ppid/profile-ppid/1_1747836129969_bgDesktop.jpg
new file mode 100644
index 00000000..9a7f9d24
Binary files /dev/null and b/public/assets/images/ppid/profile-ppid/1_1747836129969_bgDesktop.jpg differ
diff --git a/public/assets/images/ppid/profile-ppid/1_1747836263333_capybara.png b/public/assets/images/ppid/profile-ppid/1_1747836263333_capybara.png
new file mode 100644
index 00000000..16a01d4c
Binary files /dev/null and b/public/assets/images/ppid/profile-ppid/1_1747836263333_capybara.png differ
diff --git a/public/assets/images/ppid/profile-ppid/1_1747836558027_capybara.png b/public/assets/images/ppid/profile-ppid/1_1747836558027_capybara.png
new file mode 100644
index 00000000..16a01d4c
Binary files /dev/null and b/public/assets/images/ppid/profile-ppid/1_1747836558027_capybara.png differ
diff --git a/public/assets/images/ppid/profile-ppid/1_1747836664305_capybara.png b/public/assets/images/ppid/profile-ppid/1_1747836664305_capybara.png
new file mode 100644
index 00000000..16a01d4c
Binary files /dev/null and b/public/assets/images/ppid/profile-ppid/1_1747836664305_capybara.png differ
diff --git a/public/assets/images/ppid/profile-ppid/1_1747894445049_capybara.png b/public/assets/images/ppid/profile-ppid/1_1747894445049_capybara.png
new file mode 100644
index 00000000..16a01d4c
Binary files /dev/null and b/public/assets/images/ppid/profile-ppid/1_1747894445049_capybara.png differ
diff --git a/public/assets/images/ppid/profile-ppid/1_1747971309851_perbekel.png b/public/assets/images/ppid/profile-ppid/1_1747971309851_perbekel.png
new file mode 100644
index 00000000..ed1cbd10
Binary files /dev/null and b/public/assets/images/ppid/profile-ppid/1_1747971309851_perbekel.png differ
diff --git a/public/assets/images/ppid/profile-ppid/4bd7c413-c88b-487d-8572-9b61df6c1251_perbekel.png b/public/assets/images/ppid/profile-ppid/4bd7c413-c88b-487d-8572-9b61df6c1251_perbekel.png
new file mode 100644
index 00000000..ed1cbd10
Binary files /dev/null and b/public/assets/images/ppid/profile-ppid/4bd7c413-c88b-487d-8572-9b61df6c1251_perbekel.png differ
diff --git a/public/assets/images/ppid/profile-ppid/77004be4-0ec0-4ed2-a0a1-4e4ea6a9f4ad_perbekel.png b/public/assets/images/ppid/profile-ppid/77004be4-0ec0-4ed2-a0a1-4e4ea6a9f4ad_perbekel.png
new file mode 100644
index 00000000..ed1cbd10
Binary files /dev/null and b/public/assets/images/ppid/profile-ppid/77004be4-0ec0-4ed2-a0a1-4e4ea6a9f4ad_perbekel.png differ
diff --git a/public/assets/images/ppid/profile-ppid/7ede98a1-a154-480c-a0f6-5dca983fdef3_perbekel.png b/public/assets/images/ppid/profile-ppid/7ede98a1-a154-480c-a0f6-5dca983fdef3_perbekel.png
new file mode 100644
index 00000000..ed1cbd10
Binary files /dev/null and b/public/assets/images/ppid/profile-ppid/7ede98a1-a154-480c-a0f6-5dca983fdef3_perbekel.png differ
diff --git a/public/uploads/profile-ppid/1_1747885424609_budaya-1.jpg b/public/uploads/profile-ppid/1_1747885424609_budaya-1.jpg
new file mode 100644
index 00000000..9cd84d04
Binary files /dev/null and b/public/uploads/profile-ppid/1_1747885424609_budaya-1.jpg differ
diff --git a/public/uploads/seeded-images/ppid/profile-ppid/1_1747836703445_capybara.png b/public/uploads/seeded-images/ppid/profile-ppid/1_1747836703445_capybara.png
new file mode 100644
index 00000000..16a01d4c
Binary files /dev/null and b/public/uploads/seeded-images/ppid/profile-ppid/1_1747836703445_capybara.png differ
diff --git a/public/uploads/seeded-images/ppid/profile-ppid/1_1747836821689_capybara.png b/public/uploads/seeded-images/ppid/profile-ppid/1_1747836821689_capybara.png
new file mode 100644
index 00000000..16a01d4c
Binary files /dev/null and b/public/uploads/seeded-images/ppid/profile-ppid/1_1747836821689_capybara.png differ
diff --git a/public/uploads/seeded-images/ppid/profile-ppid/1_1747839042145_capybara.png b/public/uploads/seeded-images/ppid/profile-ppid/1_1747839042145_capybara.png
new file mode 100644
index 00000000..16a01d4c
Binary files /dev/null and b/public/uploads/seeded-images/ppid/profile-ppid/1_1747839042145_capybara.png differ
diff --git a/public/uploads/seeded-images/profile-ppid/021b212f-097f-4c2a-a5e5-273d7458c8da_perbekel.png b/public/uploads/seeded-images/profile-ppid/021b212f-097f-4c2a-a5e5-273d7458c8da_perbekel.png
new file mode 100644
index 00000000..ed1cbd10
Binary files /dev/null and b/public/uploads/seeded-images/profile-ppid/021b212f-097f-4c2a-a5e5-273d7458c8da_perbekel.png differ
diff --git a/public/uploads/seeded-images/profile-ppid/20202f69-857c-463a-b524-c407e50401c8_perbekel.png b/public/uploads/seeded-images/profile-ppid/20202f69-857c-463a-b524-c407e50401c8_perbekel.png
new file mode 100644
index 00000000..ed1cbd10
Binary files /dev/null and b/public/uploads/seeded-images/profile-ppid/20202f69-857c-463a-b524-c407e50401c8_perbekel.png differ
diff --git a/public/uploads/seeded-images/profile-ppid/47ef008b-bf7f-467f-8c8e-bf9259a08656_perbekel.png b/public/uploads/seeded-images/profile-ppid/47ef008b-bf7f-467f-8c8e-bf9259a08656_perbekel.png
new file mode 100644
index 00000000..ed1cbd10
Binary files /dev/null and b/public/uploads/seeded-images/profile-ppid/47ef008b-bf7f-467f-8c8e-bf9259a08656_perbekel.png differ
diff --git a/public/uploads/seeded-images/profile-ppid/54ad4911-4752-413b-8242-b8fbd0309df4_perbekel.png b/public/uploads/seeded-images/profile-ppid/54ad4911-4752-413b-8242-b8fbd0309df4_perbekel.png
new file mode 100644
index 00000000..ed1cbd10
Binary files /dev/null and b/public/uploads/seeded-images/profile-ppid/54ad4911-4752-413b-8242-b8fbd0309df4_perbekel.png differ
diff --git a/public/uploads/seeded-images/profile-ppid/64ed4abc-9a5a-40d8-afd4-042c408ec092_perbekel.png b/public/uploads/seeded-images/profile-ppid/64ed4abc-9a5a-40d8-afd4-042c408ec092_perbekel.png
new file mode 100644
index 00000000..ed1cbd10
Binary files /dev/null and b/public/uploads/seeded-images/profile-ppid/64ed4abc-9a5a-40d8-afd4-042c408ec092_perbekel.png differ
diff --git a/public/uploads/seeded-images/profile-ppid/664e4fbc-af1e-4e5f-aecd-4fdbf728c74d_perbekel.png b/public/uploads/seeded-images/profile-ppid/664e4fbc-af1e-4e5f-aecd-4fdbf728c74d_perbekel.png
new file mode 100644
index 00000000..ed1cbd10
Binary files /dev/null and b/public/uploads/seeded-images/profile-ppid/664e4fbc-af1e-4e5f-aecd-4fdbf728c74d_perbekel.png differ
diff --git a/public/uploads/seeded-images/profile-ppid/8e492234-e95e-4672-9041-d5c4f611d7fb_perbekel.png b/public/uploads/seeded-images/profile-ppid/8e492234-e95e-4672-9041-d5c4f611d7fb_perbekel.png
new file mode 100644
index 00000000..ed1cbd10
Binary files /dev/null and b/public/uploads/seeded-images/profile-ppid/8e492234-e95e-4672-9041-d5c4f611d7fb_perbekel.png differ
diff --git a/public/uploads/seeded-images/profile-ppid/90db5197-b0c1-441a-8585-bc33758cc3a9_perbekel.png b/public/uploads/seeded-images/profile-ppid/90db5197-b0c1-441a-8585-bc33758cc3a9_perbekel.png
new file mode 100644
index 00000000..ed1cbd10
Binary files /dev/null and b/public/uploads/seeded-images/profile-ppid/90db5197-b0c1-441a-8585-bc33758cc3a9_perbekel.png differ
diff --git a/public/uploads/seeded-images/profile-ppid/a146af5a-e48d-4c19-8350-2383a3e3be22_perbekel.png b/public/uploads/seeded-images/profile-ppid/a146af5a-e48d-4c19-8350-2383a3e3be22_perbekel.png
new file mode 100644
index 00000000..ed1cbd10
Binary files /dev/null and b/public/uploads/seeded-images/profile-ppid/a146af5a-e48d-4c19-8350-2383a3e3be22_perbekel.png differ
diff --git a/public/uploads/seeded-images/profile-ppid/a85625e1-cbd4-4869-b809-6f27bc4979b2_perbekel.png b/public/uploads/seeded-images/profile-ppid/a85625e1-cbd4-4869-b809-6f27bc4979b2_perbekel.png
new file mode 100644
index 00000000..ed1cbd10
Binary files /dev/null and b/public/uploads/seeded-images/profile-ppid/a85625e1-cbd4-4869-b809-6f27bc4979b2_perbekel.png differ
diff --git a/public/uploads/seeded-images/profile-ppid/bbfed5d8-a1f1-4087-a542-d7f7c9935bd8_perbekel.png b/public/uploads/seeded-images/profile-ppid/bbfed5d8-a1f1-4087-a542-d7f7c9935bd8_perbekel.png
new file mode 100644
index 00000000..ed1cbd10
Binary files /dev/null and b/public/uploads/seeded-images/profile-ppid/bbfed5d8-a1f1-4087-a542-d7f7c9935bd8_perbekel.png differ
diff --git a/public/uploads/seeded-images/profile-ppid/cdd3cd52-c9c4-4c96-a29d-728a774b5955_perbekel.png b/public/uploads/seeded-images/profile-ppid/cdd3cd52-c9c4-4c96-a29d-728a774b5955_perbekel.png
new file mode 100644
index 00000000..ed1cbd10
Binary files /dev/null and b/public/uploads/seeded-images/profile-ppid/cdd3cd52-c9c4-4c96-a29d-728a774b5955_perbekel.png differ
diff --git a/public/uploads/seeded-images/profile-ppid/e658ba55-fa8a-4f0d-bcbd-78de12b2ce33_perbekel.png b/public/uploads/seeded-images/profile-ppid/e658ba55-fa8a-4f0d-bcbd-78de12b2ce33_perbekel.png
new file mode 100644
index 00000000..ed1cbd10
Binary files /dev/null and b/public/uploads/seeded-images/profile-ppid/e658ba55-fa8a-4f0d-bcbd-78de12b2ce33_perbekel.png differ
diff --git a/public/uploads/seeded-images/profile-ppid/perbekel.png b/public/uploads/seeded-images/profile-ppid/perbekel.png
new file mode 100644
index 00000000..ed1cbd10
Binary files /dev/null and b/public/uploads/seeded-images/profile-ppid/perbekel.png differ
diff --git a/src/app/admin/(dashboard)/_com/modalKonfirmasiHapus.tsx b/src/app/admin/(dashboard)/_com/modalKonfirmasiHapus.tsx
new file mode 100644
index 00000000..d8805319
--- /dev/null
+++ b/src/app/admin/(dashboard)/_com/modalKonfirmasiHapus.tsx
@@ -0,0 +1,35 @@
+// components/modal/ModalKonfirmasiHapus.tsx
+import { Modal, Text, Button, Flex } from "@mantine/core"
+
+interface ModalKonfirmasiHapusProps {
+ opened: boolean
+ loading?: boolean
+ onClose: () => void
+ onConfirm: () => void
+ text: string
+}
+
+export function ModalKonfirmasiHapus({
+ opened,
+ loading = false,
+ onClose,
+ onConfirm,
+ text,
+}: ModalKonfirmasiHapusProps) {
+ return (
+
+ {text}
+
+ Batal
+
+ Yakin Hapus
+
+
+
+ )
+}
diff --git a/src/app/admin/(dashboard)/_state/desa/berita.ts b/src/app/admin/(dashboard)/_state/desa/berita.ts
index 817c5127..64245619 100644
--- a/src/app/admin/(dashboard)/_state/desa/berita.ts
+++ b/src/app/admin/(dashboard)/_state/desa/berita.ts
@@ -1,23 +1,34 @@
-/* eslint-disable @typescript-eslint/no-explicit-any */
+
import ApiFetch from "@/lib/api-fetch";
import { Prisma } from "@prisma/client";
import { toast } from "react-toastify";
import { proxy } from "valtio";
import { z } from "zod";
+// 1. Schema validasi dengan Zod
const templateForm = z.object({
judul: z.string().min(3, "Judul minimal 3 karakter"),
deskripsi: z.string().min(3, "Deskripsi minimal 3 karakter"),
- image: z.string().url().min(3, "Image minimal 3 karakter"),
content: z.string().min(3, "Content minimal 3 karakter"),
- katagoryBeritaId: z.string().nonempty(),
+ kategoriBeritaId: z.string().nonempty(),
+ imageId: z.string().nonempty(),
});
+// 2. Default value form berita (hindari uncontrolled input)
+const defaultForm = {
+ judul: "",
+ deskripsi: "",
+ imageId: "",
+ content: "",
+ kategoriBeritaId: "",
+};
+
+// 3. Kategori proxy
const category = proxy({
findMany: {
data: null as
| null
- | Prisma.KatagoryBeritaGetPayload<{ omit: { isActive: true } }>[],
+ | Prisma.KategoriBeritaGetPayload<{ omit: { isActive: true } }>[],
async load() {
const res = await ApiFetch.api.desa.berita.category["find-many"].get();
if (res.status === 200) {
@@ -27,23 +38,12 @@ const category = proxy({
},
});
-type BeritaForm = Prisma.BeritaGetPayload<{
- select: {
- judul: true;
- deskripsi: true;
- image: true;
- content: true;
- katagoryBeritaId: true;
- };
-}>;
-
+// 4. Berita proxy
const berita = proxy({
create: {
- form: {} as BeritaForm,
+ form: { ...defaultForm }, // ✅ ini kunci fix-nya
loading: false,
async create() {
- berita.create.form.image =
- "https://www.shutterstock.com/image-vector/lower-news-live-streaming-breaking-600nw-2535984111.jpg";
const cek = templateForm.safeParse(berita.create.form);
if (!cek.success) {
const err = `[${cek.error.issues
@@ -51,6 +51,7 @@ const berita = proxy({
.join("\n")}] required`;
return toast.error(err);
}
+
try {
berita.create.loading = true;
const res = await ApiFetch.api.desa.berita["create"].post(
@@ -58,7 +59,7 @@ const berita = proxy({
);
if (res.status === 200) {
berita.findMany.load();
- return toast.success("succes create");
+ return toast.success("success create");
}
return toast.error("failed create");
@@ -68,20 +69,62 @@ const berita = proxy({
berita.create.loading = false;
}
},
+ resetForm() {
+ berita.create.form = { ...defaultForm };
+ },
},
+
findMany: {
data: null as
- | Prisma.BeritaGetPayload<{ omit: { isActive: true } }>[]
+ | Prisma.BeritaGetPayload<{
+ include: {
+ image: true;
+ kategoriBerita: true;
+ };
+ }>[]
| null,
async load() {
const res = await ApiFetch.api.desa.berita["find-many"].get();
if (res.status === 200) {
- berita.findMany.data = (res.data?.data as any) ?? [];
+ berita.findMany.data = (res.data?.data ) ?? [];
}
},
},
+ delete: {
+ loading: false,
+ async byId(id: string) {
+ if (!id) return toast.warn("ID tidak valid");
+
+ try {
+ berita.delete.loading = true;
+
+ const response = await fetch(`/api/desa/berita/delete/${id}`, {
+ method: 'DELETE',
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ });
+
+ const result = await response.json();
+
+ if (response.ok && result?.success) {
+ toast.success(result.message || "Berita berhasil dihapus");
+ await berita.findMany.load(); // refresh list
+ } else {
+ toast.error(result?.message || "Gagal menghapus berita");
+ }
+ } catch (error) {
+ console.error("Gagal delete:", error);
+ toast.error("Terjadi kesalahan saat menghapus berita");
+ } finally {
+ berita.delete.loading = false;
+ }
+ },
+ },
+
});
+// 5. State global
const stateDashboardBerita = proxy({
category,
berita,
diff --git a/src/app/admin/(dashboard)/_state/desa/profile.ts b/src/app/admin/(dashboard)/_state/desa/profile.ts
new file mode 100644
index 00000000..744b426d
--- /dev/null
+++ b/src/app/admin/(dashboard)/_state/desa/profile.ts
@@ -0,0 +1,239 @@
+import ApiFetch from "@/lib/api-fetch";
+import { Prisma } from "@prisma/client";
+import { toast } from "react-toastify";
+import { proxy } from "valtio";
+import { z } from "zod";
+
+/* Sejarah */
+const templateFormSejarahForm = z.object({
+ sejarah: z.string().min(3, "Sejarah minimal 3 karakter"),
+})
+
+type SejarahForm = Prisma.ProfileDesaGetPayload<{
+ select: {
+ id: true;
+ sejarah: true;
+ }
+}>
+
+const Sejarah = proxy({
+ findById: {
+ data: null as SejarahForm | null,
+ loading: false,
+ initialize() {
+ Sejarah.findById.data = {
+ id: "",
+ sejarah: "",
+ } as SejarahForm;
+ },
+ async load(id: string) {
+ try {
+ Sejarah.findById.loading = true;
+ const res = await ApiFetch.api.desa.profile["find-by-id"].get({
+ query: { id },
+ });
+ if (res.status === 200) {
+ Sejarah.findById.data = {
+ id: id,
+ sejarah: res.data?.data?.sejarah ?? ""
+ };
+ } else {
+ toast.error("Gagal mengambil data sejarah");
+ }
+ } catch (error) {
+ console.error((error as Error).message);
+ toast.error("Terjadi kesalahan saat mengambil data sejarah");
+ } finally {
+ Sejarah.findById.loading = false;
+ }
+ }
+ },
+ update: {
+ loading: false,
+ async save(data: SejarahForm) {
+ const cek = templateFormSejarahForm.safeParse(data);
+ if (!cek.success) {
+ const errors = cek.error.issues
+ .map((issue) => `${issue.path.join(".")}: ${issue.message}`)
+ .join(", ");
+ toast.error(`Form tidak valid: ${errors}`);
+ return;
+ }
+ try {
+ Sejarah.update.loading = true;
+ const res = await ApiFetch.api.desa.profile.sejarah["update"].post(data);
+ if (res.status === 200) {
+ toast.success("Berhasil update sejarah");
+ await Sejarah.findById.load(data.id);
+ } else {
+ toast.error("Gagal update sejarah");
+ }
+ } catch (error) {
+ console.error((error as Error).message);
+ toast.error("Terjadi kesalahan saat update sejarah");
+ } finally {
+ Sejarah.update.loading = false;
+ }
+ }
+ }
+})
+
+/* Visi Misi Desa */
+const templateFormVisiForm = z.object({
+ visi: z.string().min(3, "Visi minimal 3 karakter"),
+ misi: z.string().min(3, "Misi minimal 3 karakter")
+})
+
+type VisiMisiDesaForm = Prisma.ProfileDesaGetPayload<{
+ select: {
+ id: true;
+ visi: true;
+ misi: true;
+ }
+}>
+
+const VisiMisiDesa = proxy({
+ findById: {
+ data: null as VisiMisiDesaForm | null,
+ loading: false,
+ initialize() {
+ VisiMisiDesa.findById.data = {
+ id: "",
+ visi: "",
+ misi: ""
+ } as VisiMisiDesaForm;
+ },
+ async load(id: string) {
+ try {
+ VisiMisiDesa.findById.loading = true;
+ const res = await ApiFetch.api.desa.profile["find-by-id"].get({
+ query: { id },
+ });
+ if (res.status === 200) {
+ VisiMisiDesa.findById.data = {
+ id: id,
+ visi: res.data?.data?.visi ?? "",
+ misi: res.data?.data?.misi ?? ""
+ };
+ } else {
+ toast.error("Gagal mengambil data visi misi");
+ }
+ } catch (error) {
+ console.error((error as Error).message);
+ toast.error("Terjadi kesalahan saat mengambil data visi misi");
+ } finally {
+ VisiMisiDesa.findById.loading = false;
+ }
+ }
+ },
+ update: {
+ loading: false,
+ async save(data: VisiMisiDesaForm) {
+ const cek = templateFormVisiForm.safeParse(data);
+ if (!cek.success) {
+ const errors = cek.error.issues
+ .map((issue) => `${issue.path.join(".")}: ${issue.message}`)
+ .join(", ");
+ toast.error(`Form tidak valid: ${errors}`);
+ return;
+ }
+ try {
+ VisiMisiDesa.update.loading = true;
+ const res = await ApiFetch.api.desa.profile.visimisiDesa["update"].post(data);
+ if (res.status === 200) {
+ toast.success("Berhasil update visi misi");
+ await VisiMisiDesa.findById.load(data.id);
+ } else {
+ toast.error("Gagal update visi");
+ }
+ } catch (error) {
+ console.error((error as Error).message);
+ toast.error("Terjadi kesalahan saat update visi misi");
+ } finally {
+ VisiMisiDesa.update.loading = false;
+ }
+ }
+ }
+})
+/* Lambang Desa */
+const templateFormLambangDesaForm = z.object({
+ lambang: z.string().min(3, "Lambang minimal 3 karakter"),
+})
+
+type LambangDesaForm = Prisma.ProfileDesaGetPayload<{
+ select: {
+ id: true;
+ lambang: true;
+ }
+}>
+
+const LambangDesa = proxy({
+ findById: {
+ data: null as LambangDesaForm | null,
+ loading: false,
+ initialize() {
+ LambangDesa.findById.data = {
+ id: "",
+ lambang: "",
+ } as LambangDesaForm;
+ },
+ async load(id: string) {
+ try {
+ LambangDesa.findById.loading = true;
+ const res = await ApiFetch.api.desa.profile["find-by-id"].get({
+ query: { id },
+ });
+ if (res.status === 200) {
+ LambangDesa.findById.data = {
+ id: id,
+ lambang: res.data?.data?.lambang ?? ""
+ };
+ } else {
+ toast.error("Gagal mengambil data lambang desa");
+ }
+ } catch (error) {
+ console.error((error as Error).message);
+ toast.error("Terjadi kesalahan saat mengambil data lambang desa");
+ } finally {
+ LambangDesa.findById.loading = false;
+ }
+ }
+ },
+ update: {
+ loading: false,
+ async save(data: LambangDesaForm) {
+ const cek = templateFormLambangDesaForm.safeParse(data);
+ if (!cek.success) {
+ const errors = cek.error.issues
+ .map((issue) => `${issue.path.join(".")}: ${issue.message}`)
+ .join(", ");
+ toast.error(`Form tidak valid: ${errors}`);
+ return;
+ }
+ try {
+ LambangDesa.update.loading = true;
+ const res = await ApiFetch.api.desa.profile.lambangDesa["update"].post(data);
+ if (res.status === 200) {
+ toast.success("Berhasil update lambang desa");
+ await LambangDesa.findById.load(data.id);
+ } else {
+ toast.error("Gagal update lambang desa");
+ }
+ } catch (error) {
+ console.error((error as Error).message);
+ toast.error("Terjadi kesalahan saat update lambang desa");
+ } finally {
+ LambangDesa.update.loading = false;
+ }
+ }
+ }
+});
+
+const stateProfileDesa = {
+ Sejarah,
+ VisiMisiDesa,
+ LambangDesa,
+};
+
+
+export default stateProfileDesa;
diff --git a/src/app/admin/(dashboard)/_state/kesehatan/data_kesehatan_warga/artikelKesehatan.ts b/src/app/admin/(dashboard)/_state/kesehatan/data_kesehatan_warga/artikelKesehatan.ts
new file mode 100644
index 00000000..e750a7c9
--- /dev/null
+++ b/src/app/admin/(dashboard)/_state/kesehatan/data_kesehatan_warga/artikelKesehatan.ts
@@ -0,0 +1,339 @@
+import ApiFetch from "@/lib/api-fetch";
+import { Prisma } from "@prisma/client";
+import { toast } from "react-toastify";
+import { proxy } from "valtio";
+import { z } from "zod";
+
+/* Introduction */
+const templateIntroduction = z.object({
+ content: z.string().min(3, "Content minimal 3 karakter"),
+})
+
+type Introduction = Prisma.IntroductionGetPayload<{
+ select: {
+ content: true;
+ };
+}>;
+
+const introduction = proxy({
+ create: {
+ form: {} as Introduction,
+ loading: false,
+ async create() {
+ const cek = templateIntroduction.safeParse(introduction.create.form);
+ if (!cek.success) {
+ const err = `[${cek.error.issues
+ .map((v) => `${v.path.join(".")}`)
+ .join("\n")}] required`;
+ return toast.error(err);
+ }
+ try {
+ introduction.create.loading = true;
+ const res = await ApiFetch.api.kesehatan.introduction["create"].post(introduction.create.form);
+ if (res.status === 200) {
+ introduction.findMany.load();
+ return toast.success("success create");
+ }
+ return toast.error("failed create");
+ } catch (error) {
+ console.log((error as Error).message);
+ } finally {
+ introduction.create.loading = false;
+ }
+ },
+ },
+ findMany: {
+ data: null as
+ | Prisma.IntroductionGetPayload<{ omit: { isActive: true } }>[]
+ | null,
+ async load() {
+ const res = await ApiFetch.api.kesehatan.introduction["find-many"].get();
+ if (res.status === 200) {
+ introduction.findMany.data = res.data?.data ?? [];
+ }
+ }
+ }
+});
+/* ======================================================================= */
+
+/* symptom */
+const templateSymptom = z.object({
+ title: z.string().min(3, "Title minimal 3 karakter"),
+ content: z.string().min(3, "Content minimal 3 karakter"),
+})
+
+type Symptom = Prisma.SymptomGetPayload<{
+ select: {
+ title: true;
+ content: true;
+ };
+}>;
+
+const symptom = proxy({
+ create: {
+ form: {} as Symptom,
+ loading: false,
+ async create() {
+ const cek = templateSymptom.safeParse(symptom.create.form);
+ if (!cek.success) {
+ const err = `[${cek.error.issues
+ .map((v) => `${v.path.join(".")}`)
+ .join("\n")}] required`;
+ return toast.error(err);
+ }
+ try {
+ symptom.create.loading = true;
+ const res = await ApiFetch.api.kesehatan.symptom["create"].post(symptom.create.form);
+ if (res.status === 200) {
+ symptom.findMany.load();
+ return toast.success("success create");
+ }
+ return toast.error("failed create");
+ } catch (error) {
+ console.log((error as Error).message);
+ } finally {
+ symptom.create.loading = false;
+ }
+ },
+ },
+ findMany: {
+ data: null as
+ | Prisma.SymptomGetPayload<{ omit: { isActive: true } }>[]
+ | null,
+ async load() {
+ const res = await ApiFetch.api.kesehatan.symptom["find-many"].get();
+ if (res.status === 200) {
+ symptom.findMany.data = res.data?.data ?? [];
+ }
+ },
+ },
+});
+/* ======================================================================= */
+
+/* Prevention */
+const templatePrevention = z.object({
+ title: z.string().min(3, "Title minimal 3 karakter"),
+ content: z.string().min(3, "Content minimal 3 karakter"),
+})
+
+type Prevention = Prisma.PreventionGetPayload<{
+ select: {
+ title: true;
+ content: true;
+ };
+}>;
+
+const prevention = proxy({
+ create: {
+ form: {} as Prevention,
+ loading: false,
+ async create() {
+ const cek = templatePrevention.safeParse(prevention.create.form);
+ if (!cek.success) {
+ const err = `[${cek.error.issues
+ .map((v) => `${v.path.join(".")}`)
+ .join("\n")}] required`;
+ return toast.error(err);
+ }
+ try {
+ prevention.create.loading = true;
+ const res = await ApiFetch.api.kesehatan.prevention["create"].post(prevention.create.form);
+ if (res.status === 200) {
+ prevention.findMany.load();
+ return toast.success("success create");
+ }
+ return toast.error("failed create");
+ } catch (error) {
+ console.log((error as Error).message);
+ } finally {
+ prevention.create.loading = false;
+ }
+ },
+ },
+ findMany: {
+ data: null as
+ | Prisma.PreventionGetPayload<{ omit: { isActive: true } }>[]
+ | null,
+ async load() {
+ const res = await ApiFetch.api.kesehatan.prevention["find-many"].get();
+ if (res.status === 200) {
+ prevention.findMany.data = res.data?.data ?? [];
+ }
+ },
+ },
+});
+/* ======================================================================= */
+
+/* First Aid */
+const templateFirstAid = z.object({
+ title: z.string().min(3, "Title minimal 3 karakter"),
+ content: z.string().min(3, "Content minimal 3 karakter"),
+})
+
+type FirstAid = Prisma.FirstAidGetPayload<{
+ select: {
+ title: true;
+ content: true;
+ };
+}>;
+
+const firstAid = proxy({
+ create: {
+ form: {} as FirstAid,
+ loading: false,
+ async create() {
+ const cek = templateFirstAid.safeParse(firstAid.create.form);
+ if (!cek.success) {
+ const err = `[${cek.error.issues
+ .map((v) => `${v.path.join(".")}`)
+ .join("\n")}] required`;
+ return toast.error(err);
+ }
+ try {
+ firstAid.create.loading = true;
+ const res = await ApiFetch.api.kesehatan.firstaid["create"].post(firstAid.create.form);
+ if (res.status === 200) {
+ firstAid.findMany.load();
+ return toast.success("success create");
+ }
+ return toast.error("failed create");
+ } catch (error) {
+ console.log((error as Error).message);
+ } finally {
+ firstAid.create.loading = false;
+ }
+ },
+ },
+ findMany: {
+ data: null as
+ | Prisma.FirstAidGetPayload<{ omit: { isActive: true } }>[]
+ | null,
+ async load() {
+ const res = await ApiFetch.api.kesehatan.firstaid["find-many"].get();
+ if (res.status === 200) {
+ firstAid.findMany.data = res.data?.data ?? [];
+ }
+ },
+ },
+})
+/* ======================================================================= */
+
+/* Myth vs Fact */
+const templateMythFact = z.object({
+ title: z.string().min(3, "Title minimal 3 karakter"),
+ mitos: z.string().min(3, "Mitos minimal 3 karakter"),
+ fakta: z.string().min(3, "Fakta minimal 3 karakter"),
+})
+
+type MythFact = Prisma.MythVsFactGetPayload<{
+ select: {
+ title: true;
+ mitos: true;
+ fakta: true;
+ };
+}>;
+
+const mythFact = proxy({
+ create: {
+ form: {} as MythFact,
+ loading: false,
+ async create() {
+ const cek = templateMythFact.safeParse(mythFact.create.form);
+ if (!cek.success) {
+ const err = `[${cek.error.issues
+ .map((v) => `${v.path.join(".")}`)
+ .join("\n")}] required`;
+ return toast.error(err);
+ }
+ try {
+ mythFact.create.loading = true;
+ const res = await ApiFetch.api.kesehatan.mythvsfact["create"].post(mythFact.create.form);
+ if (res.status === 200) {
+ mythFact.findMany.load();
+ return toast.success("success create");
+ }
+ return toast.error("failed create");
+ } catch (error) {
+ console.log((error as Error).message);
+ } finally {
+ mythFact.create.loading = false;
+ }
+ },
+ },
+ findMany: {
+ data: null as
+ | Prisma.MythVsFactGetPayload<{ omit: { isActive: true } }>[]
+ | null,
+ async load() {
+ const res = await ApiFetch.api.kesehatan.mythvsfact["find-many"].get();
+ if (res.status === 200) {
+ mythFact.findMany.data = res.data?.data ?? [];
+ }
+ },
+ },
+})
+/* ======================================================================= */
+
+/* Doctor Sign */
+const templateDoctorSign = z.object({
+ content: z.string().min(3, "Content minimal 3 karakter"),
+})
+
+type DoctorSign = Prisma.DoctorSignGetPayload<{
+ select: {
+ content: true
+ }
+}>
+
+const doctorSign = proxy({
+ create: {
+ form: {} as DoctorSign,
+ loading: false,
+ async create() {
+ const cek = templateDoctorSign.safeParse(doctorSign.create.form);
+ if (!cek.success) {
+ const err = `[${cek.error.issues
+ .map((v) => `${v.path.join(".")}`)
+ .join("\n")}] required`;
+ return toast.error(err);
+ }
+ try {
+ doctorSign.create.loading = true;
+ const res = await ApiFetch.api.kesehatan.doctor_sign["create"].post(doctorSign.create.form);
+ if (res.status === 200) {
+ doctorSign.findMany.load();
+ return toast.success("success create");
+ }
+ return toast.error("failed create");
+ } catch (error) {
+ console.log((error as Error).message);
+ } finally {
+ doctorSign.create.loading = false;
+ }
+ },
+ },
+ findMany: {
+ data: null as
+ | Prisma.DoctorSignGetPayload<{ omit: { isActive: true } }>[]
+ | null,
+ async load() {
+ const res = await ApiFetch.api.kesehatan.doctor_sign["find-many"].get();
+ if (res.status === 200) {
+ doctorSign.findMany.data = res.data?.data ?? [];
+ }
+ },
+ },
+})
+
+/* ======================================================================= */
+
+const stateArtikelKesehatan = proxy({
+ introduction,
+ symptom,
+ prevention,
+ firstAid,
+ mythFact,
+ doctorSign
+})
+
+export default stateArtikelKesehatan
\ No newline at end of file
diff --git a/src/app/admin/(dashboard)/_state/ppid/daftar_informasi_publik/daftarInformasiPublik.ts b/src/app/admin/(dashboard)/_state/ppid/daftar_informasi_publik/daftarInformasiPublik.ts
new file mode 100644
index 00000000..ff0b2792
--- /dev/null
+++ b/src/app/admin/(dashboard)/_state/ppid/daftar_informasi_publik/daftarInformasiPublik.ts
@@ -0,0 +1,65 @@
+import ApiFetch from "@/lib/api-fetch";
+import { Prisma } from "@prisma/client";
+import { toast } from "react-toastify";
+import { proxy } from "valtio";
+import { z } from "zod";
+
+const templateDaftarInformasi = z.object({
+ jenisInformasi: z.string().min(3, "Jenis Informasi minimal 3 karakter"),
+ deskripsi: z.string().min(3, "Deskripsi minimal 3 karakter"),
+ tanggal: z.string().min(3, "Tanggal minimal 3 karakter"),
+})
+
+type DaftarInformasi = Prisma.DaftarInformasiPublikGetPayload<{
+ select: {
+ jenisInformasi: true;
+ deskripsi: true;
+ tanggal: true;
+ };
+}>;
+
+const daftarInformasi = proxy({
+ create: {
+ form: {} as DaftarInformasi,
+ loading: false,
+ async create() {
+ const cek = templateDaftarInformasi.safeParse(daftarInformasi.create.form);
+ if (!cek.success) {
+ const err = `[${cek.error.issues
+ .map((v) => `${v.path.join(".")}`)
+ .join("\n")}] required`;
+ return toast.error(err);
+ }
+ try {
+ daftarInformasi.create.loading = true;
+ const res = await ApiFetch.api.ppid.daftarinformasipublik["create"].post(daftarInformasi.create.form);
+ if (res.status === 200) {
+ daftarInformasi.findMany.load();
+ return toast.success("success create");
+ }
+ return toast.error("failed create");
+ } catch (error) {
+ console.log((error as Error).message);
+ } finally {
+ daftarInformasi.create.loading = false;
+ }
+ },
+ },
+ findMany: {
+ data: null as
+ | Prisma.DaftarInformasiPublikGetPayload<{ omit: { isActive: true } }>[]
+ | null,
+ async load() {
+ const res = await ApiFetch.api.ppid.daftarinformasipublik["find-many"].get();
+ if (res.status === 200) {
+ daftarInformasi.findMany.data = res.data?.data ?? [];
+ }
+ }
+ }
+ });
+
+ const stateDaftarInformasiPublik = proxy({
+ daftarInformasi
+ })
+
+ export default stateDaftarInformasiPublik;
\ No newline at end of file
diff --git a/src/app/admin/(dashboard)/_state/ppid/dasar_hukum/dasarHukum.ts b/src/app/admin/(dashboard)/_state/ppid/dasar_hukum/dasarHukum.ts
new file mode 100644
index 00000000..f4223a98
--- /dev/null
+++ b/src/app/admin/(dashboard)/_state/ppid/dasar_hukum/dasarHukum.ts
@@ -0,0 +1,82 @@
+import ApiFetch from "@/lib/api-fetch";
+import { Prisma } from "@prisma/client";
+import { toast } from "react-toastify";
+import { proxy } from "valtio";
+import { z } from "zod";
+
+const templateForm = z.object({
+ judul: z.string().min(3, "Judul minimal 3 karakter"),
+ content: z.string().min(3, "Content minimal 3 karakter"),
+});
+
+type DasarHukumForm = Prisma.DasarHukumPPIDGetPayload<{
+ select: {
+ id: true;
+ judul: true;
+ content: true;
+ };
+}>;
+
+const stateDasarHukumPPID = proxy({
+ findById: {
+ data: null as DasarHukumForm | null,
+ loading: false,
+ initialize() {
+ stateDasarHukumPPID.findById.data = {
+ id: '',
+ judul: '',
+ content: '',
+ } as DasarHukumForm;
+ },
+ async load(id: string) {
+ try {
+ stateDasarHukumPPID.findById.loading = true;
+ const res = await ApiFetch.api.ppid.dasarhukumppid["find-by-id"].get({
+ query: { id },
+ });
+ if (res.status === 200) {
+ stateDasarHukumPPID.findById.data = res.data?.data ?? null;
+ } else {
+ toast.error("Gagal mengambil data dasar hukum");
+ }
+ } catch (error) {
+ console.error((error as Error).message);
+ toast.error("Terjadi kesalahan saat mengambil data dasar hukum");
+ } finally {
+ stateDasarHukumPPID.findById.loading = false;
+ }
+ },
+ },
+
+ update: {
+ loading: false,
+ async save(data: DasarHukumForm) {
+ const cek = templateForm.safeParse(data);
+ if (!cek.success) {
+ const errors = cek.error.issues
+ .map((issue) => `${issue.path.join(".")}: ${issue.message}`)
+ .join(", ");
+ toast.error(`Form tidak valid: ${errors}`);
+ return;
+ }
+
+ try {
+ stateDasarHukumPPID.update.loading = true;
+ const res = await ApiFetch.api.ppid.dasarhukumppid["update"].post(data);
+ if (res.status === 200) {
+ toast.success("Data dasar hukum berhasil diubah");
+ await stateDasarHukumPPID.findById.load(data.id);
+ } else {
+ toast.error("Gagal mengubah data dasar hukum");
+ }
+ } catch (error) {
+ console.error((error as Error).message);
+ toast.error("Terjadi kesalahan saat mengubah data dasar hukum");
+ } finally {
+ stateDasarHukumPPID.update.loading = false;
+ }
+ },
+ },
+});
+
+export default stateDasarHukumPPID;
diff --git a/src/app/admin/(dashboard)/_state/ppid/indeks_kepuasan_masyarakat/grafikBerdasarkanJenisKelamin.ts b/src/app/admin/(dashboard)/_state/ppid/indeks_kepuasan_masyarakat/grafikBerdasarkanJenisKelamin.ts
new file mode 100644
index 00000000..5e2c0192
--- /dev/null
+++ b/src/app/admin/(dashboard)/_state/ppid/indeks_kepuasan_masyarakat/grafikBerdasarkanJenisKelamin.ts
@@ -0,0 +1,77 @@
+import ApiFetch from "@/lib/api-fetch";
+import { Prisma } from "@prisma/client";
+import { toast } from "react-toastify";
+import { proxy } from "valtio";
+import { z } from "zod";
+
+const templateGrafikJenisKelamin = z.object({
+ laki: z.string().min(2, "Data laki-laki harus diisi"),
+ perempuan: z.string().min(2, "Data perempuan harus diisi"),
+});
+
+type GrafikJenisKelamin = Prisma.GrafikBerdasarkanJenisKelaminGetPayload<{
+ select: {
+ laki: true;
+ perempuan: true;
+ };
+}>;
+
+const defaultForm: GrafikJenisKelamin = {
+ laki: "",
+ perempuan: "",
+};
+
+const grafikBerdasarkanJenisKelamin = proxy({
+ create: {
+ form: defaultForm,
+ loading: false,
+ async create() {
+ const cek = templateGrafikJenisKelamin.safeParse(
+ grafikBerdasarkanJenisKelamin.create.form
+ );
+ if (!cek.success) {
+ const err = `[${cek.error.issues
+ .map((v) => `${v.path.join(".")}`)
+ .join("\n")}] required`;
+ return toast.error(err);
+ }
+ try {
+ grafikBerdasarkanJenisKelamin.create.loading = true;
+ const res = await ApiFetch.api.ppid.grafikberdasarkanjeniskelamin[
+ "create"
+ ].post(grafikBerdasarkanJenisKelamin.create.form);
+ if (res.status === 200) {
+ grafikBerdasarkanJenisKelamin.create.form = defaultForm;
+ grafikBerdasarkanJenisKelamin.findMany.load();
+ return toast.success("success create");
+ }
+ return toast.error("failed create");
+ } catch (error) {
+ console.log((error as Error).message);
+ } finally {
+ grafikBerdasarkanJenisKelamin.create.loading = false;
+ }
+ },
+ },
+ findMany: {
+ data: null as
+ | Prisma.GrafikBerdasarkanJenisKelaminGetPayload<{
+ omit: { isActive: true };
+ }>[]
+ | null,
+ loading: false,
+ async load() {
+ const res = await ApiFetch.api.ppid.grafikberdasarkanjeniskelamin[
+ "find-many"
+ ].get();
+ if (res.status === 200) {
+ grafikBerdasarkanJenisKelamin.findMany.data = res.data?.data ?? [];
+ }
+ },
+ },
+});
+
+const stateGrafikBerdasarkanJenisKelamin = proxy({
+ grafikBerdasarkanJenisKelamin,
+});
+export default stateGrafikBerdasarkanJenisKelamin;
diff --git a/src/app/admin/(dashboard)/_state/ppid/indeks_kepuasan_masyarakat/grafikBerdasarkanResponden.ts b/src/app/admin/(dashboard)/_state/ppid/indeks_kepuasan_masyarakat/grafikBerdasarkanResponden.ts
new file mode 100644
index 00000000..4fd2e69b
--- /dev/null
+++ b/src/app/admin/(dashboard)/_state/ppid/indeks_kepuasan_masyarakat/grafikBerdasarkanResponden.ts
@@ -0,0 +1,84 @@
+import ApiFetch from "@/lib/api-fetch";
+import { Prisma } from "@prisma/client";
+import { toast } from "react-toastify";
+import { proxy } from "valtio";
+import { z } from "zod";
+
+const templateGrafikResponden = z.object({
+ sangatbaik: z.string().min(1, "Data sangat baik harus diisi"),
+ baik: z.string().min(1, "Data baik harus diisi"),
+ kurangbaik: z.string().min(1, "Data kurang baik harus diisi"),
+ tidakbaik: z.string().min(1, "Data tidak baik harus diisi"),
+});
+
+type GrafikResponden = Prisma.GrafikBerdasarkanRespondenGetPayload<{
+ select: {
+ sangatbaik: true;
+ baik: true;
+ kurangbaik: true;
+ tidakbaik: true;
+ };
+}>;
+
+const defaultForm: GrafikResponden = {
+ sangatbaik: "",
+ baik: "",
+ kurangbaik: "",
+ tidakbaik: "",
+};
+
+const grafikBerdasarkanResponden = proxy({
+ create: {
+ form: defaultForm,
+ loading: false,
+ async create() {
+ const cek = templateGrafikResponden.safeParse(
+ grafikBerdasarkanResponden.create.form
+ );
+ if (!cek.success) {
+ const err = `[${cek.error.issues
+ .map((v) => `${v.path.join(".")}`)
+ .join("\n")}] required`;
+ return toast.error(err);
+ }
+ try {
+ grafikBerdasarkanResponden.create.loading = true;
+ const res = await ApiFetch.api.ppid.grafikberdasarkanresponden[
+ "create"
+ ].post(grafikBerdasarkanResponden.create.form);
+ if (res.status === 200) {
+ grafikBerdasarkanResponden.create.form = defaultForm;
+ grafikBerdasarkanResponden.findMany.load();
+ return toast.success("success create");
+ }
+ return toast.error("failed create");
+ } catch (error) {
+ console.log((error as Error).message);
+ } finally {
+ grafikBerdasarkanResponden.create.loading = false;
+ }
+ },
+ },
+ findMany: {
+ data: null as
+ | Prisma.GrafikBerdasarkanRespondenGetPayload<{
+ omit: { isActive: true };
+ }>[]
+ | null,
+ loading: false,
+ async load() {
+ const res = await ApiFetch.api.ppid.grafikberdasarkanresponden[
+ "find-many"
+ ].get();
+ if (res.status === 200) {
+ grafikBerdasarkanResponden.findMany.data = res.data?.data ?? [];
+ }
+ },
+ },
+});
+
+const stateGrafikResponden = proxy({
+ grafikBerdasarkanResponden,
+});
+
+export default stateGrafikResponden;
\ No newline at end of file
diff --git a/src/app/admin/(dashboard)/_state/ppid/indeks_kepuasan_masyarakat/grafikBerdasarkanUmur.ts b/src/app/admin/(dashboard)/_state/ppid/indeks_kepuasan_masyarakat/grafikBerdasarkanUmur.ts
new file mode 100644
index 00000000..3d05f6cf
--- /dev/null
+++ b/src/app/admin/(dashboard)/_state/ppid/indeks_kepuasan_masyarakat/grafikBerdasarkanUmur.ts
@@ -0,0 +1,84 @@
+import ApiFetch from "@/lib/api-fetch";
+import { Prisma } from "@prisma/client";
+import { toast } from "react-toastify";
+import { proxy } from "valtio";
+import { z } from "zod";
+
+const templateGrafikUmur = z.object({
+ remaja: z.string().min(2, "Data remaja harus diisi"),
+ dewasa: z.string().min(2, "Data dewasa harus diisi"),
+ orangtua: z.string().min(2, "Data orangtua harus diisi"),
+ lansia: z.string().min(2, "Data lansia harus diisi"),
+});
+
+type GrafikUmur = Prisma.GrafikBerdasarkanUmurGetPayload<{
+ select: {
+ remaja: true;
+ dewasa: true;
+ orangtua: true;
+ lansia: true;
+ };
+}>;
+
+const defaultForm: GrafikUmur = {
+ remaja: "",
+ dewasa: "",
+ orangtua: "",
+ lansia: "",
+};
+
+const grafikBerdasarkanUmur = proxy({
+ create: {
+ form: defaultForm,
+ loading: false,
+ async create() {
+ const cek = templateGrafikUmur.safeParse(
+ grafikBerdasarkanUmur.create.form
+ );
+ if (!cek.success) {
+ const err = `[${cek.error.issues
+ .map((v) => `${v.path.join(".")}`)
+ .join("\n")}] required`;
+ return toast.error(err);
+ }
+ try {
+ grafikBerdasarkanUmur.create.loading = true;
+ const res = await ApiFetch.api.ppid.grafikberdasarkanumur[
+ "create"
+ ].post(grafikBerdasarkanUmur.create.form);
+ if (res.status === 200) {
+ grafikBerdasarkanUmur.create.form = defaultForm;
+ grafikBerdasarkanUmur.findMany.load();
+ return toast.success("success create");
+ }
+ return toast.error("failed create");
+ } catch (error) {
+ console.log((error as Error).message);
+ } finally {
+ grafikBerdasarkanUmur.create.loading = false;
+ }
+ },
+ },
+ findMany: {
+ data: null as
+ | Prisma.GrafikBerdasarkanUmurGetPayload<{
+ omit: { isActive: true };
+ }>[]
+ | null,
+ loading: false,
+ async load() {
+ const res = await ApiFetch.api.ppid.grafikberdasarkanumur[
+ "find-many"
+ ].get();
+ if (res.status === 200) {
+ grafikBerdasarkanUmur.findMany.data = res.data?.data ?? [];
+ }
+ },
+ },
+})
+
+const stateGrafikBerdasarkanUmur = proxy({
+ grafikBerdasarkanUmur,
+})
+
+export default stateGrafikBerdasarkanUmur;
\ No newline at end of file
diff --git a/src/app/admin/(dashboard)/_state/ppid/indeks_kepuasan_masyarakat/grafikHasilKepuasan.ts b/src/app/admin/(dashboard)/_state/ppid/indeks_kepuasan_masyarakat/grafikHasilKepuasan.ts
new file mode 100644
index 00000000..b8badf0c
--- /dev/null
+++ b/src/app/admin/(dashboard)/_state/ppid/indeks_kepuasan_masyarakat/grafikHasilKepuasan.ts
@@ -0,0 +1,76 @@
+import ApiFetch from "@/lib/api-fetch";
+import { Prisma } from "@prisma/client";
+import { toast } from "react-toastify";
+import { proxy } from "valtio";
+import { z } from "zod";
+
+const templateGrafikHasilKepuasanMasyarakat = z.object({
+ label: z.string().min(2, "Label harus diisi"),
+ kepuasan: z.string().min(2, "Kepuasan harus diisi"),
+});
+
+type GrafikHasilKepuasanMasyarakat = Prisma.IndeksKepuasanMasyarakatGetPayload<{
+ select: {
+ label: true;
+ kepuasan: true;
+ };
+}>;
+
+const defaultForm: GrafikHasilKepuasanMasyarakat = {
+ label: "",
+ kepuasan: "",
+};
+
+const grafikHasilKepuasanMasyarakat = proxy({
+ create: {
+ form: defaultForm,
+ loading: false,
+ async create() {
+ const cek = templateGrafikHasilKepuasanMasyarakat.safeParse(
+ grafikHasilKepuasanMasyarakat.create.form
+ );
+ if (!cek.success) {
+ const err = `[${cek.error.issues
+ .map((v) => `${v.path.join(".")}`)
+ .join("\n")}] required`;
+ return toast.error(err);
+ }
+ try {
+ grafikHasilKepuasanMasyarakat.create.loading = true;
+ const res = await ApiFetch.api.ppid.grafikhasilkepuasamanmasyarakat["create"].post(
+ grafikHasilKepuasanMasyarakat.create.form
+ );
+ if (res.status === 200) {
+ grafikHasilKepuasanMasyarakat.create.form = {
+ label: "",
+ kepuasan: ""
+ };
+ grafikHasilKepuasanMasyarakat.findMany.load();
+ return toast.success("success create");
+ }
+ return toast.error("failed create");
+ } catch (error) {
+ console.log((error as Error).message);
+ } finally {
+ grafikHasilKepuasanMasyarakat.create.loading = false;
+ }
+ },
+ },
+ findMany: {
+ data: null as
+ | Prisma.IndeksKepuasanMasyarakatGetPayload<{ omit: { isActive: true } }>[]
+ | null,
+ async load() {
+ const res = await ApiFetch.api.ppid.grafikhasilkepuasamanmasyarakat["find-many"].get();
+ if (res.status === 200) {
+ grafikHasilKepuasanMasyarakat.findMany.data = res.data?.data ?? [];
+ }
+ }
+ }
+});
+
+const stateGrafikHasilKepuasanMasyarakat = proxy({
+ grafikHasilKepuasanMasyarakat,
+});
+
+export default stateGrafikHasilKepuasanMasyarakat;
diff --git a/src/app/admin/(dashboard)/_state/ppid/permohonan_informasi_publik/permohonanInformasiPublik.ts b/src/app/admin/(dashboard)/_state/ppid/permohonan_informasi_publik/permohonanInformasiPublik.ts
new file mode 100644
index 00000000..363998cf
--- /dev/null
+++ b/src/app/admin/(dashboard)/_state/ppid/permohonan_informasi_publik/permohonanInformasiPublik.ts
@@ -0,0 +1,125 @@
+import ApiFetch from "@/lib/api-fetch";
+import { Prisma } from "@prisma/client";
+import { toast } from "react-toastify";
+import { proxy } from "valtio";
+import { z } from "zod";
+
+const templateForm = z.object({
+ name: z.string().min(3, "Nama minimal 3 karakter"),
+ nik: z.string().min(3, "NIK minimal 3 karakter"),
+ notelp: z.string().min(3, "Nomor Telepon minimal 3 karakter"),
+ alamat: z.string().min(3, "Alamat minimal 3 karakter"),
+ email: z.string().min(3, "Email minimal 3 karakter"),
+ jenisInformasiDimintaId: z.string().nonempty(),
+ caraMemperolehInformasiId: z.string().nonempty(),
+ caraMemperolehSalinanInformasiId: z.string().nonempty(),
+})
+
+const jenisInformasiDiminta = proxy({
+ findMany: {
+ data: null as
+ | null
+ | Prisma.JenisInformasiDimintaGetPayload<{ omit: { isActive: true } }>[],
+ async load(){
+ const res = await ApiFetch.api.ppid.permohonaninformasipublik.jenisInformasi["find-many"].get();
+ if (res.status === 200) {
+ jenisInformasiDiminta.findMany.data = res.data?.data ?? [];
+ }
+ }
+ }
+})
+
+const caraMemperolehInformasi = proxy({
+ findMany: {
+ data: null as
+ | null
+ | Prisma.CaraMemperolehInformasiGetPayload<{ omit: { isActive: true } }>[],
+ async load() {
+ const res = await ApiFetch.api.ppid.permohonaninformasipublik.memperolehInformasi["find-many"].get();
+ if (res.status === 200) {
+ caraMemperolehInformasi.findMany.data = res.data?.data ?? [];
+ }
+ }
+ }
+})
+
+const caraMemperolehSalinanInformasi = proxy({
+ findMany: {
+ data: null as
+ | null
+ | Prisma.CaraMemperolehSalinanInformasiGetPayload<{ omit: { isActive: true } }>[],
+ async load() {
+ const res = await ApiFetch.api.ppid.permohonaninformasipublik.salinanInformasi["find-many"].get();
+ if (res.status === 200) {
+ caraMemperolehSalinanInformasi.findMany.data = res.data?.data ?? [];
+ }
+ }
+ }
+})
+console.log(caraMemperolehSalinanInformasi)
+
+type PermohonanInformasiPublikForm = Prisma.PermohonanInformasiPublikGetPayload<{
+ select: {
+ name: true;
+ nik: true;
+ notelp: true;
+ alamat: true;
+ email: true;
+ jenisInformasiDimintaId: true;
+ caraMemperolehInformasiId: true;
+ caraMemperolehSalinanInformasiId: true;
+ };
+}>;
+
+const statepermohonanInformasiPublik = proxy({
+ create: {
+ form: {} as PermohonanInformasiPublikForm,
+ loading: false,
+ async create(){
+ const cek = templateForm.safeParse(statepermohonanInformasiPublik.create.form);
+ if(!cek.success) {
+ const err = `[${cek.error.issues
+ .map((v) => `${v.path.join(".")}`)
+ .join("\n")}] required`;
+ return toast.error(err);
+ }
+ try {
+ statepermohonanInformasiPublik.create.loading = true;
+ const res = await ApiFetch.api.ppid.permohonaninformasipublik["create"].post(statepermohonanInformasiPublik.create.form);
+ if (res.status === 200) {
+ statepermohonanInformasiPublik.findMany.load();
+ return toast.success("success create");
+ }
+ return toast.error("failed create");
+ } catch (error) {
+ console.log((error as Error).message);
+ } finally {
+ statepermohonanInformasiPublik.create.loading = false;
+ }
+ }
+ },
+ findMany: {
+ data: null as
+ | Prisma.PermohonanInformasiPublikGetPayload<{ include: {
+ caraMemperolehSalinanInformasi: true,
+ jenisInformasiDiminta: true,
+ caraMemperolehInformasi: true,
+ } }>[]
+ | null,
+ async load() {
+ const res = await ApiFetch.api.ppid.permohonaninformasipublik["find-many"].get();
+ if (res.status === 200) {
+ statepermohonanInformasiPublik.findMany.data = res.data?.data ?? [];
+ }
+ }
+ }
+})
+
+const statepermohonanInformasiPublikForm = proxy({
+ statepermohonanInformasiPublik,
+ jenisInformasiDiminta,
+ caraMemperolehInformasi,
+ caraMemperolehSalinanInformasi,
+})
+
+export default statepermohonanInformasiPublikForm;
diff --git a/src/app/admin/(dashboard)/_state/ppid/permohonan_keberatan_informasi_publik/permohonanKeberatanInformasi.ts b/src/app/admin/(dashboard)/_state/ppid/permohonan_keberatan_informasi_publik/permohonanKeberatanInformasi.ts
new file mode 100644
index 00000000..0decf48a
--- /dev/null
+++ b/src/app/admin/(dashboard)/_state/ppid/permohonan_keberatan_informasi_publik/permohonanKeberatanInformasi.ts
@@ -0,0 +1,64 @@
+import ApiFetch from "@/lib/api-fetch";
+import { Prisma } from "@prisma/client";
+import { toast } from "react-toastify";
+import { proxy } from "valtio";
+import { z } from "zod";
+
+const templateForm = z.object({
+ name: z.string().min(3, "Nama minimal 3 karakter"),
+ email: z.string().min(3, "Email minimal 3 karakter"),
+ notelp: z.string().min(3, "Nomor Telepon minimal 3 karakter"),
+ alasan: z.string().min(3, "Alasan minimal 3 karakter"),
+})
+
+type PermohonanKeberatanInformasiForm = Prisma.FormulirPermohonanKeberatanGetPayload<{
+ select: {
+ name: true;
+ email: true;
+ notelp: true;
+ alasan: true;
+ };
+}>;
+
+const permohonanKeberatanInformasi = proxy({
+ create: {
+ form: {} as PermohonanKeberatanInformasiForm,
+ loading: false,
+ async create(){
+ const cek = templateForm.safeParse(permohonanKeberatanInformasi.create.form);
+ if(!cek.success) {
+ const err = `[${cek.error.issues
+ .map((v) => `${v.path.join(".")}`)
+ .join("\n")}] required`;
+ return toast.error(err);
+ }
+ try {
+ permohonanKeberatanInformasi.create.loading = true;
+ const res = await ApiFetch.api.ppid.permohonankeberataninformasipublik["create"].post(permohonanKeberatanInformasi.create.form);
+ if (res.status === 200) {
+ permohonanKeberatanInformasi.findMany.load();
+ return toast.success("success create");
+ }
+ return toast.error("failed create");
+ } catch (error) {
+ console.log((error as Error).message);
+ } finally {
+ permohonanKeberatanInformasi.create.loading = false;
+ }
+ },
+ },
+ findMany: {
+ data: null as
+ | Prisma.FormulirPermohonanKeberatanGetPayload<{omit: {isActive: true}}>[]
+ | null,
+ async load() {
+ const res = await ApiFetch.api.ppid.permohonankeberataninformasipublik["find-many"].get();
+ if (res.status === 200) {
+ permohonanKeberatanInformasi.findMany.data = res.data?.data ?? [];
+ }
+ }
+ }
+});
+
+export default permohonanKeberatanInformasi;
+
diff --git a/src/app/admin/(dashboard)/_state/ppid/profile_ppid/profile_PPID.ts b/src/app/admin/(dashboard)/_state/ppid/profile_ppid/profile_PPID.ts
new file mode 100644
index 00000000..167d8edd
--- /dev/null
+++ b/src/app/admin/(dashboard)/_state/ppid/profile_ppid/profile_PPID.ts
@@ -0,0 +1,172 @@
+import ApiFetch from "@/lib/api-fetch";
+import { Prisma } from "@prisma/client";
+import { toast } from "react-toastify";
+import { proxy } from "valtio";
+import { z } from "zod";
+
+/**
+ * Schema validasi form ProfilePPID menggunakan Zod.
+ */
+const templateForm = z.object({
+ name: z.string().min(3, "Nama minimal 3 karakter"),
+ biodata: z.string().min(3, "Biodata minimal 3 karakter"),
+ riwayat: z.string().min(3, "Riwayat minimal 3 karakter"),
+ pengalaman: z.string().min(3, "Pengalaman minimal 3 karakter"),
+ unggulan: z.string().min(3, "Unggulan minimal 3 karakter"),
+});
+
+/**
+ * Tipe data ProfilePPID yang digunakan dalam form dan API, berdasarkan Prisma schema.
+ */
+type ProfilePPIDForm = Prisma.ProfilePPIDGetPayload<{
+ select: {
+ id: true;
+ name: true;
+ biodata: true;
+ riwayat: true;
+ pengalaman: true;
+ unggulan: true;
+ imageUrl: true;
+ };
+}>;
+
+/**
+ * State utama ProfilePPID yang mencakup fitur:
+ * - Ambil data berdasarkan ID
+ * - Update data
+ * - Upload gambar
+ */
+const stateProfilePPID = proxy({
+ /**
+ * Bagian untuk ambil data berdasarkan ID
+ */
+ findById: {
+ data: null as ProfilePPIDForm | null,
+ loading: false,
+
+ /**
+ * Inisialisasi data kosong ke dalam state.
+ */
+ initialize() {
+ stateProfilePPID.findById.data = {
+ id: '',
+ name: '',
+ biodata: '',
+ riwayat: '',
+ pengalaman: '',
+ unggulan: '',
+ imageUrl: ''
+ } as ProfilePPIDForm;
+ },
+
+ /**
+ * Mengambil data profil berdasarkan ID.
+ * @param {string} id - ID dari profile yang ingin diambil.
+ */
+ async load(id: string) {
+ try {
+ stateProfilePPID.findById.loading = true;
+ const res = await ApiFetch.api.ppid.profileppid["find-by-id"].get({
+ query: { id },
+ });
+
+ if (res.status === 200) {
+ stateProfilePPID.findById.data = res.data?.data ?? null;
+ } else {
+ toast.error("Gagal mengambil data profile");
+ }
+ } catch (error) {
+ console.error((error as Error).message);
+ toast.error("Terjadi kesalahan saat mengambil data profile");
+ } finally {
+ stateProfilePPID.findById.loading = false;
+ }
+ },
+ },
+
+ /**
+ * Bagian untuk update data profile
+ */
+ update: {
+ loading: false,
+
+ /**
+ * Melakukan validasi dan menyimpan perubahan data profile ke server.
+ * @param {ProfilePPIDForm} data - Data profil yang akan disimpan.
+ */
+ async save(data: ProfilePPIDForm) {
+ const cek = templateForm.safeParse(data);
+
+ if (!cek.success) {
+ const errors = cek.error.issues
+ .map((issue) => `${issue.path.join(".")}: ${issue.message}`)
+ .join(", ");
+ toast.error(`Form tidak valid: ${errors}`);
+ return;
+ }
+
+ try {
+ stateProfilePPID.update.loading = true;
+ const res = await ApiFetch.api.ppid.profileppid["update"].post(data);
+
+ if (res.status === 200) {
+ toast.success("Berhasil update profile");
+ await stateProfilePPID.findById.load(data.id);
+ } else {
+ toast.error("Gagal update profile");
+ }
+ } catch (error) {
+ console.error((error as Error).message);
+ toast.error("Terjadi kesalahan saat update profile");
+ } finally {
+ stateProfilePPID.update.loading = false;
+ }
+ },
+ },
+
+ /**
+ * Bagian untuk upload gambar profil
+ */
+ uploadImage: {
+ loading: false,
+
+ /**
+ * Mengunggah gambar profil berdasarkan ID.
+ * @param {File} file - File gambar yang akan diunggah.
+ * @param {string} id - ID dari profil yang akan diperbarui gambarnya.
+ */
+ async save(file: File, id: string) {
+ if (!file || !id) {
+ toast.error("File atau ID harus disertakan");
+ return;
+ }
+
+ try {
+ stateProfilePPID.uploadImage.loading = true;
+
+ const form = new FormData();
+ form.append("file", file);
+ form.append("id", id);
+
+ const res = await ApiFetch.api.ppid.profileppid["edit-img"].post(form);
+
+ if (res.status === 200) {
+ toast.success("Berhasil mengunggah gambar");
+ await stateProfilePPID.findById.load(id);
+ } else {
+ toast.error("Gagal mengunggah gambar");
+ }
+ } catch (error) {
+ console.error((error as Error).message);
+ toast.error("Terjadi kesalahan saat mengunggah gambar");
+ } finally {
+ stateProfilePPID.uploadImage.loading = false;
+ }
+ },
+ },
+});
+
+/**
+ * Ekspor state utama ProfilePPID untuk digunakan di komponen lain.
+ */
+export default stateProfilePPID;
diff --git a/src/app/admin/(dashboard)/_state/ppid/visi_misi_ppid/visimisiPPID.ts b/src/app/admin/(dashboard)/_state/ppid/visi_misi_ppid/visimisiPPID.ts
new file mode 100644
index 00000000..86e90bc7
--- /dev/null
+++ b/src/app/admin/(dashboard)/_state/ppid/visi_misi_ppid/visimisiPPID.ts
@@ -0,0 +1,81 @@
+import ApiFetch from "@/lib/api-fetch";
+import { Prisma } from "@prisma/client";
+import { toast } from "react-toastify";
+import { proxy } from "valtio";
+import { z } from "zod";
+
+const templateForm = z.object({
+ misi: z.string().min(3, "Misi minimal 3 karakter"),
+ visi: z.string().min(3, "Visi minimal 3 karakter"),
+});
+
+type VisiMisiPPIDForm = Prisma.VisiMisiPPIDGetPayload<{
+ select: {
+ id: true;
+ misi: true;
+ visi: true;
+ };
+}>;
+
+const stateVisiMisiPPID = proxy({
+ findById: {
+ data: null as VisiMisiPPIDForm | null,
+ loading: false,
+ initialize() {
+ stateVisiMisiPPID.findById.data = {
+ id: "",
+ misi: "",
+ visi: "",
+ } as VisiMisiPPIDForm;
+ },
+ async load(id: string) {
+ try {
+ stateVisiMisiPPID.findById.loading = true;
+ const res = await ApiFetch.api.ppid.visimisippid["find-by-id"].get({
+ query: { id },
+ });
+ if (res.status === 200) {
+ stateVisiMisiPPID.findById.data = res.data?.data ?? null;
+ } else {
+ toast.error("Gagal mengambil data visi misi");
+ }
+ } catch (error) {
+ console.error((error as Error).message);
+ toast.error("Terjadi kesalahan saat mengambil data visi misi");
+ } finally {
+ stateVisiMisiPPID.findById.loading = false;
+ }
+ },
+ },
+ update: {
+ loading: false,
+ async save(data: VisiMisiPPIDForm) {
+ const cek = templateForm.safeParse(data);
+ if (!cek.success) {
+ const errors = cek.error.issues
+ .map((issue) => `${issue.path.join(".")}: ${issue.message}`)
+ .join(", ");
+ toast.error(`Form tidak valid: ${errors}`);
+ return;
+ }
+
+ try {
+ stateVisiMisiPPID.update.loading = true;
+ const res = await ApiFetch.api.ppid.visimisippid["update"].post(data);
+ if (res.status === 200) {
+ toast.success("Berhasil update visi misi");
+ await stateVisiMisiPPID.findById.load(data.id);
+ } else {
+ toast.error("Gagal update visi misi");
+ }
+ } catch (error) {
+ console.error((error as Error).message);
+ toast.error("Terjadi kesalahan saat update visi misi");
+ } finally {
+ stateVisiMisiPPID.update.loading = false;
+ }
+ },
+ },
+});
+
+export default stateVisiMisiPPID;
diff --git a/src/app/admin/(dashboard)/desa/_com/desaEditor.tsx b/src/app/admin/(dashboard)/desa/_com/desaEditor.tsx
new file mode 100644
index 00000000..de60355a
--- /dev/null
+++ b/src/app/admin/(dashboard)/desa/_com/desaEditor.tsx
@@ -0,0 +1,93 @@
+'use client'
+import colors from '@/con/colors';
+import { Button, Stack } from '@mantine/core';
+import { Link, RichTextEditor } from '@mantine/tiptap';
+import Highlight from '@tiptap/extension-highlight';
+import SubScript from '@tiptap/extension-subscript';
+import Superscript from '@tiptap/extension-superscript';
+import TextAlign from '@tiptap/extension-text-align';
+import Underline from '@tiptap/extension-underline';
+import { useEditor } from '@tiptap/react';
+import StarterKit from '@tiptap/starter-kit';
+
+const content =
+ 'Welcome to Mantine rich text editor RichTextEditor component focuses on usability and is designed to be as simple as possible to bring a familiar editing experience to regular users. RichTextEditor is based on Tiptap.dev and supports all of its features:
General text formatting: bold , italic , underline , strike-through Headings (h1-h6) Sub and super scripts (<sup /> and <sub /> tags) Ordered and bullet lists Text align And all other extensions ';
+
+export function DesaEditor({showSubmit = true} : {
+ showSubmit: boolean
+}) {
+ const editor = useEditor({
+ extensions: [
+ StarterKit,
+ Underline,
+ Link,
+ Superscript,
+ SubScript,
+ Highlight,
+ TextAlign.configure({ types: ['heading', 'paragraph'] }),
+ ],
+ immediatelyRender: false,
+ content,
+ });
+
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {showSubmit && (
+
+ Submit
+
+ )}
+
+ );
+}
\ No newline at end of file
diff --git a/src/app/admin/(dashboard)/desa/_com/desaEditorText.tsx b/src/app/admin/(dashboard)/desa/_com/desaEditorText.tsx
new file mode 100644
index 00000000..3452d0a2
--- /dev/null
+++ b/src/app/admin/(dashboard)/desa/_com/desaEditorText.tsx
@@ -0,0 +1,95 @@
+'use client'
+import { Button, Stack } from '@mantine/core';
+import { Link, RichTextEditor } from '@mantine/tiptap';
+import Highlight from '@tiptap/extension-highlight';
+import SubScript from '@tiptap/extension-subscript';
+import Superscript from '@tiptap/extension-superscript';
+import TextAlign from '@tiptap/extension-text-align';
+import Underline from '@tiptap/extension-underline';
+import { useEditor } from '@tiptap/react';
+import StarterKit from '@tiptap/starter-kit';
+
+
+function DesaEditorText({ onSubmit, onChange, showSubmit = true, initialContent = '', }: {
+ onSubmit?: (val: string) => void,
+ onChange: (val: string) => void,
+ showSubmit?: boolean,
+ initialContent?: string }) {
+ const editor = useEditor({
+ extensions: [
+ StarterKit,
+ Underline,
+ Link,
+ Superscript,
+ SubScript,
+ Highlight,
+ TextAlign.configure({ types: ['heading', 'paragraph'] }),
+ ],
+ immediatelyRender: false,
+ content: initialContent,
+ onUpdate : ({editor}) => {
+ onChange(editor.getHTML())
+ }
+ });
+
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {showSubmit && (
+ {
+ if (!editor) return
+ onSubmit?.(editor?.getHTML())
+ }}>Submit
+ )}
+
+ );
+}
+
+export default DesaEditorText;
diff --git a/src/app/admin/(dashboard)/desa/berita/_com/BeritaEditor.tsx b/src/app/admin/(dashboard)/desa/berita/_com/BeritaEditor.tsx
index aef1e401..4efd681f 100644
--- a/src/app/admin/(dashboard)/desa/berita/_com/BeritaEditor.tsx
+++ b/src/app/admin/(dashboard)/desa/berita/_com/BeritaEditor.tsx
@@ -1,3 +1,4 @@
+/* eslint-disable @typescript-eslint/no-explicit-any */
'use client'
import { RichTextEditor, Link } from '@mantine/tiptap';
import { useEditor } from '@tiptap/react';
@@ -8,23 +9,40 @@ import TextAlign from '@tiptap/extension-text-align';
import Superscript from '@tiptap/extension-superscript';
import SubScript from '@tiptap/extension-subscript';
import { Button, Stack } from '@mantine/core';
+import { useEffect } from 'react';
-const content =
- 'Welcome to Mantine rich text editor RichTextEditor component focuses on usability and is designed to be as simple as possible to bring a familiar editing experience to regular users. RichTextEditor is based on Tiptap.dev and supports all of its features:
General text formatting: bold , italic , underline , strike-through Headings (h1-h6) Sub and super scripts (<sup /> and <sub /> tags) Ordered and bullet lists Text align And all other extensions ';
+// const content =
+// 'Welcome to Mantine rich text editor RichTextEditor component focuses on usability and is designed to be as simple as possible to bring a familiar editing experience to regular users. RichTextEditor is based on Tiptap.dev and supports all of its features:
General text formatting: bold , italic , underline , strike-through Headings (h1-h6) Sub and super scripts (<sup /> and <sub /> tags) Ordered and bullet lists Text align And all other extensions ';
+
+ export function BeritaEditor({
+ onEditorReady,
+ showSubmit = true,
+ onSubmit,
+ }: {
+ onEditorReady?: (editor: any | null) => void;
+ onSubmit?: (val: string) => void;
+ showSubmit?: boolean;
+ }) {
+ const editor = useEditor({
+ extensions: [
+ StarterKit,
+ Underline,
+ Link,
+ Superscript,
+ SubScript,
+ Highlight,
+ TextAlign.configure({ types: ['heading', 'paragraph'] }),
+ ],
+ content: '',
+ immediatelyRender: false
+ });
+
+ useEffect(() => {
+ onEditorReady?.(editor);
+ }, [editor, onEditorReady] );
+
+ if (!editor) return null;
-export function BeritaEditor({ onSubmit }: { onSubmit: (val: string) => void }) {
- const editor = useEditor({
- extensions: [
- StarterKit,
- Underline,
- Link,
- Superscript,
- SubScript,
- Highlight,
- TextAlign.configure({ types: ['heading', 'paragraph'] }),
- ],
- content,
- });
return (
@@ -76,10 +94,12 @@ export function BeritaEditor({ onSubmit }: { onSubmit: (val: string) => void })
- {
- if (!editor) return
- onSubmit(editor?.getHTML())
- }}>Submit
+ {showSubmit && (
+ {
+ if (!editor) return
+ onSubmit?.(editor?.getHTML())
+ }}>Submit
+ )}
);
}
\ No newline at end of file
diff --git a/src/app/admin/(dashboard)/desa/berita/page.tsx b/src/app/admin/(dashboard)/desa/berita/page.tsx
index 26c3df72..134cd4ad 100644
--- a/src/app/admin/(dashboard)/desa/berita/page.tsx
+++ b/src/app/admin/(dashboard)/desa/berita/page.tsx
@@ -1,88 +1,358 @@
+/* eslint-disable @typescript-eslint/no-explicit-any */
'use client'
-import { Center, Group, Select, SimpleGrid, Skeleton, Stack, Text, TextInput } from '@mantine/core';
+import colors from '@/con/colors';
+import ApiFetch from '@/lib/api-fetch';
+import { ActionIcon, Box, Button, Center, FileInput, Flex, Image, Paper, Select, SimpleGrid, Skeleton, Stack, Text, TextInput, Title } from '@mantine/core';
import { useShallowEffect } from '@mantine/hooks';
import { Prisma } from '@prisma/client';
-import { IconImageInPicture } from '@tabler/icons-react';
+import { IconEdit, IconImageInPicture, IconX } from '@tabler/icons-react';
+import { useRouter } from 'next/navigation';
+import { useState } from 'react';
+import { toast } from 'react-toastify';
import { useProxy } from 'valtio/utils';
+import { ModalKonfirmasiHapus } from '../../_com/modalKonfirmasiHapus';
import stateDashboardBerita from '../../_state/desa/berita';
import { BeritaEditor } from './_com/BeritaEditor';
function Page() {
return (
-
-
-
-
-
-
+
+ Berita
+
+
+
);
}
+function BeritaCreate() {
+ const beritaState = useProxy(stateDashboardBerita);
+ const [previewImage, setPreviewImage] = useState(null);
+ const [file, setFile] = useState(null);
+ const [editorInstance, setEditorInstance] = useState(null);
+
+ const resetForm = () => {
+ // Reset state di valtio
+ beritaState.berita.create.form = {
+ judul: "",
+ deskripsi: "",
+ kategoriBeritaId: "",
+ imageId: "",
+ content: "",
+ };
+
+ // Reset state lokal
+ setPreviewImage(null);
+ setFile(null);
+ if (editorInstance) {
+ editorInstance.commands.setContent(""); // Kosongkan editor
+ }
+ };
+
+ const handleSubmit = async () => {
+ if (!file) {
+ return toast.warn("Pilih file gambar terlebih dahulu");
+ }
+ if (!editorInstance) return toast.error("Editor belum siap");
+
+ const htmlContent = editorInstance.getHTML();
+ if (!htmlContent || htmlContent === "
") return toast.warn("Konten tidak boleh kosong");
+
+ beritaState.berita.create.form.content = htmlContent;
+
+ // Upload gambar dulu
+ const res = await ApiFetch.api.fileStorage.create.post({
+ file,
+ name: file.name,
+ });
+
+ const uploaded = res.data?.data;
+ if (!uploaded?.id) {
+ return toast.error("Gagal upload gambar");
+ }
+
+ // Simpan ID gambar ke form
+ beritaState.berita.create.form.imageId = uploaded.id;
+
+ // Submit data berita
+ await beritaState.berita.create.create();
+
+ toast.success("Berita berhasil disimpan!");
+
+ // Reset form setelah submit
+ resetForm();
+ };
+
+ return (
+
+
+
+ {
+ beritaState.berita.create.form.judul = val.target.value;
+ }}
+ label={Judul }
+ placeholder="masukkan judul"
+ />
+ {
+ beritaState.berita.create.form.kategoriBeritaId = val.id;
+ }}
+ />
+ {
+ beritaState.berita.create.form.deskripsi = val.target.value;
+ }}
+ label={Deskripsi }
+ placeholder="masukkan deskripsi"
+ />
+
+ Upload Gambar}
+ value={file}
+ onChange={async (e) => {
+ if (!e) return;
+ setFile(e);
+ const base64 = await e.arrayBuffer().then((buf) =>
+ "data:image/png;base64," + Buffer.from(buf).toString("base64")
+ );
+ setPreviewImage(base64);
+ }}
+ />
+ {previewImage ? (
+
+ ) : (
+
+
+
+ )}
+
+ Konten
+ setEditorInstance(ed)}
+ />
+
+ Simpan Berita
+
+
+
+ );
+}
+
+
+
+
+// function BeritaList() {
+// const beritaState = useProxy(stateDashboardBerita)
+// useShallowEffect(() => {
+// beritaState.berita.findMany.load()
+// }, [])
+
+
+
+// const router = useRouter()
+
+// if (!beritaState.berita.findMany.data) return
+// {Array.from({ length: 10 }).map((v, k) => )}
+//
+// return (
+//
+//
+//
+// List Berita
+//
+// {beritaState.berita.findMany.data?.map((item) => (
+//
+//
+//
+// beritaState.berita.delete.byId(item.id)}
+// disabled={beritaState.berita.delete.loading}
+// color={colors['blue-button']} variant='transparent'>
+//
+//
+// {
+// router.push("/desa/berita/edit");
+// }} color={colors['blue-button']} variant='transparent'>
+//
+//
+//
+//
+// Kategori
+//
+// {item.kategoriBerita?.name}
+//
+// Judul
+//
+// {item.judul}
+//
+// Deskripsi
+//
+// {item.deskripsi}
+//
+// Gambar
+//
+//
+//
+//
+// ))}
+//
+//
+//
+//
+// )
+// }
+
function BeritaList() {
const beritaState = useProxy(stateDashboardBerita)
+ const [modalHapus, setModalHapus] = useState(false)
+ const [selectedId, setSelectedId] = useState(null)
+
useShallowEffect(() => {
beritaState.berita.findMany.load()
}, [])
- if (!beritaState.berita.findMany.data) return
- {Array.from({ length: 10 }).map((v, k) => )}
-
- return
- News List
- {beritaState.berita.findMany.data?.map((item) => (
- {item.judul}
- ))}
-
-}
+ const router = useRouter()
-function BeritaCreate() {
- const beritaState = useProxy(stateDashboardBerita)
- return
- Create Some News
- {
- beritaState.berita.create.form.katagoryBeritaId = val.id
- }} />
- {
- beritaState.berita.create.form.judul = val.target.value
- }} label={"Judul"} placeholder='masukkan judul' />
- {
- beritaState.berita.create.form.deskripsi = val.target.value
- }} label={"Deskripsi"} placeholder='masukkan deskripsi' />
-
-
-
- {
-
- beritaState.berita.create.form.content = val
- beritaState.berita.create.create()
- }} />
-
-}
-
-function SelectCategory({ onChange }: {
- onChange: (value: Prisma.KatagoryBeritaGetPayload<{
- select: {
- name: true,
- id: true
+ const handleHapus = () => {
+ if (selectedId) {
+ beritaState.berita.delete.byId(selectedId)
+ setModalHapus(false)
+ setSelectedId(null)
}
- }>) => void
-}) {
- const beritaState = useProxy(stateDashboardBerita)
- useShallowEffect(() => {
- beritaState.category.findMany.load()
- }, [])
+ }
- if (!beritaState.category.findMany.data) return
- return
- ({
- value: item.id,
- label: item.name
- }))} onChange={(v) => {
- const data = beritaState.category.findMany.data?.find((item) => item.id === v)
- if (!data) return
- onChange(data)
- }} />
-
+ if (!beritaState.berita.findMany.data) {
+ return (
+
+ {Array.from({ length: 10 }).map((_, k) => (
+
+ ))}
+
+ )
+ }
+
+ return (
+
+
+
+ List Berita
+
+ {beritaState.berita.findMany.data?.map((item) => (
+
+
+
+ {
+ setSelectedId(item.id)
+ setModalHapus(true)
+ }}
+ disabled={beritaState.berita.delete.loading}
+ color={colors['blue-button']} variant='transparent'
+ >
+
+
+ router.push("/desa/berita/edit")}
+ color={colors['blue-button']} variant='transparent'
+ >
+
+
+
+ Kategori
+ {item.kategoriBerita?.name}
+ Judul
+ {item.judul}
+ Deskripsi
+ {item.deskripsi}
+ Gambar
+
+
+
+ ))}
+
+
+
+
+ {/* Modal Konfirmasi Hapus */}
+ setModalHapus(false)}
+ onConfirm={handleHapus}
+ text='Apakah anda yakin ingin menghapus berita ini?'
+ />
+
+ )
}
+
+function SelectCategory({
+ onChange,
+}: {
+ onChange: (value: Prisma.KategoriBeritaGetPayload<{
+ select: {
+ name: true;
+ id: true;
+ };
+ }>) => void;
+}) {
+ const categoryState = useProxy(stateDashboardBerita.category);
+
+ useShallowEffect(() => {
+ categoryState.findMany.load();
+ }, []);
+
+ if (!categoryState.findMany.data) {
+ return ;
+ }
+
+ return (
+ Kategori}
+ placeholder="Pilih kategori"
+ data={categoryState.findMany.data.map((item) => ({
+ label: item.name,
+ value: item.id,
+ }))}
+ onChange={(val) => {
+ const selected = categoryState.findMany.data?.find((item) => item.id === val);
+ if (selected) {
+ onChange(selected);
+ }
+ }}
+ searchable
+ nothingFoundMessage="Tidak ditemukan"
+ />
+ );
+}
+
+
+// function SelectCategory({ onChange }: {
+// onChange: (value: Prisma.KategoriBeritaGetPayload<{
+// select: {
+// name: true,
+// id: true
+// }
+// }>) => void
+// }) {
+// const beritaState = useProxy(stateDashboardBerita)
+// useShallowEffect(() => {
+// beritaState.category.findMany.load()
+// }, [])
+
+// if (!beritaState.category.findMany.data) return
+// return
+// Pilih Kategori} data={beritaState.category.findMany.data.map((item) => ({
+// value: item.id,
+// label: item.name
+// }))} onChange={(v) => {
+// const data = beritaState.category.findMany.data?.find((item) => item.id === v)
+// if (!data) return
+// onChange(data)
+// }} />
+//
+// }
+
export default Page;
diff --git a/src/app/admin/(dashboard)/desa/gallery/page.tsx b/src/app/admin/(dashboard)/desa/gallery/page.tsx
index 2fd3c7d3..bb753607 100644
--- a/src/app/admin/(dashboard)/desa/gallery/page.tsx
+++ b/src/app/admin/(dashboard)/desa/gallery/page.tsx
@@ -1,11 +1,35 @@
-import React from 'react';
+import colors from '@/con/colors';
+import { Box, Stack, Tabs, TabsList, TabsPanel, TabsTab, Title } from '@mantine/core';
+import { IconPhoto, IconVideo } from '@tabler/icons-react';
+import Foto from './ui/foto/page';
+import Video from './ui/video/page';
-function Page() {
+function Gallery() {
return (
-
- Gallery
-
+
+
+ Gallery
+
+
+ }>
+ Foto
+
+ }>
+ Video
+
+
+
+
+
+
+
+
+
+
+
+
+
);
}
-export default Page;
+export default Gallery;
diff --git a/src/app/admin/(dashboard)/desa/gallery/ui/foto/listPage.tsx b/src/app/admin/(dashboard)/desa/gallery/ui/foto/listPage.tsx
new file mode 100644
index 00000000..4cecb3a0
--- /dev/null
+++ b/src/app/admin/(dashboard)/desa/gallery/ui/foto/listPage.tsx
@@ -0,0 +1,17 @@
+import colors from '@/con/colors';
+import { Box, Paper, Stack, Title } from '@mantine/core';
+import React from 'react';
+
+function ListFoto() {
+ return (
+
+
+
+ List Foto
+
+
+
+ );
+}
+
+export default ListFoto;
diff --git a/src/app/admin/(dashboard)/desa/gallery/ui/foto/page.tsx b/src/app/admin/(dashboard)/desa/gallery/ui/foto/page.tsx
new file mode 100644
index 00000000..a696750c
--- /dev/null
+++ b/src/app/admin/(dashboard)/desa/gallery/ui/foto/page.tsx
@@ -0,0 +1,52 @@
+import colors from '@/con/colors';
+import { Box, Button, Center, Group, Paper, SimpleGrid, Stack, Text, TextInput, Title } from '@mantine/core';
+import { IconUpload } from '@tabler/icons-react';
+import { DesaEditor } from '../../../_com/desaEditor';
+import ListFoto from './listPage';
+
+function Foto() {
+ return (
+
+
+
+
+
+ Foto
+ Tanggal Foto}
+ placeholder="2022-01-01"
+ />
+ Judul Foto}
+ placeholder="Judul Foto"
+ />
+ Upload Foto
+
+
+
+
+
+
+ Deskripsi Foto
+
+
+
+
+ Submit
+
+
+
+
+
+
+
+
+ );
+}
+
+export default Foto;
diff --git a/src/app/admin/(dashboard)/desa/gallery/ui/video/listPage.tsx b/src/app/admin/(dashboard)/desa/gallery/ui/video/listPage.tsx
new file mode 100644
index 00000000..83880a4d
--- /dev/null
+++ b/src/app/admin/(dashboard)/desa/gallery/ui/video/listPage.tsx
@@ -0,0 +1,17 @@
+import colors from '@/con/colors';
+import { Box, Paper, Stack, Title } from '@mantine/core';
+import React from 'react';
+
+function ListVideo() {
+ return (
+
+
+
+ List Video
+
+
+
+ );
+}
+
+export default ListVideo;
diff --git a/src/app/admin/(dashboard)/desa/gallery/ui/video/page.tsx b/src/app/admin/(dashboard)/desa/gallery/ui/video/page.tsx
new file mode 100644
index 00000000..f25c6873
--- /dev/null
+++ b/src/app/admin/(dashboard)/desa/gallery/ui/video/page.tsx
@@ -0,0 +1,52 @@
+import colors from '@/con/colors';
+import { Box, Button, Center, Group, Paper, SimpleGrid, Stack, Text, TextInput, Title } from '@mantine/core';
+import { IconUpload } from '@tabler/icons-react';
+import { DesaEditor } from '../../../_com/desaEditor';
+import ListVideo from './listPage';
+
+function Video() {
+ return (
+
+
+
+
+
+ Video
+ Tanggal Video}
+ placeholder="2022-01-01"
+ />
+ Judul Video}
+ placeholder="Judul Video"
+ />
+ Upload Video
+
+
+
+
+
+
+ Deskripsi Video
+
+
+
+
+ Submit
+
+
+
+
+
+
+
+
+ );
+}
+
+export default Video;
diff --git a/src/app/admin/(dashboard)/desa/layanan/page.tsx b/src/app/admin/(dashboard)/desa/layanan/page.tsx
index bc8d36f9..83f6a69b 100644
--- a/src/app/admin/(dashboard)/desa/layanan/page.tsx
+++ b/src/app/admin/(dashboard)/desa/layanan/page.tsx
@@ -1,11 +1,48 @@
-import React from 'react';
+import colors from '@/con/colors';
+import { Box, Stack, Tabs, TabsList, TabsPanel, TabsTab, Title } from '@mantine/core';
+import SuratKeterangan from './ui/surat_keterangan/page';
+import PerizinanUsaha from './ui/perizinan_usaha/page';
+import TelunjukSaktiDesa from './ui/telunjuk_sakti_desa/page';
+import PendudukNonPermanent from './ui/penduduk_non_permanent/page';
function Page() {
return (
-
- Layanan
-
+
+
+ Layanan
+
+
+
+ Pelayanan Surat Keterangan
+
+
+ Pelayanan Perizinan Berusaha
+
+
+ Pelayanan Telunjuk Sakti Desa
+
+
+ Pelayanan Penduduk Non-Permanent
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
);
}
export default Page;
+
diff --git a/src/app/admin/(dashboard)/desa/layanan/ui/penduduk_non_permanent/listPage.tsx b/src/app/admin/(dashboard)/desa/layanan/ui/penduduk_non_permanent/listPage.tsx
new file mode 100644
index 00000000..93d7c0dc
--- /dev/null
+++ b/src/app/admin/(dashboard)/desa/layanan/ui/penduduk_non_permanent/listPage.tsx
@@ -0,0 +1,17 @@
+import colors from '@/con/colors';
+import { Box, Paper, Stack, Title } from '@mantine/core';
+import React from 'react';
+
+function ListPendudukNonPermanent() {
+ return (
+
+
+
+ List Penduduk Non-Permanent
+
+
+
+ );
+}
+
+export default ListPendudukNonPermanent;
diff --git a/src/app/admin/(dashboard)/desa/layanan/ui/penduduk_non_permanent/page.tsx b/src/app/admin/(dashboard)/desa/layanan/ui/penduduk_non_permanent/page.tsx
new file mode 100644
index 00000000..a3585e50
--- /dev/null
+++ b/src/app/admin/(dashboard)/desa/layanan/ui/penduduk_non_permanent/page.tsx
@@ -0,0 +1,35 @@
+import colors from '@/con/colors';
+import { Box, SimpleGrid, Paper, Stack, Title, Group, Button, Text } from '@mantine/core';
+import React from 'react';
+import { DesaEditor } from '../../../_com/desaEditor';
+import ListPendudukNonPermanent from './listPage';
+
+function PendudukNonPermanent() {
+ return (
+
+
+
+
+
+ Penduduk Non-Permanent
+ Deskripsi Penduduk Non-Permanent
+
+
+
+ Submit
+
+
+
+
+
+
+
+
+ );
+}
+
+export default PendudukNonPermanent;
+
diff --git a/src/app/admin/(dashboard)/desa/layanan/ui/perizinan_usaha/listPage.tsx b/src/app/admin/(dashboard)/desa/layanan/ui/perizinan_usaha/listPage.tsx
new file mode 100644
index 00000000..440f1a43
--- /dev/null
+++ b/src/app/admin/(dashboard)/desa/layanan/ui/perizinan_usaha/listPage.tsx
@@ -0,0 +1,17 @@
+import colors from '@/con/colors';
+import { Box, Paper, Stack, Title } from '@mantine/core';
+import React from 'react';
+
+function ListPerizinanUsaha() {
+ return (
+
+
+
+ List Perizinan Usaha
+
+
+
+ );
+}
+
+export default ListPerizinanUsaha;
diff --git a/src/app/admin/(dashboard)/desa/layanan/ui/perizinan_usaha/page.tsx b/src/app/admin/(dashboard)/desa/layanan/ui/perizinan_usaha/page.tsx
new file mode 100644
index 00000000..aa85a19f
--- /dev/null
+++ b/src/app/admin/(dashboard)/desa/layanan/ui/perizinan_usaha/page.tsx
@@ -0,0 +1,40 @@
+import colors from '@/con/colors';
+import { Box, Button, Group, Paper, SimpleGrid, Stack, Text, Title } from '@mantine/core';
+import React from 'react';
+import ListPerizinanUsaha from './listPage';
+import { DesaEditor } from '../../../_com/desaEditor';
+
+function PerizinanUsaha() {
+ return (
+
+
+
+
+
+
+ Pelayanan Perizinan Usaha
+
+ Deskripsi Perizinan Usaha
+
+
+
+
+ Submit
+
+
+
+
+
+
+
+
+
+ );
+}
+
+export default PerizinanUsaha;
diff --git a/src/app/admin/(dashboard)/desa/layanan/ui/surat_keterangan/listPage.tsx b/src/app/admin/(dashboard)/desa/layanan/ui/surat_keterangan/listPage.tsx
new file mode 100644
index 00000000..bd4dd422
--- /dev/null
+++ b/src/app/admin/(dashboard)/desa/layanan/ui/surat_keterangan/listPage.tsx
@@ -0,0 +1,17 @@
+import colors from '@/con/colors';
+import { Box, Paper, Stack, Title } from '@mantine/core';
+import React from 'react';
+
+function ListSuratKeterangan() {
+ return (
+
+
+
+ List Surat Keterangan
+
+
+
+ );
+}
+
+export default ListSuratKeterangan;
diff --git a/src/app/admin/(dashboard)/desa/layanan/ui/surat_keterangan/page.tsx b/src/app/admin/(dashboard)/desa/layanan/ui/surat_keterangan/page.tsx
new file mode 100644
index 00000000..5ac1070e
--- /dev/null
+++ b/src/app/admin/(dashboard)/desa/layanan/ui/surat_keterangan/page.tsx
@@ -0,0 +1,48 @@
+import colors from '@/con/colors';
+import { Box, SimpleGrid, Paper, Stack, Title, Button, Group, TextInput, Text, Center, Flex } from '@mantine/core';
+import { IconUpload } from '@tabler/icons-react';
+import React from 'react';
+import ListSuratKeterangan from './listPage';
+
+function SuratKeterangan() {
+ return (
+
+
+
+
+
+
+ Pelayanan Surat Keterangan
+ Nama Surat Keterangan}
+ placeholder='masukkan nama surat keterangan'
+ />
+ Upload Gambar Surat Keterangan
+
+
+
+
+
+
+ *
+ Upload foto untuk konten surat keterangan
+
+
+
+ Submit
+
+
+
+
+
+
+
+
+
+ );
+}
+
+export default SuratKeterangan;
diff --git a/src/app/admin/(dashboard)/desa/layanan/ui/telunjuk_sakti_desa/listPage.tsx b/src/app/admin/(dashboard)/desa/layanan/ui/telunjuk_sakti_desa/listPage.tsx
new file mode 100644
index 00000000..42f8d68a
--- /dev/null
+++ b/src/app/admin/(dashboard)/desa/layanan/ui/telunjuk_sakti_desa/listPage.tsx
@@ -0,0 +1,17 @@
+import colors from '@/con/colors';
+import { Box, Paper, Stack, Title } from '@mantine/core';
+import React from 'react';
+
+function ListTelunjukSaktiDesa() {
+ return (
+
+
+
+ List Telunjuk Sakti Desa
+
+
+
+ );
+}
+
+export default ListTelunjukSaktiDesa;
diff --git a/src/app/admin/(dashboard)/desa/layanan/ui/telunjuk_sakti_desa/page.tsx b/src/app/admin/(dashboard)/desa/layanan/ui/telunjuk_sakti_desa/page.tsx
new file mode 100644
index 00000000..60a28a7c
--- /dev/null
+++ b/src/app/admin/(dashboard)/desa/layanan/ui/telunjuk_sakti_desa/page.tsx
@@ -0,0 +1,36 @@
+import colors from '@/con/colors';
+import { Box, SimpleGrid, Paper, Stack, Title, Group, Button, Text } from '@mantine/core';
+import React from 'react';
+import { DesaEditor } from '../../../_com/desaEditor';
+import ListTelunjukSaktiDesa from './listPage';
+
+function TelunjukSaktiDesa() {
+ return (
+
+
+
+
+
+ Telunjuk Sakti Desa
+
+ Deskripsi Telunjuk Sakti Desa
+
+
+
+
+ Submit
+
+
+
+
+
+
+
+
+ );
+}
+
+export default TelunjukSaktiDesa;
diff --git a/src/app/admin/(dashboard)/desa/penghargaan/page.tsx b/src/app/admin/(dashboard)/desa/penghargaan/page.tsx
index 8e3cf122..40e01edb 100644
--- a/src/app/admin/(dashboard)/desa/penghargaan/page.tsx
+++ b/src/app/admin/(dashboard)/desa/penghargaan/page.tsx
@@ -1,10 +1,33 @@
+import colors from '@/con/colors';
+import { Box, Stack, Tabs, TabsList, TabsPanel, TabsTab, Title } from '@mantine/core';
import React from 'react';
+import Penghargaan from './ui/penghargaan/page';
+import GambarPerhargaan from './ui/gambar_perhargaan/page';
function Page() {
return (
-
- Penghargaan
-
+
+
+ Penghargaan
+
+
+
+ Penghargaan
+
+
+ Gambar Penghargaan
+
+
+
+
+
+
+
+
+
+
+
+
);
}
diff --git a/src/app/admin/(dashboard)/desa/penghargaan/ui/gambar_perhargaan/listPage.tsx b/src/app/admin/(dashboard)/desa/penghargaan/ui/gambar_perhargaan/listPage.tsx
new file mode 100644
index 00000000..cfdaf4c7
--- /dev/null
+++ b/src/app/admin/(dashboard)/desa/penghargaan/ui/gambar_perhargaan/listPage.tsx
@@ -0,0 +1,17 @@
+import colors from '@/con/colors';
+import { Box, Paper, Stack, Title } from '@mantine/core';
+import React from 'react';
+
+function ListGambarPenghargaan() {
+ return (
+
+
+
+ List Gambar Penghargaan
+
+
+
+ );
+}
+
+export default ListGambarPenghargaan;
diff --git a/src/app/admin/(dashboard)/desa/penghargaan/ui/gambar_perhargaan/page.tsx b/src/app/admin/(dashboard)/desa/penghargaan/ui/gambar_perhargaan/page.tsx
new file mode 100644
index 00000000..93bfcbe7
--- /dev/null
+++ b/src/app/admin/(dashboard)/desa/penghargaan/ui/gambar_perhargaan/page.tsx
@@ -0,0 +1,50 @@
+import colors from '@/con/colors';
+import { Box, Paper, SimpleGrid, Stack, Title, Text, Group, Button, TextInput, Center } from '@mantine/core';
+import React from 'react';
+import { DesaEditor } from '../../../_com/desaEditor';
+import ListGambarPenghargaan from './listPage';
+import { IconUpload } from '@tabler/icons-react';
+
+
+function GambarPerhargaan() {
+ return (
+
+
+
+
+
+
+ Tambah Gambar Penghargaan
+
+ Deskripsi Gambar Penghargaan
+
+
+ Upload Gambar Penghargaan
+
+
+
+
+
+
+
+
+ Submit
+
+
+
+
+
+
+
+
+
+ );
+}
+
+export default GambarPerhargaan;
diff --git a/src/app/admin/(dashboard)/desa/penghargaan/ui/penghargaan/listPage.tsx b/src/app/admin/(dashboard)/desa/penghargaan/ui/penghargaan/listPage.tsx
new file mode 100644
index 00000000..d217eb80
--- /dev/null
+++ b/src/app/admin/(dashboard)/desa/penghargaan/ui/penghargaan/listPage.tsx
@@ -0,0 +1,17 @@
+import colors from '@/con/colors';
+import { Box, Paper, Stack, Title } from '@mantine/core';
+import React from 'react';
+
+function ListPenghargaan() {
+ return (
+
+
+
+ List Penghargaan
+
+
+
+ );
+}
+
+export default ListPenghargaan;
diff --git a/src/app/admin/(dashboard)/desa/penghargaan/ui/penghargaan/page.tsx b/src/app/admin/(dashboard)/desa/penghargaan/ui/penghargaan/page.tsx
new file mode 100644
index 00000000..ba63a677
--- /dev/null
+++ b/src/app/admin/(dashboard)/desa/penghargaan/ui/penghargaan/page.tsx
@@ -0,0 +1,40 @@
+import colors from '@/con/colors';
+import { Box, Button, Group, Paper, SimpleGrid, Stack, Text, Title } from '@mantine/core';
+import React from 'react';
+import { DesaEditor } from '../../../_com/desaEditor';
+import ListPenghargaan from './listPage';
+
+function Penghargaan() {
+ return (
+
+
+
+
+
+
+ Penghargaan
+
+ Deskripsi Penghargaan
+
+
+
+
+ Submit
+
+
+
+
+
+
+
+
+
+ );
+}
+
+export default Penghargaan;
diff --git a/src/app/admin/(dashboard)/desa/pengumuman/page.tsx b/src/app/admin/(dashboard)/desa/pengumuman/page.tsx
index 660fe2d9..22ebd3d9 100644
--- a/src/app/admin/(dashboard)/desa/pengumuman/page.tsx
+++ b/src/app/admin/(dashboard)/desa/pengumuman/page.tsx
@@ -1,62 +1,75 @@
'use client'
-import { Group, Select, SimpleGrid, Skeleton, Stack, Text, TextInput } from '@mantine/core';
+import { Box, Group, Paper, Select, SimpleGrid, Skeleton, Stack, Text, TextInput, Title } from '@mantine/core';
import React from 'react';
import { useProxy } from 'valtio/utils';
import stateDesaPengumuman from '../../_state/desa/pengumuman';
import { useShallowEffect } from '@mantine/hooks';
import { Prisma } from '@prisma/client';
import { BeritaEditor } from '../berita/_com/BeritaEditor';
+import colors from '@/con/colors';
function Page() {
return (
-
+
+ Pengumuman
-
+
-
+
);
}
+function PengumumanCreate() {
+ const pengumumanState = useProxy(stateDesaPengumuman)
+
+
+ return (
+
+
+
+ {
+ pengumumanState.pengumuman.create.form.categoryPengumumanId = val.id
+ }} />
+ {
+ pengumumanState.pengumuman.create.form.judul = val.target.value
+ }} label={Judul } placeholder='masukkan judul' />
+ {
+ pengumumanState.pengumuman.create.form.deskripsi = val.target.value
+ }} label={Deskripsi } placeholder='masukkan deskripsi' />
+ {
+ pengumumanState.pengumuman.create.form.content = val
+ pengumumanState.pengumuman.create.create()
+ }} />
+
+
+
+ )
+}
+
function PengumumanList() {
const pengumumanState = useProxy(stateDesaPengumuman)
useShallowEffect(() => {
pengumumanState.pengumuman.findMany.load()
}, [])
- if (!pengumumanState.pengumuman.findMany.data) return
+ if (!pengumumanState.pengumuman.findMany.data) return
{Array.from({ length: 10 }).map((v, k) => )}
- return
- Announcement List
- {pengumumanState.pengumuman.findMany.data?.map((item) => (
- {item.judul}
- ))}
- ;
-}
-
-function PengumumanCreate() {
- const pengumumanState = useProxy(stateDesaPengumuman)
-
-
- return
- Create Some Announcement
- {
- pengumumanState.pengumuman.create.form.categoryPengumumanId = val.id
- }} />
- {
- pengumumanState.pengumuman.create.form.judul = val.target.value
- }} label={"Judul"} placeholder='masukkan judul' />
- {
- pengumumanState.pengumuman.create.form.deskripsi = val.target.value
- }} label={"Deskripsi"} placeholder='masukkan deskripsi' />
- {
- pengumumanState.pengumuman.create.form.content = val
- pengumumanState.pengumuman.create.create()
- }} />
-
+ return (
+
+
+
+ List Pengumuman
+ {pengumumanState.pengumuman.findMany.data?.map((item) => (
+ {item.judul}
+ ))}
+
+
+
+ )
}
function SelectCategory({ onChange }: {
@@ -75,7 +88,7 @@ function SelectCategory({ onChange }: {
if (!pengumumanState.category.findMany.data) return
return
{/* {JSON.stringify(pengumumanState.category.findMany.data)} */}
- ({
+ Pilih Kategori} data={pengumumanState.category.findMany.data.map((item) => ({
value: item.id,
label: item.name
}))} onChange={(v) => {
diff --git a/src/app/admin/(dashboard)/desa/potensi/listPage.tsx b/src/app/admin/(dashboard)/desa/potensi/listPage.tsx
new file mode 100644
index 00000000..255b08b2
--- /dev/null
+++ b/src/app/admin/(dashboard)/desa/potensi/listPage.tsx
@@ -0,0 +1,17 @@
+import colors from '@/con/colors';
+import { Box, Paper, Stack, Title } from '@mantine/core';
+import React from 'react';
+
+function ListPotensi() {
+ return (
+
+
+
+ List Potensi Desa
+
+
+
+ );
+}
+
+export default ListPotensi;
diff --git a/src/app/admin/(dashboard)/desa/potensi/page.tsx b/src/app/admin/(dashboard)/desa/potensi/page.tsx
index 8a2285b8..e626a6ab 100644
--- a/src/app/admin/(dashboard)/desa/potensi/page.tsx
+++ b/src/app/admin/(dashboard)/desa/potensi/page.tsx
@@ -1,11 +1,40 @@
-import React from 'react';
+import colors from '@/con/colors';
+import { Box, Button, Group, Paper, SimpleGrid, Stack, TextInput, Title } from '@mantine/core';
+import ListPotensi from './listPage';
-function Page() {
+function Potensi() {
return (
-
- Potensi
-
+
+
+ Potensi Desa
+
+
+
+
+
+
+
+
+ Submit
+
+
+
+
+
+
+
+
+
);
}
-export default Page;
+export default Potensi;
diff --git a/src/app/admin/(dashboard)/desa/profile/page.tsx b/src/app/admin/(dashboard)/desa/profile/page.tsx
index 216d6d1d..8f85b2fa 100644
--- a/src/app/admin/(dashboard)/desa/profile/page.tsx
+++ b/src/app/admin/(dashboard)/desa/profile/page.tsx
@@ -1,10 +1,52 @@
+import colors from '@/con/colors';
+import { Stack, Title, Tabs, TabsList, TabsTab, TabsPanel } from '@mantine/core';
import React from 'react';
+import SejarahDesa from './ui/sejarah_desa/page';
+import VisiMisiDesa from './ui/visi_misi_desa/page';
+import LambangDesa from './ui/lambang_desa/page';
+import MaskotDesa from './ui/maskot_desa/page';
+import ProfilePerbekel from './ui/profile_perbekel/page';
function Page() {
return (
-
- Profile
-
+
+ Profile Desa
+
+
+
+ Sejarah Desa
+
+
+ Visi Misi Desa
+
+
+ Lambang Desa
+
+
+ Maskot Desa
+
+
+ Profile Perbekel
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
);
}
diff --git a/src/app/admin/(dashboard)/desa/profile/ui/lambang_desa/page.tsx b/src/app/admin/(dashboard)/desa/profile/ui/lambang_desa/page.tsx
new file mode 100644
index 00000000..ca48c832
--- /dev/null
+++ b/src/app/admin/(dashboard)/desa/profile/ui/lambang_desa/page.tsx
@@ -0,0 +1,39 @@
+import colors from '@/con/colors';
+import { Box, SimpleGrid, Paper, Stack, Title, Group, Button, Text } from '@mantine/core';
+import React from 'react';
+import { DesaEditor } from '../../../_com/desaEditor';
+
+function LambangDesa() {
+ return (
+
+
+
+
+
+ Lambang Desa
+ Deskripsi Lambang Desa
+
+
+
+ Submit
+
+
+
+
+
+
+
+
+ List Lambang Desa
+
+
+
+
+
+ );
+}
+
+export default LambangDesa;
diff --git a/src/app/admin/(dashboard)/desa/profile/ui/maskot_desa/page.tsx b/src/app/admin/(dashboard)/desa/profile/ui/maskot_desa/page.tsx
new file mode 100644
index 00000000..9fc4973b
--- /dev/null
+++ b/src/app/admin/(dashboard)/desa/profile/ui/maskot_desa/page.tsx
@@ -0,0 +1,39 @@
+import colors from '@/con/colors';
+import { Box, SimpleGrid, Paper, Stack, Title, Group, Button, Text } from '@mantine/core';
+import React from 'react';
+import { DesaEditor } from '../../../_com/desaEditor';
+
+function MaskotDesa() {
+ return (
+
+
+
+
+
+ Maskot Desa
+ Deskripsi Maskot Desa
+
+
+
+ Submit
+
+
+
+
+
+
+
+
+ List Maskot Desa
+
+
+
+
+
+ );
+}
+
+export default MaskotDesa;
diff --git a/src/app/admin/(dashboard)/desa/profile/ui/profile_perbekel/page.tsx b/src/app/admin/(dashboard)/desa/profile/ui/profile_perbekel/page.tsx
new file mode 100644
index 00000000..702189dd
--- /dev/null
+++ b/src/app/admin/(dashboard)/desa/profile/ui/profile_perbekel/page.tsx
@@ -0,0 +1,49 @@
+import colors from '@/con/colors';
+import { Box, SimpleGrid, Paper, Stack, Title, Group, Button, TextInput, Text } from '@mantine/core';
+import React from 'react';
+import { DesaEditor } from '../../../_com/desaEditor';
+
+function ProfilePerbekel() {
+ return (
+
+
+
+
+
+ Profil Perbekel
+
+ Biodata
+
+ Pengalaman
+
+ Pengalaman Organisasi
+
+ Program Unggulan
+
+
+
+ Submit
+
+
+
+
+
+
+
+
+ List Profil Perbekel
+
+
+
+
+
+ );
+}
+
+export default ProfilePerbekel;
diff --git a/src/app/admin/(dashboard)/desa/profile/ui/sejarah_desa/listPage.tsx b/src/app/admin/(dashboard)/desa/profile/ui/sejarah_desa/listPage.tsx
new file mode 100644
index 00000000..35a8dbda
--- /dev/null
+++ b/src/app/admin/(dashboard)/desa/profile/ui/sejarah_desa/listPage.tsx
@@ -0,0 +1,17 @@
+import colors from '@/con/colors';
+import { Box, Paper, Stack, Title } from '@mantine/core';
+import React from 'react';
+
+function ListPage() {
+ return (
+
+
+
+ List Sejarah Desa
+
+
+
+ );
+}
+
+export default ListPage;
diff --git a/src/app/admin/(dashboard)/desa/profile/ui/sejarah_desa/page.tsx b/src/app/admin/(dashboard)/desa/profile/ui/sejarah_desa/page.tsx
new file mode 100644
index 00000000..ea95455e
--- /dev/null
+++ b/src/app/admin/(dashboard)/desa/profile/ui/sejarah_desa/page.tsx
@@ -0,0 +1,65 @@
+'use client'
+import stateProfileDesa from '@/app/admin/(dashboard)/_state/desa/profile';
+import colors from '@/con/colors';
+import { Box, Button, Group, Paper, SimpleGrid, Stack, Text, Title } from '@mantine/core';
+import { useProxy } from 'valtio/utils';
+import DesaEditorText from '../../../_com/desaEditorText';
+import ListPage from './listPage';
+import { useShallowEffect } from '@mantine/hooks';
+
+
+function SejarahDesa() {
+ const stateSejarah = useProxy(stateProfileDesa.Sejarah)
+
+ useShallowEffect(() => {
+ if (!stateSejarah.findById.data) {
+ stateSejarah.findById.initialize()
+ }
+ }, [])
+
+ const submit = () => {
+ if (stateSejarah.findById.data?.id && stateSejarah.findById.data.sejarah) {
+ stateSejarah.update.save({
+ id: stateSejarah.findById.data.id,
+ sejarah: stateSejarah.findById.data.sejarah
+ })
+ }
+ }
+
+ return (
+
+
+
+
+
+ Sejarah Desa
+ Deskripsi Sejarah Desa
+ {
+ if (stateSejarah.findById.data) {
+ stateSejarah.findById.data.sejarah = val
+ }
+ }}
+ initialContent={stateSejarah.findById.data?.sejarah ?? ""}
+ />
+
+
+ Submit
+
+
+
+
+
+
+
+
+ );
+}
+
+export default SejarahDesa;
diff --git a/src/app/admin/(dashboard)/desa/profile/ui/visi_misi_desa/page.tsx b/src/app/admin/(dashboard)/desa/profile/ui/visi_misi_desa/page.tsx
new file mode 100644
index 00000000..f0ccf437
--- /dev/null
+++ b/src/app/admin/(dashboard)/desa/profile/ui/visi_misi_desa/page.tsx
@@ -0,0 +1,64 @@
+import colors from '@/con/colors';
+import { Box, Button, Group, Paper, SimpleGrid, Stack, Text, Title } from '@mantine/core';
+import { DesaEditor } from '../../../_com/desaEditor';
+
+function VisiMisiDesa() {
+ return (
+
+
+
+
+
+ Visi Desa
+ Deskripsi Visi Desa
+
+
+
+ Submit
+
+
+
+
+
+
+
+
+ List Visi Desa
+
+
+
+
+
+
+
+
+ Misi Desa
+ Deskripsi Misi Desa
+
+
+
+ Submit
+
+
+
+
+
+
+
+
+ List Misi Desa
+
+
+
+
+
+ );
+}
+
+export default VisiMisiDesa;
diff --git a/src/app/admin/(dashboard)/ekonomi/demografi-pekerjaan/page.tsx b/src/app/admin/(dashboard)/ekonomi/demografi-pekerjaan/page.tsx
index 630313ea..c2a37b38 100644
--- a/src/app/admin/(dashboard)/ekonomi/demografi-pekerjaan/page.tsx
+++ b/src/app/admin/(dashboard)/ekonomi/demografi-pekerjaan/page.tsx
@@ -1,10 +1,46 @@
+import colors from '@/con/colors';
+import { Box, Button, Group, Paper, Stack, Text, TextInput, Title } from '@mantine/core';
import React from 'react';
function Page() {
return (
-
- demografi-pekerjaan
-
+
+
+
+
+
+ Demografi Pekerjaan
+ Jumlah Pekerja Laki - Laki}
+ placeholder="Masukkan jumlah pekerja laki - laki"
+ />
+ Jumlah Pekerja Perempuan}
+ placeholder="Masukkan jumlah pekerja perempuan"
+ />
+ Nama Pekerjaan}
+ placeholder="Masukkan nama pekerjaan"
+ />
+
+
+ Submit
+
+
+
+
+
+
+
+
+ Grafik Demografi Pekerjaan
+
+
+
+
+
);
}
diff --git a/src/app/admin/(dashboard)/ekonomi/jumlah-penduduk-miskin-2024-2025/page.tsx b/src/app/admin/(dashboard)/ekonomi/jumlah-penduduk-miskin-2024-2025/page.tsx
index cd2b60db..2b121b34 100644
--- a/src/app/admin/(dashboard)/ekonomi/jumlah-penduduk-miskin-2024-2025/page.tsx
+++ b/src/app/admin/(dashboard)/ekonomi/jumlah-penduduk-miskin-2024-2025/page.tsx
@@ -1,10 +1,42 @@
+import { Box, Button, Group, Paper, Stack, TextInput, Title } from '@mantine/core';
+import colors from '@/con/colors';
import React from 'react';
function Page() {
return (
-
- jumlah-penduduk-miskin-2024-2025
-
+
+
+
+
+
+ Jumlah Penduduk Miskin 2024-2025
+
+
+
+
+ Submit
+
+
+
+
+
+
+
+
+ Grafik Jumlah Penduduk Miskin 2024-2025
+
+
+
+
+
);
}
diff --git a/src/app/admin/(dashboard)/ekonomi/jumlah-penduduk-usia-kerja-yang-menganggur/page.tsx b/src/app/admin/(dashboard)/ekonomi/jumlah-penduduk-usia-kerja-yang-menganggur/page.tsx
index 04a107b2..6f9e8e20 100644
--- a/src/app/admin/(dashboard)/ekonomi/jumlah-penduduk-usia-kerja-yang-menganggur/page.tsx
+++ b/src/app/admin/(dashboard)/ekonomi/jumlah-penduduk-usia-kerja-yang-menganggur/page.tsx
@@ -1,11 +1,31 @@
-import React from 'react';
+import colors from "@/con/colors";
+import { Box, Stack, Tabs, TabsList, TabsPanel, TabsTab, Title } from "@mantine/core";
+import PengangguranBerdasarkanUsia from "./ui/pengangguranBerdasarkanUsia/page";
+import PengangguranBerdasarkanPendidikan from "./ui/pengangguranBerdasarkanPendidikan/page";
-function Page() {
+export default function Page() {
return (
-
- jumlah-penduduk-usia-kerja-yang-menganggur
-
- );
-}
+
+
+ Jumlah Penduduk Usia Kerja yang Menganggur
+
+
+
+ Pengangguran Bredasarkan Usia
+
+
+ Pengangguran Bredasarkan Pendidikan
+
+
-export default Page;
+
+
+
+
+
+
+
+
+
+ );
+}
\ No newline at end of file
diff --git a/src/app/admin/(dashboard)/ekonomi/jumlah-penduduk-usia-kerja-yang-menganggur/ui/pengangguranBerdasarkanPendidikan/page.tsx b/src/app/admin/(dashboard)/ekonomi/jumlah-penduduk-usia-kerja-yang-menganggur/ui/pengangguranBerdasarkanPendidikan/page.tsx
new file mode 100644
index 00000000..89bfd0f2
--- /dev/null
+++ b/src/app/admin/(dashboard)/ekonomi/jumlah-penduduk-usia-kerja-yang-menganggur/ui/pengangguranBerdasarkanPendidikan/page.tsx
@@ -0,0 +1,47 @@
+import colors from '@/con/colors';
+import { Box, Button, Group, Paper, Stack, Text, TextInput, Title } from '@mantine/core';
+import React from 'react';
+
+function PengangguranBerdasarkanPendidikan() {
+ return (
+
+
+
+
+ Pengangguran Berdasarkan Pendidikan
+ Pendidikan SD}
+ placeholder="masukkan jumlah penduduk Pendidikan SD yang menganggur"
+ />
+ Pendidikan SMP}
+ placeholder="masukkan jumlah penduduk Pendidikan SMP yang menganggur"
+ />
+ Pendidikan SMA / SMK}
+ placeholder="masukkan jumlah penduduk Pendidikan SMA / SMK yang menganggur"
+ />
+ Pendidikan D1-D3 / S1}
+ placeholder="masukkan jumlah penduduk Pendidikan D1-D3 yang menganggur"
+ />
+
+
+ Submit
+
+
+
+
+
+
+
+
+ Grafik Pengangguran Berdasarkan Pendidikan
+
+
+
+
+ );
+}
+
+export default PengangguranBerdasarkanPendidikan;
diff --git a/src/app/admin/(dashboard)/ekonomi/jumlah-penduduk-usia-kerja-yang-menganggur/ui/pengangguranBerdasarkanUsia/page.tsx b/src/app/admin/(dashboard)/ekonomi/jumlah-penduduk-usia-kerja-yang-menganggur/ui/pengangguranBerdasarkanUsia/page.tsx
new file mode 100644
index 00000000..32bc78aa
--- /dev/null
+++ b/src/app/admin/(dashboard)/ekonomi/jumlah-penduduk-usia-kerja-yang-menganggur/ui/pengangguranBerdasarkanUsia/page.tsx
@@ -0,0 +1,47 @@
+import colors from '@/con/colors';
+import { Box, Button, Group, Paper, Stack, Text, TextInput, Title } from '@mantine/core';
+import React from 'react';
+
+function PengangguranBerdasarkanUsia() {
+ return (
+
+
+
+
+ Pengangguran Berdasarkan Usia
+ Usia 18 - 25 tahun}
+ placeholder="masukkan jumlah penduduk usia 18 - 25 tahun yang menganggur"
+ />
+ Usia 26 - 35 tahun}
+ placeholder="masukkan jumlah penduduk usia 26 - 35 tahun yang menganggur"
+ />
+ Usia 36 - 45 tahun}
+ placeholder="masukkan jumlah penduduk usia 36 - 45 tahun yang menganggur"
+ />
+ Usia 46+}
+ placeholder="masukkan jumlah penduduk usia 46+ yang menganggur"
+ />
+
+
+ Submit
+
+
+
+
+
+
+
+
+ Grafik Pengangguran Berdasarkan Usia
+
+
+
+
+ );
+}
+
+export default PengangguranBerdasarkanUsia;
diff --git a/src/app/admin/(dashboard)/ekonomi/jumlah-pengangguran-2024-2025/page.tsx b/src/app/admin/(dashboard)/ekonomi/jumlah-pengangguran-2024-2025/page.tsx
index 437f9d33..3f21fdb6 100644
--- a/src/app/admin/(dashboard)/ekonomi/jumlah-pengangguran-2024-2025/page.tsx
+++ b/src/app/admin/(dashboard)/ekonomi/jumlah-pengangguran-2024-2025/page.tsx
@@ -1,11 +1,37 @@
-import React from 'react';
+import colors from '@/con/colors';
+import { Stack, Tabs, TabsList, TabsPanel, TabsTab, Title } from '@mantine/core';
+import DataPengangguran from './ui/dataPengangguran/page';
+import GrafikDataPengangguran from './ui/grafikDataPengangguran/page';
+import DetailDataPengangguran from './ui/detailDataPengangguran/page';
function Page() {
return (
-
- jumlah-pengangguran-2024-2025
-
- );
+
+ Jumlah Pengangguran 2024-2025
+
+
+
+ Data Pengangguran Desa
+
+
+ Grafik Data Pengangguran Desa
+
+
+ Detail Data Pengangguran Desa
+
+
+
+
+
+
+
+
+
+
+
+
+
+ )
}
export default Page;
diff --git a/src/app/admin/(dashboard)/ekonomi/jumlah-pengangguran-2024-2025/ui/dataPengangguran/page.tsx b/src/app/admin/(dashboard)/ekonomi/jumlah-pengangguran-2024-2025/ui/dataPengangguran/page.tsx
new file mode 100644
index 00000000..45d9ff2f
--- /dev/null
+++ b/src/app/admin/(dashboard)/ekonomi/jumlah-pengangguran-2024-2025/ui/dataPengangguran/page.tsx
@@ -0,0 +1,51 @@
+import colors from '@/con/colors';
+import { Box, Button, Group, Paper, SimpleGrid, Stack, Text, TextInput, Title } from '@mantine/core';
+
+function DataPengangguran() {
+ return (
+
+
+
+
+
+
+ Data Pengangguran
+ Total Pengangguran}
+ placeholder="masukkan total pengangguran"
+ />
+ Pengangguran Terdidik}
+ placeholder="masukkan pengangguran terdidik"
+ />
+ Usia Produktif}
+ placeholder="masukkan usia produktif"
+ />
+ Sedang Mencari Kerja}
+ placeholder="masukkan jumlah sedang mencari kerja"
+ />
+
+
+ Submit
+
+
+
+
+
+
+
+
+ List Data Pengangguran
+
+
+
+
+
+
+
+ );
+}
+
+export default DataPengangguran;
diff --git a/src/app/admin/(dashboard)/ekonomi/jumlah-pengangguran-2024-2025/ui/detailDataPengangguran/page.tsx b/src/app/admin/(dashboard)/ekonomi/jumlah-pengangguran-2024-2025/ui/detailDataPengangguran/page.tsx
new file mode 100644
index 00000000..5da9dec4
--- /dev/null
+++ b/src/app/admin/(dashboard)/ekonomi/jumlah-pengangguran-2024-2025/ui/detailDataPengangguran/page.tsx
@@ -0,0 +1,18 @@
+import colors from '@/con/colors';
+import { Box, Paper, Stack, Title } from '@mantine/core';
+
+function DetailDataPengangguran() {
+ return (
+
+
+
+
+ Detail Data Pengangguran
+
+
+
+
+ );
+}
+
+export default DetailDataPengangguran;
diff --git a/src/app/admin/(dashboard)/ekonomi/jumlah-pengangguran-2024-2025/ui/grafikDataPengangguran/page.tsx b/src/app/admin/(dashboard)/ekonomi/jumlah-pengangguran-2024-2025/ui/grafikDataPengangguran/page.tsx
new file mode 100644
index 00000000..d0cf2a55
--- /dev/null
+++ b/src/app/admin/(dashboard)/ekonomi/jumlah-pengangguran-2024-2025/ui/grafikDataPengangguran/page.tsx
@@ -0,0 +1,49 @@
+import colors from '@/con/colors';
+import { Box, Button, Group, Paper, Stack, Text, TextInput, Title } from '@mantine/core';
+
+function GrafikDataPengangguran() {
+ return (
+
+
+
+
+
+ Data Pengangguran
+ Total Pengangguran}
+ placeholder="masukkan total pengangguran"
+ />
+ Pengangguran Terdidik}
+ placeholder="masukkan pengangguran terdidik"
+ />
+ Usia Produktif}
+ placeholder="masukkan usia produktif"
+ />
+ Sedang Mencari Kerja}
+ placeholder="masukkan jumlah sedang mencari kerja"
+ />
+
+
+ Submit
+
+
+
+
+
+
+
+
+ List Data Pengangguran
+
+
+
+
+
+
+ );
+}
+
+export default GrafikDataPengangguran;
diff --git a/src/app/admin/(dashboard)/ekonomi/lowongan-kerja-lokal/create/createLowongan.tsx b/src/app/admin/(dashboard)/ekonomi/lowongan-kerja-lokal/create/createLowongan.tsx
new file mode 100644
index 00000000..715e9f28
--- /dev/null
+++ b/src/app/admin/(dashboard)/ekonomi/lowongan-kerja-lokal/create/createLowongan.tsx
@@ -0,0 +1,29 @@
+import { Box, Stack, Text, TextInput, Title } from '@mantine/core';
+
+function CreateLowongan() {
+ return (
+
+
+ Lowongan Kerja Lokal
+ Bekerja Sebagai}
+ placeholder="masukkan bekerja sebagai"
+ />
+ Alamat Usaha}
+ placeholder="masukkan alamat usaha"
+ />
+ Waktu Kerja}
+ placeholder="masukkan waktu kerja"
+ />
+ Gaji selama 1 bulan}
+ placeholder="masukkan gaji selama 1 bulan"
+ />
+
+
+ );
+}
+
+export default CreateLowongan;
diff --git a/src/app/admin/(dashboard)/ekonomi/lowongan-kerja-lokal/listData/page.tsx b/src/app/admin/(dashboard)/ekonomi/lowongan-kerja-lokal/listData/page.tsx
new file mode 100644
index 00000000..199264e2
--- /dev/null
+++ b/src/app/admin/(dashboard)/ekonomi/lowongan-kerja-lokal/listData/page.tsx
@@ -0,0 +1,25 @@
+import colors from '@/con/colors';
+import { Box, Paper, Stack, Title, Text } from '@mantine/core';
+import React from 'react';
+
+function ListDataLowongan() {
+ return (
+
+
+ List Data Lowongan Kerja Lokal
+
+ Bekerja Sebagai
+
+ Alamat Usaha
+
+ Waktu Kerja
+
+ Gaji selama 1 bulan
+
+
+
+
+ );
+}
+
+export default ListDataLowongan;
diff --git a/src/app/admin/(dashboard)/ekonomi/lowongan-kerja-lokal/page.tsx b/src/app/admin/(dashboard)/ekonomi/lowongan-kerja-lokal/page.tsx
index 78f8a7ee..b222a023 100644
--- a/src/app/admin/(dashboard)/ekonomi/lowongan-kerja-lokal/page.tsx
+++ b/src/app/admin/(dashboard)/ekonomi/lowongan-kerja-lokal/page.tsx
@@ -1,10 +1,31 @@
+import colors from '@/con/colors';
+import { Box, Button, Group, Paper, SimpleGrid, Stack, Title } from '@mantine/core';
import React from 'react';
+import CreateLowongan from './create/createLowongan';
+import ListDataLowongan from './listData/page';
function Page() {
return (
-
- lowongan-kerja-lokal
-
+
+
+
+
+ Lowongan Kerja Lokal
+
+
+
+ Submit
+
+
+
+
+
+
+
+
+
+
+
);
}
diff --git a/src/app/admin/(dashboard)/ekonomi/pasar-desa/create/createPasarDesa.tsx b/src/app/admin/(dashboard)/ekonomi/pasar-desa/create/createPasarDesa.tsx
new file mode 100644
index 00000000..ca116352
--- /dev/null
+++ b/src/app/admin/(dashboard)/ekonomi/pasar-desa/create/createPasarDesa.tsx
@@ -0,0 +1,36 @@
+import colors from '@/con/colors';
+import { Box, Stack, Text, TextInput, Title } from '@mantine/core';
+import { IconImageInPicture } from '@tabler/icons-react';
+import React from 'react';
+
+function CreatePasarDesa() {
+ return (
+
+
+ Produk Pasar Desa
+
+ Masukkan Foto Produk
+
+
+ Nama Produk}
+ placeholder="masukkan nama produk"
+ />
+ Harga Produk}
+ placeholder="masukkan harga produk"
+ />
+ Rating Produk}
+ placeholder="masukkan rating produk"
+ />
+ Alamat Usaha}
+ placeholder="masukkan alamat usaha"
+ />
+
+
+ );
+}
+
+export default CreatePasarDesa;
diff --git a/src/app/admin/(dashboard)/ekonomi/pasar-desa/listData/page.tsx b/src/app/admin/(dashboard)/ekonomi/pasar-desa/listData/page.tsx
new file mode 100644
index 00000000..3809f2ad
--- /dev/null
+++ b/src/app/admin/(dashboard)/ekonomi/pasar-desa/listData/page.tsx
@@ -0,0 +1,32 @@
+import colors from '@/con/colors';
+import { Box, Paper, Stack, Text, Title } from '@mantine/core';
+import { IconImageInPicture } from '@tabler/icons-react';
+import React from 'react';
+
+function ListDataUsaha() {
+ return (
+
+
+
+
+ List Produk Pasar Desa
+
+ Foto Produk
+
+
+ Nama Produk
+
+ Harga Produk
+
+ Rating Produk
+
+ Alamat Usaha
+
+
+
+
+
+ );
+}
+
+export default ListDataUsaha;
diff --git a/src/app/admin/(dashboard)/ekonomi/pasar-desa/page.tsx b/src/app/admin/(dashboard)/ekonomi/pasar-desa/page.tsx
index bc3baf55..95de3555 100644
--- a/src/app/admin/(dashboard)/ekonomi/pasar-desa/page.tsx
+++ b/src/app/admin/(dashboard)/ekonomi/pasar-desa/page.tsx
@@ -1,10 +1,30 @@
+import colors from '@/con/colors';
+import { Box, Button, Group, Paper, Stack, Title } from '@mantine/core';
import React from 'react';
+import CreatePasarDesa from './create/createPasarDesa';
+import ListDataUsaha from './listData/page';
function Page() {
return (
-
- pasar-desa
-
+
+
+
+
+ Pasar Desa
+
+
+
+ Submit
+
+
+
+
+
+
+
);
}
diff --git a/src/app/admin/(dashboard)/ekonomi/program-kemiskinan/page.tsx b/src/app/admin/(dashboard)/ekonomi/program-kemiskinan/page.tsx
index 98679492..690a8999 100644
--- a/src/app/admin/(dashboard)/ekonomi/program-kemiskinan/page.tsx
+++ b/src/app/admin/(dashboard)/ekonomi/program-kemiskinan/page.tsx
@@ -1,10 +1,30 @@
-import React from 'react';
+import colors from '@/con/colors';
+import { Stack, Tabs, TabsList, TabsPanel, TabsTab, Title } from '@mantine/core';
+import ProgramKemiskinan from './ui/program/page';
+import StatistikKemiskinan from './ui/statistik/page';
function Page() {
return (
-
- program-kemiskinan
-
+
+ Program Kemiskinan
+
+
+
+ Program Kemiskinan
+
+
+ Statistik Kemiskinan
+
+
+
+
+
+
+
+
+
+
+
);
}
diff --git a/src/app/admin/(dashboard)/ekonomi/program-kemiskinan/ui/program/page.tsx b/src/app/admin/(dashboard)/ekonomi/program-kemiskinan/ui/program/page.tsx
new file mode 100644
index 00000000..78a78521
--- /dev/null
+++ b/src/app/admin/(dashboard)/ekonomi/program-kemiskinan/ui/program/page.tsx
@@ -0,0 +1,43 @@
+import colors from '@/con/colors';
+import { Box, Button, Group, Paper, SimpleGrid, Stack, Text, TextInput, Title } from '@mantine/core';
+import React from 'react';
+
+function ProgramKemiskinan() {
+ return (
+
+
+
+
+
+ Program Kemiskinan
+ Nama Program}
+ placeholder="Masukkan nama program"
+ />
+ Deskripsi Program}
+ placeholder="Masukkan deskripsi program"
+ />
+
+
+ Submit
+
+
+
+
+
+
+
+
+ List Data Program Kemiskinan
+
+
+
+
+
+ );
+}
+
+export default ProgramKemiskinan;
diff --git a/src/app/admin/(dashboard)/ekonomi/program-kemiskinan/ui/statistik/page.tsx b/src/app/admin/(dashboard)/ekonomi/program-kemiskinan/ui/statistik/page.tsx
new file mode 100644
index 00000000..0786257c
--- /dev/null
+++ b/src/app/admin/(dashboard)/ekonomi/program-kemiskinan/ui/statistik/page.tsx
@@ -0,0 +1,43 @@
+import colors from '@/con/colors';
+import { Box, Button, Group, Paper, Stack, Text, TextInput, Title } from '@mantine/core';
+import React from 'react';
+
+function StatistikKemiskinan() {
+ return (
+
+
+
+
+
+ Statistik Kemiskinan
+ Tahun}
+ placeholder="Masukkan tahun"
+ />
+ Jumlah Penduduk Miskin}
+ placeholder="Masukkan jumlah penduduk miskin"
+ />
+
+
+ Submit
+
+
+
+
+
+
+
+
+ Statistik Kemiskinan
+
+
+
+
+
+ );
+}
+
+export default StatistikKemiskinan;
diff --git a/src/app/admin/(dashboard)/ekonomi/sektor-unggulan-desa/page.tsx b/src/app/admin/(dashboard)/ekonomi/sektor-unggulan-desa/page.tsx
index e4701ee1..f308290e 100644
--- a/src/app/admin/(dashboard)/ekonomi/sektor-unggulan-desa/page.tsx
+++ b/src/app/admin/(dashboard)/ekonomi/sektor-unggulan-desa/page.tsx
@@ -1,10 +1,31 @@
+import colors from '@/con/colors';
+import { Stack, Tabs, TabsList, TabsPanel, TabsTab, Title } from '@mantine/core';
import React from 'react';
+import DataSektorUnggulan from './ui/data_sektor_unggulan/page';
+import GrafikDataSektor from './ui/grafik_data_sektor/page';
function Page() {
return (
-
- sektor-unggulan-desa
-
+
+ Sektor Unggulan Desa
+
+
+
+ Data Sektor Unggulan Desa
+
+
+ Grafik Data Sektor Unggulan Desa
+
+
+
+
+
+
+
+
+
+
+
);
}
diff --git a/src/app/admin/(dashboard)/ekonomi/sektor-unggulan-desa/ui/data_sektor_unggulan/page.tsx b/src/app/admin/(dashboard)/ekonomi/sektor-unggulan-desa/ui/data_sektor_unggulan/page.tsx
new file mode 100644
index 00000000..7281ed4f
--- /dev/null
+++ b/src/app/admin/(dashboard)/ekonomi/sektor-unggulan-desa/ui/data_sektor_unggulan/page.tsx
@@ -0,0 +1,45 @@
+import colors from '@/con/colors';
+import { Box, Button, Group, Paper, SimpleGrid, Stack, Text, TextInput, Title } from '@mantine/core';
+import React from 'react';
+
+function DataSektorUnggulan() {
+ return (
+
+
+
+
+
+
+ Data Sektor Unggulan
+ Nama Sektor Unggulan}
+ placeholder="Masukkan nama sektor unggulan"
+ />
+ Deskripsi Sektor Unggulan}
+ placeholder="Masukkan deskripsi sektor unggulan"
+ />
+
+
+ Submit
+
+
+
+
+
+
+
+
+ Data Sektor Unggulan
+
+
+
+
+
+
+ );
+}
+
+export default DataSektorUnggulan;
diff --git a/src/app/admin/(dashboard)/ekonomi/sektor-unggulan-desa/ui/grafik_data_sektor/page.tsx b/src/app/admin/(dashboard)/ekonomi/sektor-unggulan-desa/ui/grafik_data_sektor/page.tsx
new file mode 100644
index 00000000..5c9985e2
--- /dev/null
+++ b/src/app/admin/(dashboard)/ekonomi/sektor-unggulan-desa/ui/grafik_data_sektor/page.tsx
@@ -0,0 +1,44 @@
+import colors from '@/con/colors';
+import { Box, Button, Group, Paper, Stack, Text, TextInput, Title } from '@mantine/core';
+import React from 'react';
+
+function GrafikDataSektor() {
+ return (
+
+
+
+
+
+ Grafik Data Sektor Unggulan
+ Nama Sektor Unggulan}
+ placeholder="Masukkan nama sektor unggulan"
+ />
+ Jumlah Sektor Unggulan}
+ placeholder="Masukkan jumlah sektor unggulan"
+ />
+
+
+ Submit
+
+
+
+
+
+
+
+
+ Grafik Sektor Unggulan
+
+
+
+
+
+
+ );
+}
+
+export default GrafikDataSektor;
diff --git a/src/app/admin/(dashboard)/inovasi/desa-digital-smart-village/page.tsx b/src/app/admin/(dashboard)/inovasi/desa-digital-smart-village/page.tsx
index d6b4e9dc..348012b2 100644
--- a/src/app/admin/(dashboard)/inovasi/desa-digital-smart-village/page.tsx
+++ b/src/app/admin/(dashboard)/inovasi/desa-digital-smart-village/page.tsx
@@ -1,10 +1,49 @@
+import colors from '@/con/colors';
+import { Box, Button, Group, Paper, Stack, Text, TextInput, Title } from '@mantine/core';
+import { IconImageInPicture } from '@tabler/icons-react';
import React from 'react';
function Page() {
return (
-
- desa-digital-smart-village
-
+
+
+
+
+
+ Create Data Desa Digital Smart Village
+ Nama Desa Digital Smart Village}
+ placeholder="Masukkan nama desa digital smart village"
+ />
+ Deskripsi Desa Digital Smart Village}
+ placeholder="Masukkan deskripsi desa digital smart village"
+ />
+
+
+ Upload Gambar Desa Digital Smart Village
+
+
+
+
+
+ Submit
+
+
+
+
+
+
+
+
+ Create Data Desa Digital Smart Village
+
+
+
+
+
);
}
diff --git a/src/app/admin/(dashboard)/keamanan/_com/keamananEditor.tsx b/src/app/admin/(dashboard)/keamanan/_com/keamananEditor.tsx
new file mode 100644
index 00000000..437e3242
--- /dev/null
+++ b/src/app/admin/(dashboard)/keamanan/_com/keamananEditor.tsx
@@ -0,0 +1,93 @@
+'use client'
+import colors from '@/con/colors';
+import { Button, Stack } from '@mantine/core';
+import { Link, RichTextEditor } from '@mantine/tiptap';
+import Highlight from '@tiptap/extension-highlight';
+import SubScript from '@tiptap/extension-subscript';
+import Superscript from '@tiptap/extension-superscript';
+import TextAlign from '@tiptap/extension-text-align';
+import Underline from '@tiptap/extension-underline';
+import { useEditor } from '@tiptap/react';
+import StarterKit from '@tiptap/starter-kit';
+
+const content =
+ 'Welcome to Mantine rich text editor RichTextEditor component focuses on usability and is designed to be as simple as possible to bring a familiar editing experience to regular users. RichTextEditor is based on Tiptap.dev and supports all of its features:
General text formatting: bold , italic , underline , strike-through Headings (h1-h6) Sub and super scripts (<sup /> and <sub /> tags) Ordered and bullet lists Text align And all other extensions ';
+
+export function KeamananEditor({showSubmit = true} : {
+ showSubmit: boolean
+}) {
+ const editor = useEditor({
+ extensions: [
+ StarterKit,
+ Underline,
+ Link,
+ Superscript,
+ SubScript,
+ Highlight,
+ TextAlign.configure({ types: ['heading', 'paragraph'] }),
+ ],
+ immediatelyRender: false,
+ content,
+ });
+
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {showSubmit && (
+
+ Submit
+
+ )}
+
+ );
+}
\ No newline at end of file
diff --git a/src/app/admin/(dashboard)/keamanan/_com/keamananEdtorText.tsx b/src/app/admin/(dashboard)/keamanan/_com/keamananEdtorText.tsx
new file mode 100644
index 00000000..77864dc7
--- /dev/null
+++ b/src/app/admin/(dashboard)/keamanan/_com/keamananEdtorText.tsx
@@ -0,0 +1,95 @@
+'use client'
+import { Button, Stack } from '@mantine/core';
+import { Link, RichTextEditor } from '@mantine/tiptap';
+import Highlight from '@tiptap/extension-highlight';
+import SubScript from '@tiptap/extension-subscript';
+import Superscript from '@tiptap/extension-superscript';
+import TextAlign from '@tiptap/extension-text-align';
+import Underline from '@tiptap/extension-underline';
+import { useEditor } from '@tiptap/react';
+import StarterKit from '@tiptap/starter-kit';
+
+
+function KeamananEditorText({ onSubmit, onChange, showSubmit = true, initialContent = '', }: {
+ onSubmit?: (val: string) => void,
+ onChange: (val: string) => void,
+ showSubmit?: boolean,
+ initialContent?: string }) {
+ const editor = useEditor({
+ extensions: [
+ StarterKit,
+ Underline,
+ Link,
+ Superscript,
+ SubScript,
+ Highlight,
+ TextAlign.configure({ types: ['heading', 'paragraph'] }),
+ ],
+ immediatelyRender: false,
+ content: initialContent,
+ onUpdate : ({editor}) => {
+ onChange(editor.getHTML())
+ }
+ });
+
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {showSubmit && (
+ {
+ if (!editor) return
+ onSubmit?.(editor?.getHTML())
+ }}>Submit
+ )}
+
+ );
+}
+
+export default KeamananEditorText;
diff --git a/src/app/admin/(dashboard)/keamanan/keamanan-lingkungan-pecalang-patwal/page.tsx b/src/app/admin/(dashboard)/keamanan/keamanan-lingkungan-pecalang-patwal/page.tsx
index 774863d5..7b7edc9f 100644
--- a/src/app/admin/(dashboard)/keamanan/keamanan-lingkungan-pecalang-patwal/page.tsx
+++ b/src/app/admin/(dashboard)/keamanan/keamanan-lingkungan-pecalang-patwal/page.tsx
@@ -1,10 +1,35 @@
+import colors from '@/con/colors';
+import { Box, Stack, Tabs, TabsList, TabsPanel, TabsTab, Title } from '@mantine/core';
import React from 'react';
+import CreateKeamananLingkungan from './ui/tambah_keamanan_lingkungan/page';
+import ListKeamananLingkungan from './ui/list_keamanan_lingkungan/page';
+
function Page() {
return (
-
- keamanan-lingkungan-pecalang-patwal
-
+
+
+ Keamanan Lingkungan
+
+
+
+ Tambah Keamanan Lingkungan
+
+
+ List Keamanan Lingkungan
+
+
+
+
+
+
+
+
+
+
+
+
+
);
}
diff --git a/src/app/admin/(dashboard)/keamanan/keamanan-lingkungan-pecalang-patwal/ui/list_keamanan_lingkungan/page.tsx b/src/app/admin/(dashboard)/keamanan/keamanan-lingkungan-pecalang-patwal/ui/list_keamanan_lingkungan/page.tsx
new file mode 100644
index 00000000..df888243
--- /dev/null
+++ b/src/app/admin/(dashboard)/keamanan/keamanan-lingkungan-pecalang-patwal/ui/list_keamanan_lingkungan/page.tsx
@@ -0,0 +1,33 @@
+import { Box, Paper, Stack, Table, TableTbody, TableTh, TableThead, TableTr, Title } from '@mantine/core';
+import colors from '@/con/colors';
+import React from 'react';
+
+function ListKeamananLingkungan() {
+ return (
+
+
+
+ List Keamanan Lingkungan
+
+
+
+
+ Image
+ Nama Keamanan Lingkungan
+ Deskripsi Keamanan Lingkungan
+ Aksi
+ Detail
+
+
+
+
+
+
+
+
+
+
+ );
+}
+
+export default ListKeamananLingkungan;
diff --git a/src/app/admin/(dashboard)/keamanan/keamanan-lingkungan-pecalang-patwal/ui/tambah_keamanan_lingkungan/page.tsx b/src/app/admin/(dashboard)/keamanan/keamanan-lingkungan-pecalang-patwal/ui/tambah_keamanan_lingkungan/page.tsx
new file mode 100644
index 00000000..1d556e92
--- /dev/null
+++ b/src/app/admin/(dashboard)/keamanan/keamanan-lingkungan-pecalang-patwal/ui/tambah_keamanan_lingkungan/page.tsx
@@ -0,0 +1,46 @@
+import colors from '@/con/colors';
+import { Box, Button, Group, Paper, SimpleGrid, Stack, Text, TextInput, Title } from '@mantine/core';
+import { IconImageInPicture } from '@tabler/icons-react';
+import React from 'react';
+import { KeamananEditor } from '../../../_com/keamananEditor';
+
+
+function KeamananLingkungan() {
+ return (
+
+
+
+
+
+
+ Tambah Keamanan Lingkungan
+
+ Masukkan Image
+
+
+ Nama Keamanan Lingkungan}
+ placeholder='Masukkan nama keamanan lingkungan'
+ />
+
+ Deskripsi Keamanan Lingkungan
+
+
+
+ Submit
+
+
+
+
+
+
+
+
+
+
+ );
+}
+
+export default KeamananLingkungan;
diff --git a/src/app/admin/(dashboard)/keamanan/kontak-darurat/create/createKontak.tsx b/src/app/admin/(dashboard)/keamanan/kontak-darurat/create/createKontak.tsx
new file mode 100644
index 00000000..98ebd6ab
--- /dev/null
+++ b/src/app/admin/(dashboard)/keamanan/kontak-darurat/create/createKontak.tsx
@@ -0,0 +1,28 @@
+import colors from '@/con/colors';
+import { Box, Stack, Text, TextInput } from '@mantine/core';
+import { IconImageInPicture } from '@tabler/icons-react';
+
+function CreateKontakDarurat() {
+ return (
+
+
+ Judul Kontak Darurat}
+ placeholder="masukkan judul kontak darurat"
+ />
+
+ Nama Kontak Darurat}
+ placeholder="masukkan nama kontak darurat"
+ />
+
+ Nomor Kontak Darurat}
+ placeholder="masukkan nomor kontak darurat"
+ />
+
+
+ );
+}
+
+export default CreateKontakDarurat;
diff --git a/src/app/admin/(dashboard)/keamanan/kontak-darurat/listData/page.tsx b/src/app/admin/(dashboard)/keamanan/kontak-darurat/listData/page.tsx
new file mode 100644
index 00000000..6de1176b
--- /dev/null
+++ b/src/app/admin/(dashboard)/keamanan/kontak-darurat/listData/page.tsx
@@ -0,0 +1,23 @@
+import colors from '@/con/colors';
+import { Box, Paper, Stack, Text, Title } from '@mantine/core';
+import React from 'react';
+
+function ListDataKontakDarurat() {
+ return (
+
+
+ List Data Kontak Darurat
+
+ Judul Kontak Darurat
+
+ Nama Kontak Darurat
+
+ Nomor Kontak Darurat
+
+
+
+
+ );
+}
+
+export default ListDataKontakDarurat;
diff --git a/src/app/admin/(dashboard)/keamanan/kontak-darurat/page.tsx b/src/app/admin/(dashboard)/keamanan/kontak-darurat/page.tsx
index 9619b475..10f224ff 100644
--- a/src/app/admin/(dashboard)/keamanan/kontak-darurat/page.tsx
+++ b/src/app/admin/(dashboard)/keamanan/kontak-darurat/page.tsx
@@ -1,10 +1,30 @@
+import colors from '@/con/colors';
+import { Box, Button, Group, Paper, SimpleGrid, Stack, Title } from '@mantine/core';
import React from 'react';
+import CreateKontakDarurat from './create/createKontak';
+import ListDataKontakDarurat from './listData/page';
function Page() {
return (
-
- kontak-darurat
-
+
+
+
+
+ Kontak Darurat
+
+
+
+ Submit
+
+
+
+
+
+
+
);
}
diff --git a/src/app/admin/(dashboard)/keamanan/laporan-publik/create/createLaporan.tsx b/src/app/admin/(dashboard)/keamanan/laporan-publik/create/createLaporan.tsx
new file mode 100644
index 00000000..72943bb3
--- /dev/null
+++ b/src/app/admin/(dashboard)/keamanan/laporan-publik/create/createLaporan.tsx
@@ -0,0 +1,27 @@
+import { Box, Stack, Text, TextInput } from '@mantine/core';
+import React from 'react';
+import { KeamananEditor } from '../../_com/keamananEditor';
+
+
+function CreateLaporanPublik() {
+ return (
+
+
+ Judul Laporan Publik}
+ placeholder="masukkan judul laporan publik"
+ />
+ Tanggal Laporan Publik}
+ placeholder="masukkan tanggal laporan publik"
+ />
+
+ Deskripsi Laporan Publik
+
+
+
+
+ );
+}
+
+export default CreateLaporanPublik;
diff --git a/src/app/admin/(dashboard)/keamanan/laporan-publik/listData/page.tsx b/src/app/admin/(dashboard)/keamanan/laporan-publik/listData/page.tsx
new file mode 100644
index 00000000..7acdb40b
--- /dev/null
+++ b/src/app/admin/(dashboard)/keamanan/laporan-publik/listData/page.tsx
@@ -0,0 +1,23 @@
+import React from 'react';
+import { Box, Paper, Stack, Text, Title } from '@mantine/core';
+import colors from '@/con/colors';
+
+function ListDataLaporanPublik() {
+ return (
+
+
+ List Data Laporan Publik
+
+ Judul Laporan Publik
+
+ Tanggal Laporan Publik
+
+ Deskripsi Laporan Publik
+
+
+
+
+ );
+}
+
+export default ListDataLaporanPublik;
diff --git a/src/app/admin/(dashboard)/keamanan/laporan-publik/page.tsx b/src/app/admin/(dashboard)/keamanan/laporan-publik/page.tsx
index 3905ba8c..0dcd6de5 100644
--- a/src/app/admin/(dashboard)/keamanan/laporan-publik/page.tsx
+++ b/src/app/admin/(dashboard)/keamanan/laporan-publik/page.tsx
@@ -1,11 +1,28 @@
-import React from 'react';
+import colors from "@/con/colors";
+import { Box, Button, Group, Paper, SimpleGrid, Stack, Title } from "@mantine/core";
+import CreateLaporanPublik from "./create/createLaporan";
+import ListDataLaporanPublik from "./listData/page";
-function Page() {
+export default function Page() {
return (
-
- laporan-publik
-
- );
-}
-
-export default Page;
+
+
+
+
+ Laporan Publik
+
+
+
+ Submit
+
+
+
+
+
+
+
+ )
+}
\ No newline at end of file
diff --git a/src/app/admin/(dashboard)/keamanan/pencegahan-kriminalitas/create/createPencegahan.tsx b/src/app/admin/(dashboard)/keamanan/pencegahan-kriminalitas/create/createPencegahan.tsx
new file mode 100644
index 00000000..3a7cf61b
--- /dev/null
+++ b/src/app/admin/(dashboard)/keamanan/pencegahan-kriminalitas/create/createPencegahan.tsx
@@ -0,0 +1,25 @@
+import colors from '@/con/colors';
+import { Box, Stack, Text, TextInput } from '@mantine/core';
+import { IconImageInPicture } from '@tabler/icons-react';
+import React from 'react';
+
+function CreatePencegahan() {
+ return (
+
+
+ Judul Pencegahan Kriminalitas}
+ placeholder="masukkan judul pencegahan kriminalitas"
+ />
+ Deskripsi Pencegahan Kriminalitas}
+ placeholder="masukkan deskripsi pencegahan kriminalitas"
+ />
+ Gambar Pencegahan Kriminalitas
+
+
+
+ );
+}
+
+export default CreatePencegahan;
diff --git a/src/app/admin/(dashboard)/keamanan/pencegahan-kriminalitas/listData/page.tsx b/src/app/admin/(dashboard)/keamanan/pencegahan-kriminalitas/listData/page.tsx
new file mode 100644
index 00000000..4153abe6
--- /dev/null
+++ b/src/app/admin/(dashboard)/keamanan/pencegahan-kriminalitas/listData/page.tsx
@@ -0,0 +1,23 @@
+import colors from '@/con/colors';
+import { Box, Paper, Stack, Text, Title } from '@mantine/core';
+import React from 'react';
+
+function ListDataPencegahan() {
+ return (
+
+
+ List Data Pencegahan Kriminalitas
+
+ Judul Pencegahan Kriminalitas
+
+ Deskripsi Pencegahan Kriminalitas
+
+ Gambar Pencegahan Kriminalitas
+
+
+
+
+ );
+}
+
+export default ListDataPencegahan;
diff --git a/src/app/admin/(dashboard)/keamanan/pencegahan-kriminalitas/page.tsx b/src/app/admin/(dashboard)/keamanan/pencegahan-kriminalitas/page.tsx
index 96ff4b2a..be34aed5 100644
--- a/src/app/admin/(dashboard)/keamanan/pencegahan-kriminalitas/page.tsx
+++ b/src/app/admin/(dashboard)/keamanan/pencegahan-kriminalitas/page.tsx
@@ -1,10 +1,31 @@
+import colors from '@/con/colors';
+import { Stack, SimpleGrid, Box, Paper, Title, Group, Button } from '@mantine/core';
import React from 'react';
+import CreatePencegahan from './create/createPencegahan';
+import ListDataPencegahan from './listData/page';
+
function Page() {
return (
-
- pencegahan-kriminalitas
-
+
+
+
+
+ Kontak Darurat
+
+
+
+ Submit
+
+
+
+
+
+
+
);
}
diff --git a/src/app/admin/(dashboard)/keamanan/polsek-terdekat/page.tsx b/src/app/admin/(dashboard)/keamanan/polsek-terdekat/page.tsx
index 642db134..92031007 100644
--- a/src/app/admin/(dashboard)/keamanan/polsek-terdekat/page.tsx
+++ b/src/app/admin/(dashboard)/keamanan/polsek-terdekat/page.tsx
@@ -1,10 +1,35 @@
+import colors from '@/con/colors';
+import { Box, Stack, Tabs, TabsList, TabsPanel, TabsTab, Title } from '@mantine/core';
import React from 'react';
+import CreatePolsekTerdekat from './ui/tambah_polsek_terdekat/page';
+import ListPolsekTerdekat from './ui/list_polsek_terdekat/page';
+
function Page() {
return (
-
- polsek-terdekat
-
+
+
+ Polsek Terdekat
+
+
+
+ Tambah Polsek Terdekat
+
+
+ List Polsek Terdekat
+
+
+
+
+
+
+
+
+
+
+
+
+
);
}
diff --git a/src/app/admin/(dashboard)/keamanan/polsek-terdekat/ui/list_polsek_terdekat/page.tsx b/src/app/admin/(dashboard)/keamanan/polsek-terdekat/ui/list_polsek_terdekat/page.tsx
new file mode 100644
index 00000000..7c119c36
--- /dev/null
+++ b/src/app/admin/(dashboard)/keamanan/polsek-terdekat/ui/list_polsek_terdekat/page.tsx
@@ -0,0 +1,36 @@
+import { Box, Paper, Stack, Table, TableTbody, TableTh, TableThead, TableTr, Title } from '@mantine/core';
+import colors from '@/con/colors';
+import React from 'react';
+
+function ListPolsekTerdekat() {
+ return (
+
+
+
+ List Polsek Terdekat
+
+
+
+
+ Nama Polsek Terdekat
+ Jarak Polsek Terdekat
+ Alamat Polsek Terdekat
+ Nomor Telepon Polsek Terdekat
+ Jam Aktif
+ Deskripsi Polsek Terdekat
+ Aksi
+ Detail
+
+
+
+
+
+
+
+
+
+
+ );
+}
+
+export default ListPolsekTerdekat;
diff --git a/src/app/admin/(dashboard)/keamanan/polsek-terdekat/ui/tambah_polsek_terdekat/page.tsx b/src/app/admin/(dashboard)/keamanan/polsek-terdekat/ui/tambah_polsek_terdekat/page.tsx
new file mode 100644
index 00000000..ba2a4c32
--- /dev/null
+++ b/src/app/admin/(dashboard)/keamanan/polsek-terdekat/ui/tambah_polsek_terdekat/page.tsx
@@ -0,0 +1,56 @@
+import colors from '@/con/colors';
+import { Box, Button, Group, Paper, SimpleGrid, Stack, Text, TextInput, Title } from '@mantine/core';
+import { KeamananEditor } from '../../../_com/keamananEditor';
+
+
+function CreatePolsekTerdekat() {
+ return (
+
+
+
+
+
+
+ Tambah Polsek Terdekat
+ Nama Polsek Terdekat}
+ placeholder='Masukkan nama polsek terdekat'
+ />
+ Jarak Polsek Terdekat}
+ placeholder='Masukkan jarak polsek terdekat'
+ />
+ Alamat Polsek Terdekat}
+ placeholder='Masukkan alamat polsek terdekat'
+ />
+ Nomor Telepon Polsek Terdekat}
+ placeholder='Masukkan nomor telepon polsek terdekat'
+ />
+ Jam Aktif}
+ placeholder='Masukkan jam aktif polsek terdekat'
+ />
+
+ Deskripsi Polsek Terdekat
+
+
+
+ Submit
+
+
+
+
+
+
+
+
+
+
+ );
+}
+
+export default CreatePolsekTerdekat;
diff --git a/src/app/admin/(dashboard)/keamanan/tips-keamanan/create/createTips.tsx b/src/app/admin/(dashboard)/keamanan/tips-keamanan/create/createTips.tsx
new file mode 100644
index 00000000..4fb1ada6
--- /dev/null
+++ b/src/app/admin/(dashboard)/keamanan/tips-keamanan/create/createTips.tsx
@@ -0,0 +1,27 @@
+import colors from '@/con/colors';
+import { Box, Stack, Text, TextInput } from '@mantine/core';
+import { IconImageInPicture } from '@tabler/icons-react';
+import React from 'react';
+import { KeamananEditor } from '../../_com/keamananEditor';
+
+function CreateTipsKeamanan() {
+ return (
+
+
+ Judul Tips Keamanan}
+ placeholder="masukkan judul tips keamanan"
+ />
+
+ Upload Gambar
+
+
+
+
+
+ );
+}
+
+export default CreateTipsKeamanan;
diff --git a/src/app/admin/(dashboard)/keamanan/tips-keamanan/listData/page.tsx b/src/app/admin/(dashboard)/keamanan/tips-keamanan/listData/page.tsx
new file mode 100644
index 00000000..4bead65a
--- /dev/null
+++ b/src/app/admin/(dashboard)/keamanan/tips-keamanan/listData/page.tsx
@@ -0,0 +1,24 @@
+import colors from '@/con/colors';
+import { Box, Paper, Stack, Text, Title } from '@mantine/core';
+import { IconImageInPicture } from '@tabler/icons-react';
+import React from 'react';
+
+function ListDataTipsKeamanan() {
+ return (
+
+
+ List Data Tips Keamanan
+
+ Judul Tips Keamanan
+
+ Gambar Tips Keamanan
+
+ Deskripsi Tips Keamanan
+
+
+
+
+ );
+}
+
+export default ListDataTipsKeamanan;
diff --git a/src/app/admin/(dashboard)/keamanan/tips-keamanan/page.tsx b/src/app/admin/(dashboard)/keamanan/tips-keamanan/page.tsx
index 17bea858..e1b672b8 100644
--- a/src/app/admin/(dashboard)/keamanan/tips-keamanan/page.tsx
+++ b/src/app/admin/(dashboard)/keamanan/tips-keamanan/page.tsx
@@ -1,11 +1,31 @@
+import colors from '@/con/colors';
+import { Box, Button, Group, Paper, SimpleGrid, Stack, Title } from '@mantine/core';
import React from 'react';
+import CreateTipsKeamanan from './create/createTips';
+import ListDataTipsKeamanan from './listData/page';
function Page() {
return (
-
- tips-keamanan
-
- );
+
+
+
+
+ Tips Keamanan
+
+
+
+ Submit
+
+
+
+
+
+
+
+ )
}
export default Page;
diff --git a/src/app/admin/(dashboard)/kesehatan/_com/kesehatanEditor.tsx b/src/app/admin/(dashboard)/kesehatan/_com/kesehatanEditor.tsx
new file mode 100644
index 00000000..a4989a83
--- /dev/null
+++ b/src/app/admin/(dashboard)/kesehatan/_com/kesehatanEditor.tsx
@@ -0,0 +1,93 @@
+'use client'
+import colors from '@/con/colors';
+import { Button, Stack } from '@mantine/core';
+import { Link, RichTextEditor } from '@mantine/tiptap';
+import Highlight from '@tiptap/extension-highlight';
+import SubScript from '@tiptap/extension-subscript';
+import Superscript from '@tiptap/extension-superscript';
+import TextAlign from '@tiptap/extension-text-align';
+import Underline from '@tiptap/extension-underline';
+import { useEditor } from '@tiptap/react';
+import StarterKit from '@tiptap/starter-kit';
+
+const content =
+ 'Welcome to Mantine rich text editor RichTextEditor component focuses on usability and is designed to be as simple as possible to bring a familiar editing experience to regular users. RichTextEditor is based on Tiptap.dev and supports all of its features:
General text formatting: bold , italic , underline , strike-through Headings (h1-h6) Sub and super scripts (<sup /> and <sub /> tags) Ordered and bullet lists Text align And all other extensions ';
+
+export function KesehatanEditor({showSubmit = true} : {
+ showSubmit: boolean
+}) {
+ const editor = useEditor({
+ extensions: [
+ StarterKit,
+ Underline,
+ Link,
+ Superscript,
+ SubScript,
+ Highlight,
+ TextAlign.configure({ types: ['heading', 'paragraph'] }),
+ ],
+ immediatelyRender: false,
+ content,
+ });
+
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {showSubmit && (
+
+ Submit
+
+ )}
+
+ );
+}
\ No newline at end of file
diff --git a/src/app/admin/(dashboard)/kesehatan/_com/kesehatanEditorText.tsx b/src/app/admin/(dashboard)/kesehatan/_com/kesehatanEditorText.tsx
new file mode 100644
index 00000000..c044bf51
--- /dev/null
+++ b/src/app/admin/(dashboard)/kesehatan/_com/kesehatanEditorText.tsx
@@ -0,0 +1,95 @@
+'use client'
+import { Button, Stack } from '@mantine/core';
+import { Link, RichTextEditor } from '@mantine/tiptap';
+import Highlight from '@tiptap/extension-highlight';
+import SubScript from '@tiptap/extension-subscript';
+import Superscript from '@tiptap/extension-superscript';
+import TextAlign from '@tiptap/extension-text-align';
+import Underline from '@tiptap/extension-underline';
+import { useEditor } from '@tiptap/react';
+import StarterKit from '@tiptap/starter-kit';
+
+
+function KesehatanEditorText({ onSubmit, onChange, showSubmit = true, initialContent = '', }: {
+ onSubmit?: (val: string) => void,
+ onChange: (val: string) => void,
+ showSubmit?: boolean,
+ initialContent?: string }) {
+ const editor = useEditor({
+ extensions: [
+ StarterKit,
+ Underline,
+ Link,
+ Superscript,
+ SubScript,
+ Highlight,
+ TextAlign.configure({ types: ['heading', 'paragraph'] }),
+ ],
+ immediatelyRender: false,
+ content: initialContent,
+ onUpdate : ({editor}) => {
+ onChange(editor.getHTML())
+ }
+ });
+
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {showSubmit && (
+ {
+ if (!editor) return
+ onSubmit?.(editor?.getHTML())
+ }}>Submit
+ )}
+
+ );
+}
+
+export default KesehatanEditorText;
diff --git a/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/_ui/artikel_kesehatan/doctor_sign/page.tsx b/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/_ui/artikel_kesehatan/doctor_sign/page.tsx
new file mode 100644
index 00000000..7975625c
--- /dev/null
+++ b/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/_ui/artikel_kesehatan/doctor_sign/page.tsx
@@ -0,0 +1,26 @@
+'use client'
+import { Box, Paper, Text } from '@mantine/core';
+import React from 'react';
+import { KesehatanEditor } from '../../../_com/kesehatanEditor';
+import { useProxy } from 'valtio/utils';
+import stateArtikelKesehatan from '@/app/admin/(dashboard)/_state/kesehatan/data_kesehatan_warga/artikelKesehatan';
+import colors from '@/con/colors';
+
+function DoctorSignUI() {
+ const doctorSign = useProxy(stateArtikelKesehatan.doctorSign)
+ return (
+
+
+ Kapan Harus ke Dokter
+ {
+ doctorSign.create.form.content = val
+ }}
+ />
+
+
+ );
+}
+
+export default DoctorSignUI;
diff --git a/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/_ui/artikel_kesehatan/first_aid/page.tsx b/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/_ui/artikel_kesehatan/first_aid/page.tsx
new file mode 100644
index 00000000..61021b8c
--- /dev/null
+++ b/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/_ui/artikel_kesehatan/first_aid/page.tsx
@@ -0,0 +1,34 @@
+'use client'
+import { Box, Paper, Stack, Text, TextInput } from '@mantine/core';
+import React from 'react';
+import { useProxy } from 'valtio/utils';
+import stateArtikelKesehatan from '@/app/admin/(dashboard)/_state/kesehatan/data_kesehatan_warga/artikelKesehatan';
+import { KesehatanEditor } from '../../../_com/kesehatanEditor';
+import colors from '@/con/colors';
+
+function FirstAidUI() {
+ const firstAidState = useProxy(stateArtikelKesehatan.firstAid)
+ return (
+
+
+
+ Judul Pertolongan Pertama}
+ placeholder="Masukkan judul"
+ onChange={(val) => {
+ firstAidState.create.form.title = val.target.value
+ }}
+ />
+ {
+ firstAidState.create.form.content = val
+ }}
+ />
+
+
+
+ );
+}
+
+export default FirstAidUI;
diff --git a/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/_ui/artikel_kesehatan/introduction/page.tsx b/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/_ui/artikel_kesehatan/introduction/page.tsx
new file mode 100644
index 00000000..7dce6b06
--- /dev/null
+++ b/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/_ui/artikel_kesehatan/introduction/page.tsx
@@ -0,0 +1,28 @@
+'use client'
+import { Box, Paper, Stack, Text } from '@mantine/core';
+import React from 'react';
+import { useProxy } from 'valtio/utils';
+import { KesehatanEditor } from '../../../_com/kesehatanEditor';
+import stateArtikelKesehatan from '@/app/admin/(dashboard)/_state/kesehatan/data_kesehatan_warga/artikelKesehatan';
+import colors from '@/con/colors';
+
+function IntoductionUI() {
+ const introduction = useProxy(stateArtikelKesehatan.introduction)
+ return (
+
+
+
+ Pendahuluan
+ {
+ introduction.create.form.content = val;
+ }}
+ />
+
+
+
+ );
+}
+
+export default IntoductionUI;
diff --git a/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/_ui/artikel_kesehatan/mythVsfact/page.tsx b/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/_ui/artikel_kesehatan/mythVsfact/page.tsx
new file mode 100644
index 00000000..6a22d179
--- /dev/null
+++ b/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/_ui/artikel_kesehatan/mythVsfact/page.tsx
@@ -0,0 +1,40 @@
+'use client'
+import stateArtikelKesehatan from '@/app/admin/(dashboard)/_state/kesehatan/data_kesehatan_warga/artikelKesehatan';
+import colors from '@/con/colors';
+import { Box, Paper, Stack, Text, TextInput } from '@mantine/core';
+import { useProxy } from 'valtio/utils';
+
+function MythFactUI() {
+ const mythFact = useProxy(stateArtikelKesehatan.mythFact)
+ return (
+
+
+
+ Judul Pertolongan Pertama Penyakit}
+ placeholder="Masukkan judul"
+ onChange={(val) => {
+ mythFact.create.form.title = val.target.value
+ }}
+ />
+ Mitos}
+ placeholder="Masukkan mitos"
+ onChange={(val) => {
+ mythFact.create.form.mitos = val.target.value
+ }}
+ />
+ Fakta}
+ placeholder="Masukkan fakta"
+ onChange={(val) => {
+ mythFact.create.form.fakta = val.target.value
+ }}
+ />
+
+
+
+ );
+}
+
+export default MythFactUI;
diff --git a/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/_ui/artikel_kesehatan/page.tsx b/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/_ui/artikel_kesehatan/page.tsx
index be352d46..4f944e96 100644
--- a/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/_ui/artikel_kesehatan/page.tsx
+++ b/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/_ui/artikel_kesehatan/page.tsx
@@ -1,26 +1,172 @@
-import { Box, SimpleGrid, Stack, TextInput, Title } from '@mantine/core';
-import React from 'react';
+'use client'
+import { Box, Button, Center, Group, Paper, SimpleGrid, Skeleton, Stack, Table, TableTbody, TableTd, TableTh, TableThead, TableTr, Text, Title } from '@mantine/core';
+import IntoductionUI from './introduction/page';
+import SymptomUI from './symptom/page';
+import PreventionUI from './prevention/page';
+import MythFactUI from './mythVsfact/page';
+import DoctorSignUI from './doctor_sign/page';
+import { useProxy } from 'valtio/utils';
+import stateArtikelKesehatan from '@/app/admin/(dashboard)/_state/kesehatan/data_kesehatan_warga/artikelKesehatan';
+import FirstAidUI from './first_aid/page';
+import { useShallowEffect } from '@mantine/hooks';
+import colors from '@/con/colors';
function ArtikelKesehatan() {
+ const state = useProxy(stateArtikelKesehatan)
+ const submitAllForms = () => {
+ if (state.introduction.create.form.content) {
+ state.introduction.create.create()
+ }
+ if (state.symptom.create.form.title && state.symptom.create.form.content) {
+ state.symptom.create.create()
+ }
+ if (state.prevention.create.form.title && state.prevention.create.form.content) {
+ state.prevention.create.create()
+ }
+ if (state.firstAid.create.form.title && state.firstAid.create.form.content) {
+ state.firstAid.create.create()
+ }
+ if (state.mythFact.create.form.title && state.mythFact.create.form.mitos && state.mythFact.create.form.fakta) {
+ state.mythFact.create.create()
+ }
+ if (state.doctorSign.create.form.content) {
+ state.doctorSign.create.create()
+ }
+ }
return (
-
- Artikel Kesehatan
-
+
+
+ Artikel Kesehatan
+
+
+
+
+
+
+
+ Submit
+
+
+
- List Artikel Kesehatan
+
+ Data Artikel Kesehatan
+
+
);
}
+function AllList() {
+ const listState = useProxy(stateArtikelKesehatan)
+ useShallowEffect(() => {
+ listState.introduction.findMany.load();
+ listState.symptom.findMany.load();
+ listState.prevention.findMany.load();
+ listState.firstAid.findMany.load();
+ listState.mythFact.findMany.load();
+ listState.doctorSign.findMany.load();
+ }, [])
+
+ if (!listState.introduction.findMany.data
+ || !listState.symptom.findMany.data
+ || !listState.prevention.findMany.data
+ || !listState.firstAid.findMany.data
+ || !listState.mythFact.findMany.data
+ || !listState.doctorSign.findMany.data
+ ) return
+ {Array.from({ length: 10 }).map((v, k) => )}
+
+ return
+ {/* Introduction */}
+
+ Pendahuluan
+ {listState.introduction.findMany.data?.map((item) => (
+
+
+
+ ))}
+
+ {/* Symptom */}
+
+ Gejala Penyakit
+ {listState.symptom.findMany.data?.map((item) => (
+
+ {item.title}
+
+
+ ))}
+
+ {/* Prevention */}
+
+ Pencegahan Penyakit
+ {listState.prevention.findMany.data?.map((item) => (
+
+ {item.title}
+
+
+ ))}
+
+ {/* First Aid */}
+
+ Pertolongan Pertama
+ {listState.firstAid.findMany.data?.map((item) => (
+
+ {item.title}
+
+
+ ))}
+
+ {/* Myth Fact */}
+
+ Mitos vs Fakta
+ {listState.mythFact.findMany.data?.map((item) => (
+
+ {item.title}
+
+
+
+
+ Mitos
+
+
+ Fakta
+
+
+
+
+
+ {item.mitos}
+ {item.fakta}
+
+
+
+
+ ))}
+
+ {/* Doctor Sign */}
+
+ Kapan Harus Ke Dokter?
+ {listState.doctorSign.findMany.data?.map((item) => (
+
+
+
+ ))}
+
+
+}
export default ArtikelKesehatan;
diff --git a/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/_ui/artikel_kesehatan/prevention/page.tsx b/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/_ui/artikel_kesehatan/prevention/page.tsx
new file mode 100644
index 00000000..4752cb9b
--- /dev/null
+++ b/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/_ui/artikel_kesehatan/prevention/page.tsx
@@ -0,0 +1,35 @@
+'use client'
+import stateArtikelKesehatan from '@/app/admin/(dashboard)/_state/kesehatan/data_kesehatan_warga/artikelKesehatan';
+import { Box, Paper, Stack, Text, TextInput } from '@mantine/core';
+import React from 'react';
+import { useProxy } from 'valtio/utils';
+import { KesehatanEditor } from '../../../_com/kesehatanEditor';
+import colors from '@/con/colors';
+
+function PreventionUI() {
+ const preventionState = useProxy(stateArtikelKesehatan.prevention)
+ return (
+
+
+
+ Judul Pencegahan Penyakit}
+ placeholder="Masukkan judul"
+ onChange={(val) => {
+ preventionState.create.form.title = val.target.value
+ }}
+ />
+ {
+ preventionState.create.form.content = val
+ }}
+ />
+
+
+
+ );
+}
+
+export default PreventionUI;
diff --git a/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/_ui/artikel_kesehatan/symptom/page.tsx b/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/_ui/artikel_kesehatan/symptom/page.tsx
new file mode 100644
index 00000000..195775f8
--- /dev/null
+++ b/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/_ui/artikel_kesehatan/symptom/page.tsx
@@ -0,0 +1,34 @@
+'use client'
+import stateArtikelKesehatan from '@/app/admin/(dashboard)/_state/kesehatan/data_kesehatan_warga/artikelKesehatan';
+import { Box, Paper, Stack, Text, TextInput } from '@mantine/core';
+import { useProxy } from 'valtio/utils';
+import { KesehatanEditor } from '../../../_com/kesehatanEditor';
+import colors from '@/con/colors';
+
+function SymptomUI() {
+ const symptomState = useProxy(stateArtikelKesehatan.symptom)
+ return (
+
+
+
+ Judul Gejala Penyakit}
+ placeholder='masukkan judul'
+ onChange={(val) => {
+ symptomState.create.form.title = val.target.value
+ }}
+ />
+ {
+ symptomState.create.form.content = val
+ }}
+ />
+
+
+
+ );
+}
+
+export default SymptomUI;
diff --git a/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/_ui/fasilitas_kesehatan/dokterdantenagamedis/page.tsx b/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/_ui/fasilitas_kesehatan/dokterdantenagamedis/page.tsx
index 1c4b9c9e..4e888c40 100644
--- a/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/_ui/fasilitas_kesehatan/dokterdantenagamedis/page.tsx
+++ b/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/_ui/fasilitas_kesehatan/dokterdantenagamedis/page.tsx
@@ -1,12 +1,15 @@
import stateFasilitasKesehatan from '@/app/admin/(dashboard)/_state/kesehatan/data_kesehatan_warga/fasilitasKesehatan';
-import { Box, Text, TextInput } from '@mantine/core';
+import colors from '@/con/colors';
+import { Box, Paper, Stack, Text, TextInput } from '@mantine/core';
import { useProxy } from 'valtio/utils';
function DokterDanTenagaMedis() {
const dokterdantenagamedisState = useProxy(stateFasilitasKesehatan.dokterdantenagamedis)
return (
- Dokter & Tenaga Medis
+
+
+ Dokter & Tenaga Medis
+
+
);
}
diff --git a/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/_ui/fasilitas_kesehatan/fasilitas_pendukung/page.tsx b/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/_ui/fasilitas_kesehatan/fasilitas_pendukung/page.tsx
index 95ceb64a..6195fcae 100644
--- a/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/_ui/fasilitas_kesehatan/fasilitas_pendukung/page.tsx
+++ b/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/_ui/fasilitas_kesehatan/fasilitas_pendukung/page.tsx
@@ -1,17 +1,20 @@
import stateFasilitasKesehatan from '@/app/admin/(dashboard)/_state/kesehatan/data_kesehatan_warga/fasilitasKesehatan';
-import { Box, Text } from '@mantine/core';
+import { Box, Paper, Text } from '@mantine/core';
import { useProxy } from 'valtio/utils';
import { KesehatanEditor } from '../../../_com/kesehatanEditor';
+import colors from '@/con/colors';
function FasilitasPendukung() {
const fasilitaspendukungState = useProxy(stateFasilitasKesehatan.fasilitaspendukung)
return
- Fasilitas Pendukung
-
+ Fasilitas Pendukung
+ {
fasilitaspendukungState.create.form.content = val;
}} />
+
}
diff --git a/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/_ui/fasilitas_kesehatan/informasi_umum/page.tsx b/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/_ui/fasilitas_kesehatan/informasi_umum/page.tsx
index 8e785f17..b220d62c 100644
--- a/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/_ui/fasilitas_kesehatan/informasi_umum/page.tsx
+++ b/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/_ui/fasilitas_kesehatan/informasi_umum/page.tsx
@@ -1,35 +1,40 @@
'use client'
import stateFasilitasKesehatan from '@/app/admin/(dashboard)/_state/kesehatan/data_kesehatan_warga/fasilitasKesehatan';
-import { Box, Text, TextInput } from '@mantine/core';
+import colors from '@/con/colors';
+import { Box, Paper, Stack, Text, TextInput } from '@mantine/core';
import { useProxy } from 'valtio/utils';
function InformasiUmum() {
const infromasiState = useProxy(stateFasilitasKesehatan.informasiumum)
- return
- Informasi Umum
- {
- infromasiState.create.form.fasilitas = val.target.value
- }}
- />
- {
- infromasiState.create.form.alamat = val.target.value
- }}
- />
- {
- infromasiState.create.form.jamOperasional = val.target.value
- }}
- />
-
+ return
+
+ Informasi Umum
+
+ {
+ infromasiState.create.form.fasilitas = val.target.value
+ }}
+ />
+ {
+ infromasiState.create.form.alamat = val.target.value
+ }}
+ />
+ {
+ infromasiState.create.form.jamOperasional = val.target.value
+ }}
+ />
+
+
+
}
export default InformasiUmum;
diff --git a/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/_ui/fasilitas_kesehatan/layanan_unggulan/page.tsx b/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/_ui/fasilitas_kesehatan/layanan_unggulan/page.tsx
index 6dfc2c27..63c53209 100644
--- a/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/_ui/fasilitas_kesehatan/layanan_unggulan/page.tsx
+++ b/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/_ui/fasilitas_kesehatan/layanan_unggulan/page.tsx
@@ -1,18 +1,21 @@
'use client'
import stateFasilitasKesehatan from '@/app/admin/(dashboard)/_state/kesehatan/data_kesehatan_warga/fasilitasKesehatan';
-import { Box, Text } from '@mantine/core';
+import { Box, Paper, Text } from '@mantine/core';
import { useProxy } from 'valtio/utils';
import { KesehatanEditor } from '../../../_com/kesehatanEditor';
+import colors from '@/con/colors';
function LayananUnggulan() {
const informasiumumState = useProxy(stateFasilitasKesehatan.layananunggulan)
return
+
Layanan Unggulan
{
informasiumumState.create.form.content = val;
}} />
+
;
}
diff --git a/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/_ui/fasilitas_kesehatan/page.tsx b/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/_ui/fasilitas_kesehatan/page.tsx
index 38264c06..bdb84c62 100644
--- a/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/_ui/fasilitas_kesehatan/page.tsx
+++ b/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/_ui/fasilitas_kesehatan/page.tsx
@@ -2,7 +2,7 @@
import stateFasilitasKesehatan from '@/app/admin/(dashboard)/_state/kesehatan/data_kesehatan_warga/fasilitasKesehatan';
import colors from '@/con/colors';
-import { Box, Button, Center, SimpleGrid, Skeleton, Stack, Table, TableTbody, TableTd, TableTh, TableThead, TableTr, Text, Title } from '@mantine/core';
+import { Box, Button, Center, Paper, SimpleGrid, Skeleton, Stack, Table, TableTbody, TableTd, TableTh, TableThead, TableTr, Text, Title } from '@mantine/core';
import { useShallowEffect } from '@mantine/hooks';
import { useProxy } from 'valtio/utils';
import DokterDanTenagaMedis from './dokterdantenagamedis/page';
@@ -91,7 +91,7 @@ function FasilitasKesehatan() {
}}>
- Fasilitas Kesehatan
+ Tambah Fasilitas Kesehatan
{/* Informasi Umum */}
{/* Layanan Unggulan */}
@@ -110,7 +110,7 @@ function FasilitasKesehatan() {
- List Fasilitas Kesehatan
+ Data Fasilitas Kesehatan
@@ -141,100 +141,113 @@ function AllList() {
{Array.from({ length: 10 }).map((v, k) => )}
return
- Informasi Umum
- {allListState.informasiumum.findMany.data?.map((item) => (
-
+
+ Informasi Umum
+ {allListState.informasiumum.findMany.data?.map((item) => (
+
- {item.fasilitas}
- {item.alamat}
- {item.jamOperasional}
-
- ))}
+ {item.fasilitas}
+ {item.alamat}
+ {item.jamOperasional}
+
+ ))}
+
- Layanan Unggulan
- {allListState.layananunggulan.findMany.data?.map((item) => (
-
-
-
- ))}
+
+ Layanan Unggulan
+ {allListState.layananunggulan.findMany.data?.map((item) => (
+
+
+
+ ))}
+
- Dokter & Tenaga Medis
-
-
-
-
-
- Nama
-
-
- Specialist
-
-
- Jadwal
-
-
-
-
- {allListState.dokterdantenagamedis.findMany.data?.map((item) => (
-
- {item.name}
- Specialist {item.specialist}
- {item.jadwal}
+
+ Dokter & Tenaga Medis
+
+
+
+
+
+ Nama
+
+
+ Specialist
+
+
+ Jadwal
+
- ))}
-
-
+
+
+ {allListState.dokterdantenagamedis.findMany.data?.map((item) => (
+
+ {item.name}
+ Specialist {item.specialist}
+ {item.jadwal}
+
+ ))}
+
+
+
- Fasilitas Pendukung
- {allListState.fasilitaspendukung.findMany.data?.map((item) => (
-
-
-
- ))}
+
- Tarif & Layanan
-
-
-
-
- Layanan
-
-
- Tarif
-
-
-
-
- {allListState.tarifdanlayanan.findMany.data?.map((item) => (
-
- {item.layanan}
- Rp.{item.tarif}
+ Fasilitas Pendukung
+ {allListState.fasilitaspendukung.findMany.data?.map((item) => (
+
+
+
+ ))}
+
+
+
+ Tarif & Layanan
+
+
+
+
+ Layanan
+
+
+ Tarif
+
- ))}
-
-
+
+
+ {allListState.tarifdanlayanan.findMany.data?.map((item) => (
+
+ {item.layanan}
+ Rp.{item.tarif}
+
+ ))}
+
+
+
- Prosedur Pendaftaran
- {allListState.prosedurpendaftaran.findMany.data?.map((item) => (
-
-
-
- ))}
+
+ Prosedur Pendaftaran
+ {allListState.prosedurpendaftaran.findMany.data?.map((item) => (
+
+
+
+ ))}
+
}
diff --git a/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/_ui/fasilitas_kesehatan/prosedurpendaftaran/page.tsx b/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/_ui/fasilitas_kesehatan/prosedurpendaftaran/page.tsx
index 17a42a30..b28cb52e 100644
--- a/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/_ui/fasilitas_kesehatan/prosedurpendaftaran/page.tsx
+++ b/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/_ui/fasilitas_kesehatan/prosedurpendaftaran/page.tsx
@@ -1,19 +1,22 @@
import stateFasilitasKesehatan from '@/app/admin/(dashboard)/_state/kesehatan/data_kesehatan_warga/fasilitasKesehatan';
-import { Box, Text } from '@mantine/core';
+import { Box, Text, Paper } from '@mantine/core';
import { useProxy } from 'valtio/utils';
import { KesehatanEditor } from '../../../_com/kesehatanEditor';
+import colors from '@/con/colors';
function ProsedurPendaftaran() {
const prosedurpendaftaranState = useProxy(stateFasilitasKesehatan.prosedurpendaftaran)
return
+
Prosedur Pendaftaran
- {
- prosedurpendaftaranState.create.form.content = val;
- }} />
-
-
+ {
+ prosedurpendaftaranState.create.form.content = val;
+ }} />
+
+
+
}
export default ProsedurPendaftaran;
diff --git a/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/_ui/fasilitas_kesehatan/tarifdanlayanan/page.tsx b/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/_ui/fasilitas_kesehatan/tarifdanlayanan/page.tsx
index 6622c5c6..b9ae2bce 100644
--- a/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/_ui/fasilitas_kesehatan/tarifdanlayanan/page.tsx
+++ b/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/_ui/fasilitas_kesehatan/tarifdanlayanan/page.tsx
@@ -1,27 +1,32 @@
import stateFasilitasKesehatan from '@/app/admin/(dashboard)/_state/kesehatan/data_kesehatan_warga/fasilitasKesehatan';
-import { Box, Text, TextInput } from '@mantine/core';
+import colors from '@/con/colors';
+import { Box, Paper, Stack, Text, TextInput } from '@mantine/core';
import { useProxy } from 'valtio/utils';
function TarifDanLayanan() {
const tarifdanlayanan = useProxy(stateFasilitasKesehatan.tarifdanlayanan)
return
- Tarif & Layanan
- {
- tarifdanlayanan.create.form.tarif = val.target.value
- }}
- />
- {
- tarifdanlayanan.create.form.layanan = val.target.value
- }}
- />
-
+
+ Tarif & Layanan
+
+ {
+ tarifdanlayanan.create.form.tarif = val.target.value
+ }}
+ />
+ {
+ tarifdanlayanan.create.form.layanan = val.target.value
+ }}
+ />
+
+
+
}
export default TarifDanLayanan;
diff --git a/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/_ui/grafik_hasil_kepuasan/page.tsx b/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/_ui/grafik_hasil_kepuasan/page.tsx
index d9aefcf6..cd352a75 100644
--- a/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/_ui/grafik_hasil_kepuasan/page.tsx
+++ b/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/_ui/grafik_hasil_kepuasan/page.tsx
@@ -1,16 +1,20 @@
+/* eslint-disable @typescript-eslint/no-explicit-any */
'use client'
import stategrafikKepuasan from '@/app/admin/(dashboard)/_state/kesehatan/data_kesehatan_warga/grafikKepuasan';
import colors from '@/con/colors';
-import { Box, Button, Group, Stack, TextInput, Title } from '@mantine/core';
-import { useShallowEffect } from '@mantine/hooks';
-import { useState } from 'react';
-import { Bar, Legend, RadialBarChart, ResponsiveContainer, Tooltip, XAxis, YAxis } from 'recharts';
+import { Box, Button, Group, Paper, Skeleton, Stack, TextInput, Title } from '@mantine/core';
+import { useMediaQuery, useShallowEffect } from '@mantine/hooks';
+import { useEffect, useState } from 'react';
+import { Bar, BarChart, Legend, Tooltip, XAxis, YAxis } from 'recharts';
import { useProxy } from 'valtio/utils';
function GrafikHasilKepuasan() {
const grafikkepuasan = useProxy(stategrafikKepuasan.grafikkepuasan)
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ const [mounted, setMounted] = useState(false);
+ const isTablet = useMediaQuery('(max-width: 1024px)')
+ const isMobile = useMediaQuery('(max-width: 768px)')
const [chartData, setChartData] = useState([])
+
useShallowEffect(() => {
const fetchData = async () => {
await grafikkepuasan.findMany.load();
@@ -20,53 +24,76 @@ function GrafikHasilKepuasan() {
};
fetchData();
}, []);
+
+ useEffect(() => {
+ setMounted(true); // setelah komponen siap di client
+ }, []);
+
+ if (!mounted) {
+ return null; // Jangan render apa-apa dulu sebelum mounted
+ }
+
+
return (
-
- Grafik Hasil Kepuasan
-
- {
- grafikkepuasan.create.form.label = val.currentTarget.value
- }}
- />
- {
- grafikkepuasan.create.form.jumlah = val.currentTarget.value
- }}
- />
-
-
- {
- await grafikkepuasan.create.create();
- await grafikkepuasan.findMany.load();
- if (grafikkepuasan.findMany.data) {
- setChartData(grafikkepuasan.findMany.data);
- }
- }}
- >Submit
-
-
- Data Kelahiran & Kematian
-
-
-
-
-
-
-
-
-
-
+
+
+ Tambah Grafik Hasil Kepuasan
+
+ {
+ grafikkepuasan.create.form.label = val.currentTarget.value
+ }}
+ />
+ {
+ grafikkepuasan.create.form.jumlah = val.currentTarget.value
+ }}
+ />
+
+ {
+ await grafikkepuasan.create.create();
+ await grafikkepuasan.findMany.load();
+ if (grafikkepuasan.findMany.data) {
+ setChartData(grafikkepuasan.findMany.data);
+ }
+ }}
+ >Submit
+
+
+
+ {!chartData ? (
+
+
+ Data Hasil Kepuasan
+
+
+
+ ) : (
+
+
+ Data Hasil Kepuasan
+
+
+
+
+
+
+
+
+
+ )}
);
}
diff --git a/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/_ui/jadwal_kegiatan/deskripsi_kegiatan/page.tsx b/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/_ui/jadwal_kegiatan/deskripsi_kegiatan/page.tsx
index 9d751bb5..f9800287 100644
--- a/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/_ui/jadwal_kegiatan/deskripsi_kegiatan/page.tsx
+++ b/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/_ui/jadwal_kegiatan/deskripsi_kegiatan/page.tsx
@@ -1,19 +1,24 @@
import stateJadwalKegiatan from '@/app/admin/(dashboard)/_state/kesehatan/data_kesehatan_warga/jadwalKegiatan';
-import { Box, Text } from '@mantine/core';
+import { Box, Paper, Stack, Text } from '@mantine/core';
import { useProxy } from 'valtio/utils';
import { KesehatanEditor } from '../../../_com/kesehatanEditor';
+import colors from '@/con/colors';
function DeskripsiKegiatan() {
const deskripsiKegiatanState = useProxy(stateJadwalKegiatan.deskripsiKegiatan)
return (
- Deskripsi Kegiatan
- {
- deskripsiKegiatanState.create.form.deskripsi = val
- }}
- />
+
+
+ Deskripsi Kegiatan
+ {
+ deskripsiKegiatanState.create.form.deskripsi = val
+ }}
+ />
+
+
);
}
diff --git a/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/_ui/jadwal_kegiatan/dokumen_yang_diperlukan/page.tsx b/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/_ui/jadwal_kegiatan/dokumen_yang_diperlukan/page.tsx
index aa4d59a1..4593215e 100644
--- a/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/_ui/jadwal_kegiatan/dokumen_yang_diperlukan/page.tsx
+++ b/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/_ui/jadwal_kegiatan/dokumen_yang_diperlukan/page.tsx
@@ -1,19 +1,24 @@
import stateJadwalKegiatan from '@/app/admin/(dashboard)/_state/kesehatan/data_kesehatan_warga/jadwalKegiatan';
-import { Box, Text } from '@mantine/core';
+import { Box, Paper, Stack, Text } from '@mantine/core';
import { useProxy } from 'valtio/utils';
import { KesehatanEditor } from '../../../_com/kesehatanEditor';
+import colors from '@/con/colors';
function DokumenYangDiperlukan() {
const dokumenDiperlukan = useProxy(stateJadwalKegiatan.dokumenjadwalkegiatan)
return (
- Dokumen Yang Diperlukan
- {
- dokumenDiperlukan.create.form.content = val;
- }}
- />
+
+
+ Dokumen Yang Diperlukan
+ {
+ dokumenDiperlukan.create.form.content = val;
+ }}
+ />
+
+
);
}
diff --git a/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/_ui/jadwal_kegiatan/informasi_kegiatan/page.tsx b/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/_ui/jadwal_kegiatan/informasi_kegiatan/page.tsx
index e07b5e2a..ea6429c5 100644
--- a/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/_ui/jadwal_kegiatan/informasi_kegiatan/page.tsx
+++ b/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/_ui/jadwal_kegiatan/informasi_kegiatan/page.tsx
@@ -1,12 +1,15 @@
import stateJadwalKegiatan from '@/app/admin/(dashboard)/_state/kesehatan/data_kesehatan_warga/jadwalKegiatan';
-import { Box, Text, TextInput } from '@mantine/core';
+import colors from '@/con/colors';
+import { Box, Paper, Stack, TextInput, Title } from '@mantine/core';
import { useProxy } from 'valtio/utils';
function InformasiKegiatan() {
const informasiKegiatanState = useProxy(stateJadwalKegiatan.informasiKegiatan)
return (
- Informasi Kegiatan
+
+
+ Informasi Kegiatan
+
+
);
}
diff --git a/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/_ui/jadwal_kegiatan/layanan_yang_tersedia/page.tsx b/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/_ui/jadwal_kegiatan/layanan_yang_tersedia/page.tsx
index e3d2b28b..c324079a 100644
--- a/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/_ui/jadwal_kegiatan/layanan_yang_tersedia/page.tsx
+++ b/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/_ui/jadwal_kegiatan/layanan_yang_tersedia/page.tsx
@@ -1,19 +1,24 @@
import stateJadwalKegiatan from '@/app/admin/(dashboard)/_state/kesehatan/data_kesehatan_warga/jadwalKegiatan';
-import { Box, Text } from '@mantine/core';
+import { Box, Paper, Stack, Text } from '@mantine/core';
import { useProxy } from 'valtio/utils';
import { KesehatanEditor } from '../../../_com/kesehatanEditor';
+import colors from '@/con/colors';
function LayananTersedia() {
const layananTersediaState = useProxy(stateJadwalKegiatan.layanantersedia)
return (
- Layanan Yang Tersedia
- {
- layananTersediaState.create.form.content = val;
- }}
- />
+
+
+ Layanan Yang Tersedia
+ {
+ layananTersediaState.create.form.content = val;
+ }}
+ />
+
+
);
}
diff --git a/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/_ui/jadwal_kegiatan/page.tsx b/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/_ui/jadwal_kegiatan/page.tsx
index a38ea92f..792a618b 100644
--- a/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/_ui/jadwal_kegiatan/page.tsx
+++ b/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/_ui/jadwal_kegiatan/page.tsx
@@ -1,6 +1,6 @@
'use client'
import stateJadwalKegiatan from '@/app/admin/(dashboard)/_state/kesehatan/data_kesehatan_warga/jadwalKegiatan';
-import { Box, Button, SimpleGrid, Skeleton, Stack, Text, Title } from '@mantine/core';
+import { Box, Button, Paper, SimpleGrid, Skeleton, Stack, Text, Title } from '@mantine/core';
import { useShallowEffect } from '@mantine/hooks';
import { useProxy } from 'valtio/utils';
import DeskripsiKegiatan from './deskripsi_kegiatan/page';
@@ -9,6 +9,7 @@ import InformasiKegiatan from './informasi_kegiatan/page';
import LayananTersedia from './layanan_yang_tersedia/page';
import Pendaftaran from './pendaftaran/page';
import SyaratDanKetentuan from './syarat_dan_ketentuan/page';
+import colors from '@/con/colors';
function JadwalKegiatan() {
const allState = useProxy(stateJadwalKegiatan)
@@ -54,21 +55,25 @@ function JadwalKegiatan() {
base: 1, md: 2
}}>
- Jadwal Kegiatan
-
-
-
-
-
-
-
- Submit
-
+
+ Tambah Jadwal Kegiatan
+
+
+
+
+
+
+
+ Submit
+
+
- List Jadwal Kegiatan
-
+
+ Data Jadwal Kegiatan
+
+
@@ -103,68 +108,82 @@ function AllList() {
);
}
return (
-
- Informasi Kegiatan
- {allList.informasiKegiatan.findMany.data?.map((item) => {
- return (
-
- {item.name}
- {item.tanggal}
- {item.waktu}
- {item.lokasi}
-
- )
- })}
+
- Deskripsi Kegiatan
- {allList.deskripsiKegiatan.findMany.data?.map((item) => {
- return (
-
-
-
- )
- })}
+
+ Informasi Kegiatan
+ {allList.informasiKegiatan.findMany.data?.map((item) => {
+ return (
+
+ {item.name}
+ {item.tanggal}
+ {item.waktu}
+ {item.lokasi}
+
+ )
+ })}
+
- Layanan Yang Tersedia
- {allList.layanantersedia.findMany.data?.map((item) => {
- return (
-
-
-
- )
- })}
+
- Syarat dan Ketentuan
- {allList.syaratketentuan.findMany.data?.map((item) => {
- return (
-
-
-
- )
- })}
+ Deskripsi Kegiatan
+ {allList.deskripsiKegiatan.findMany.data?.map((item) => {
+ return (
+
+
+
+ )
+ })}
+
- Dokumen Yang Diperlukan
- {allList.dokumenjadwalkegiatan.findMany.data?.map((item) => {
- return (
-
-
-
- )
- })}
+
+ Layanan Yang Tersedia
+ {allList.layanantersedia.findMany.data?.map((item) => {
+ return (
+
+
+
+ )
+ })}
+
- Pendaftaran
- {allList.pendaftaranjadwal.findMany.data?.map((item) => {
- return (
-
- {item.name}
- {item.tanggal}
- {item.namaOrangtua}
- {item.nomor}
- {item.alamat}
- {item.catatan}
-
- )
- })}
+
+ Syarat dan Ketentuan
+ {allList.syaratketentuan.findMany.data?.map((item) => {
+ return (
+
+
+
+ )
+ })}
+
+
+
+ Dokumen Yang Diperlukan
+ {allList.dokumenjadwalkegiatan.findMany.data?.map((item) => {
+ return (
+
+
+
+ )
+ })}
+
+
+
+ Pendaftaran
+ {allList.pendaftaranjadwal.findMany.data?.map((item) => {
+ return (
+
+ {item.name}
+ {item.tanggal}
+ {item.namaOrangtua}
+ {item.nomor}
+ {item.alamat}
+ {item.catatan}
+
+ )
+ })}
+
)
}
diff --git a/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/_ui/jadwal_kegiatan/pendaftaran/page.tsx b/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/_ui/jadwal_kegiatan/pendaftaran/page.tsx
index f59af324..6fa56544 100644
--- a/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/_ui/jadwal_kegiatan/pendaftaran/page.tsx
+++ b/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/_ui/jadwal_kegiatan/pendaftaran/page.tsx
@@ -1,56 +1,61 @@
'use client'
import stateJadwalKegiatan from '@/app/admin/(dashboard)/_state/kesehatan/data_kesehatan_warga/jadwalKegiatan';
-import { Box, Text, Textarea, TextInput } from '@mantine/core';
+import colors from '@/con/colors';
+import { Box, Paper, Stack, Text, Textarea, TextInput } from '@mantine/core';
import { useProxy } from 'valtio/utils';
function Pendaftaran() {
- const pendaftaran = useProxy(stateJadwalKegiatan.pendaftaranjadwal)
+ const pendaftaran = useProxy(stateJadwalKegiatan.pendaftaranjadwal)
return (
- Pendaftaran
- {
- pendaftaran.create.form.name = val.target.value
- }}
- />
- {
- pendaftaran.create.form.tanggal = val.target.value
- }}
- />
- {
- pendaftaran.create.form.namaOrangtua = val.target.value
- }}
- />
- {
- pendaftaran.create.form.nomor = val.target.value
- }}
- />
- {
- pendaftaran.create.form.alamat = val.target.value
- }}
- />
-
);
}
diff --git a/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/_ui/jadwal_kegiatan/syarat_dan_ketentuan/page.tsx b/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/_ui/jadwal_kegiatan/syarat_dan_ketentuan/page.tsx
index 6c07c83c..dc2757fe 100644
--- a/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/_ui/jadwal_kegiatan/syarat_dan_ketentuan/page.tsx
+++ b/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/_ui/jadwal_kegiatan/syarat_dan_ketentuan/page.tsx
@@ -1,19 +1,24 @@
import stateJadwalKegiatan from '@/app/admin/(dashboard)/_state/kesehatan/data_kesehatan_warga/jadwalKegiatan';
-import { Box, Text } from '@mantine/core';
+import { Box, Paper, Stack, Text } from '@mantine/core';
import { useProxy } from 'valtio/utils';
import { KesehatanEditor } from '../../../_com/kesehatanEditor';
+import colors from '@/con/colors';
function SyaratDanKetentuan() {
const syaratKetentuan = useProxy(stateJadwalKegiatan.syaratketentuan)
return (
- Syarat dan Ketentuan
- {
- syaratKetentuan.create.form.content = val;
- }}
- />
+
+
+ Syarat dan Ketentuan
+ {
+ syaratKetentuan.create.form.content = val;
+ }}
+ />
+
+
);
}
diff --git a/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/_ui/persentase_data_kelahiran_kematian/page.tsx b/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/_ui/persentase_data_kelahiran_kematian/page.tsx
index beb1ea95..87714c66 100644
--- a/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/_ui/persentase_data_kelahiran_kematian/page.tsx
+++ b/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/_ui/persentase_data_kelahiran_kematian/page.tsx
@@ -1,16 +1,19 @@
'use client'
/* eslint-disable @typescript-eslint/no-explicit-any */
import statePersentase from '@/app/admin/(dashboard)/_state/kesehatan/data_kesehatan_warga/persentaseKelahiran';
-import { Box, Button, Stack, TextInput, Title } from '@mantine/core';
-import { useShallowEffect } from '@mantine/hooks';
+import colors from '@/con/colors';
+import { Box, Button, Group, Paper, Skeleton, Stack, TextInput, Title } from '@mantine/core';
+import { useMediaQuery, useShallowEffect } from '@mantine/hooks';
import { useEffect, useState } from 'react';
-import { Bar, BarChart, Legend, ResponsiveContainer, Tooltip, XAxis, YAxis } from 'recharts';
+import { Bar, BarChart, Legend, Tooltip, XAxis, YAxis } from 'recharts';
import { useProxy } from 'valtio/utils';
function PersentaseDataKelahiranKematian() {
const persentase = useProxy(statePersentase.persentasekelahiran);
const [chartData, setChartData] = useState([]);
const [mounted, setMounted] = useState(false); // untuk memastikan DOM sudah ready
+ const isTablet = useMediaQuery('(max-width: 1024px)')
+ const isMobile = useMediaQuery('(max-width: 768px)')
useEffect(() => {
setMounted(true);
@@ -30,78 +33,90 @@ function PersentaseDataKelahiranKematian() {
{/* Form Input */}
- Persentase Data Kelahiran & Kematian
- {
- persentase.create.form.tahun = val.currentTarget.value;
- }}
- />
- {
- persentase.create.form.kematianKasar = val.currentTarget.value;
- }}
- />
- {
- persentase.create.form.kematianBayi = val.currentTarget.value;
- }}
- />
- {
- persentase.create.form.kelahiranKasar = val.currentTarget.value;
- }}
- />
- {
- await persentase.create.create();
- await persentase.findMany.load();
- if (persentase.findMany.data) {
- setChartData(persentase.findMany.data);
- }
- }}
- >
- Submit
-
+
+ Tambah Persentase Data Kelahiran & Kematian
+
+ {
+ persentase.create.form.tahun = val.currentTarget.value;
+ }}
+ />
+ {
+ persentase.create.form.kematianKasar = val.currentTarget.value;
+ }}
+ />
+ {
+ persentase.create.form.kematianBayi = val.currentTarget.value;
+ }}
+ />
+ {
+ persentase.create.form.kelahiranKasar = val.currentTarget.value;
+ }}
+ />
+
+ {
+ await persentase.create.create();
+ await persentase.findMany.load();
+ if (persentase.findMany.data) {
+ setChartData(persentase.findMany.data);
+ }
+ }}
+ >
+ Submit
+
+
+
+
{/* Chart */}
-
- Data Kelahiran & Kematian
- {mounted && chartData.length > 0 && (
-
-
-
-
-
-
-
-
-
-
-
- )}
-
+ {!mounted && !chartData ? (
+
+
+ Data Kelahiran & Kematian
+
+
+
+ ) : (
+
+
+ Data Kelahiran & Kematian
+ {mounted && chartData.length > 0 && (
+
+
+
+
+
+
+
+
+
+ )}
+
+
+ )}
);
}
diff --git a/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/page.tsx b/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/page.tsx
index 14e45529..0f5a0f45 100644
--- a/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/page.tsx
+++ b/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/page.tsx
@@ -1,5 +1,5 @@
import colors from '@/con/colors';
-import { Stack, Tabs, TabsList, TabsPanel, TabsTab } from '@mantine/core';
+import { Stack, Tabs, TabsList, TabsPanel, TabsTab, Title } from '@mantine/core';
import ArtikelKesehatan from './_ui/artikel_kesehatan/page';
import FasilitasKesehatan from './_ui/fasilitas_kesehatan/page';
import GrafikHasilKepuasan from './_ui/grafik_hasil_kepuasan/page';
@@ -10,8 +10,9 @@ import PersentaseDataKelahiranKematian from './_ui/persentase_data_kelahiran_kem
function Page() {
return (
+ Data Kesehatan Warga
-
+
Persentase Kelahiran & Kematian
diff --git a/src/app/admin/(dashboard)/kesehatan/info-wabah-penyakit/page.tsx b/src/app/admin/(dashboard)/kesehatan/info-wabah-penyakit/page.tsx
index 7dfc0518..0e7322c2 100644
--- a/src/app/admin/(dashboard)/kesehatan/info-wabah-penyakit/page.tsx
+++ b/src/app/admin/(dashboard)/kesehatan/info-wabah-penyakit/page.tsx
@@ -1,10 +1,35 @@
+import colors from '@/con/colors';
+import { Box, Stack, Tabs, TabsList, TabsPanel, TabsTab, Title } from '@mantine/core';
import React from 'react';
+import CreateInfoWabahPenyakit from './ui/tambah_wabah_penyakit/page';
+import ListInfoWabahPenyakit from './ui/list_wabah_penyakit/page';
+
function Page() {
return (
-
- Wabah Penyakit
-
+
+
+ Info Wabah/Penyakit
+
+
+
+ Tambah Info Wabah/Penyakit
+
+
+ List Info Wabah/Penyakit
+
+
+
+
+
+
+
+
+
+
+
+
+
);
}
diff --git a/src/app/admin/(dashboard)/kesehatan/info-wabah-penyakit/ui/list_wabah_penyakit/page.tsx b/src/app/admin/(dashboard)/kesehatan/info-wabah-penyakit/ui/list_wabah_penyakit/page.tsx
new file mode 100644
index 00000000..329fea96
--- /dev/null
+++ b/src/app/admin/(dashboard)/kesehatan/info-wabah-penyakit/ui/list_wabah_penyakit/page.tsx
@@ -0,0 +1,33 @@
+import { Box, Paper, Stack, Table, TableTbody, TableTh, TableThead, TableTr, Title } from '@mantine/core';
+import colors from '@/con/colors';
+import React from 'react';
+
+function ListInfoWabahPenyakit() {
+ return (
+
+
+
+ List Info Wabah/Penyakit
+
+
+
+
+ Image
+ Nama Info Wabah/Penyakit
+ Deskripsi Info Wabah/Penyakit
+ Aksi
+ Detail
+
+
+
+
+
+
+
+
+
+
+ );
+}
+
+export default ListInfoWabahPenyakit;
diff --git a/src/app/admin/(dashboard)/kesehatan/info-wabah-penyakit/ui/tambah_wabah_penyakit/page.tsx b/src/app/admin/(dashboard)/kesehatan/info-wabah-penyakit/ui/tambah_wabah_penyakit/page.tsx
new file mode 100644
index 00000000..212e8d61
--- /dev/null
+++ b/src/app/admin/(dashboard)/kesehatan/info-wabah-penyakit/ui/tambah_wabah_penyakit/page.tsx
@@ -0,0 +1,45 @@
+import colors from '@/con/colors';
+import { Box, Button, Group, Paper, SimpleGrid, Stack, Text, TextInput, Title } from '@mantine/core';
+import { IconImageInPicture } from '@tabler/icons-react';
+import React from 'react';
+import { KesehatanEditor } from '../../../_com/kesehatanEditor';
+
+function CreateInfoWabahPenyakit() {
+ return (
+
+
+
+
+
+
+ Tambah Info Wabah/Penyakit
+
+ Masukkan Image
+
+
+ Nama Info Wabah/Penyakit}
+ placeholder='Masukkan nama info wabah/penyakit'
+ />
+
+ Deskripsi Info Wabah/Penyakit
+
+
+
+ Submit
+
+
+
+
+
+
+
+
+
+
+ );
+}
+
+export default CreateInfoWabahPenyakit;
diff --git a/src/app/admin/(dashboard)/kesehatan/kontak-darurat/page.tsx b/src/app/admin/(dashboard)/kesehatan/kontak-darurat/page.tsx
index ea20956b..12c0b0c0 100644
--- a/src/app/admin/(dashboard)/kesehatan/kontak-darurat/page.tsx
+++ b/src/app/admin/(dashboard)/kesehatan/kontak-darurat/page.tsx
@@ -1,10 +1,34 @@
+import colors from '@/con/colors';
+import { Box, Stack, Tabs, TabsList, TabsPanel, TabsTab, Title } from '@mantine/core';
import React from 'react';
+import CreateKontakDarurat from './ui/tambah_kontak_darurat/page';
+import ListKontakDarurat from './ui/list_kontak_darurat/page';
function Page() {
return (
-
- Kontak Darurat
-
+
+
+ Kontak Darurat
+
+
+
+ Tambah Kontak Darurat
+
+
+ List Kontak Darurat
+
+
+
+
+
+
+
+
+
+
+
+
+
);
}
diff --git a/src/app/admin/(dashboard)/kesehatan/kontak-darurat/ui/list_kontak_darurat/page.tsx b/src/app/admin/(dashboard)/kesehatan/kontak-darurat/ui/list_kontak_darurat/page.tsx
new file mode 100644
index 00000000..107bc33f
--- /dev/null
+++ b/src/app/admin/(dashboard)/kesehatan/kontak-darurat/ui/list_kontak_darurat/page.tsx
@@ -0,0 +1,33 @@
+import { Box, Paper, Stack, Table, TableTbody, TableTh, TableThead, TableTr, Title } from '@mantine/core';
+import colors from '@/con/colors';
+import React from 'react';
+
+function ListKontakDarurat() {
+ return (
+
+
+
+ List Kontak Darurat
+
+
+
+
+ Image
+ Nama Kontak Darurat
+ Deskripsi Kontak Darurat
+ Aksi
+ Detail
+
+
+
+
+
+
+
+
+
+
+ );
+}
+
+export default ListKontakDarurat;
diff --git a/src/app/admin/(dashboard)/kesehatan/kontak-darurat/ui/tambah_kontak_darurat/page.tsx b/src/app/admin/(dashboard)/kesehatan/kontak-darurat/ui/tambah_kontak_darurat/page.tsx
new file mode 100644
index 00000000..7de7b971
--- /dev/null
+++ b/src/app/admin/(dashboard)/kesehatan/kontak-darurat/ui/tambah_kontak_darurat/page.tsx
@@ -0,0 +1,45 @@
+import colors from '@/con/colors';
+import { Box, Button, Group, Paper, SimpleGrid, Stack, Text, TextInput, Title } from '@mantine/core';
+import { IconImageInPicture } from '@tabler/icons-react';
+import React from 'react';
+import { KesehatanEditor } from '../../../_com/kesehatanEditor';
+
+function CreateKontakDarurat() {
+ return (
+
+
+
+
+
+
+ Tambah Kontak Darurat
+
+ Masukkan Image
+
+
+ Nama Kontak Darurat}
+ placeholder='Masukkan nama kontak darurat'
+ />
+
+ Deskripsi Kontak Darurat
+
+
+
+ Submit
+
+
+
+
+
+
+
+
+
+
+ );
+}
+
+export default CreateKontakDarurat;
diff --git a/src/app/admin/(dashboard)/kesehatan/penanganan-darurat/page.tsx b/src/app/admin/(dashboard)/kesehatan/penanganan-darurat/page.tsx
index 62f2a24c..4d03ce9e 100644
--- a/src/app/admin/(dashboard)/kesehatan/penanganan-darurat/page.tsx
+++ b/src/app/admin/(dashboard)/kesehatan/penanganan-darurat/page.tsx
@@ -1,10 +1,34 @@
+import colors from '@/con/colors';
+import { Box, Stack, Tabs, TabsList, TabsPanel, TabsTab, Title } from '@mantine/core';
import React from 'react';
+import CreatePenangananDarurat from './ui/tambah_penanganan_darurat/page';
+import ListPenangananDarurat from './ui/list_penanganan_darurat/page';
function Page() {
return (
-
- Penanganan Darurat
-
+
+
+ Penanganan Darurat
+
+
+
+ Tambah Penanganan Darurat
+
+
+ List Penanganan Darurat
+
+
+
+
+
+
+
+
+
+
+
+
+
);
}
diff --git a/src/app/admin/(dashboard)/kesehatan/penanganan-darurat/ui/list_penanganan_darurat/page.tsx b/src/app/admin/(dashboard)/kesehatan/penanganan-darurat/ui/list_penanganan_darurat/page.tsx
new file mode 100644
index 00000000..c6f233eb
--- /dev/null
+++ b/src/app/admin/(dashboard)/kesehatan/penanganan-darurat/ui/list_penanganan_darurat/page.tsx
@@ -0,0 +1,33 @@
+import { Box, Paper, Stack, Table, TableTbody, TableTh, TableThead, TableTr, Title } from '@mantine/core';
+import colors from '@/con/colors';
+import React from 'react';
+
+function ListPenangananDarurat() {
+ return (
+
+
+
+ List Penanganan Darurat
+
+
+
+
+ Image
+ Nama Penanganan Darurat
+ Deskripsi Penanganan Darurat
+ Aksi
+ Detail
+
+
+
+
+
+
+
+
+
+
+ );
+}
+
+export default ListPenangananDarurat;
diff --git a/src/app/admin/(dashboard)/kesehatan/penanganan-darurat/ui/tambah_penanganan_darurat/page.tsx b/src/app/admin/(dashboard)/kesehatan/penanganan-darurat/ui/tambah_penanganan_darurat/page.tsx
new file mode 100644
index 00000000..5adecaee
--- /dev/null
+++ b/src/app/admin/(dashboard)/kesehatan/penanganan-darurat/ui/tambah_penanganan_darurat/page.tsx
@@ -0,0 +1,45 @@
+import colors from '@/con/colors';
+import { Box, Button, Group, Paper, SimpleGrid, Stack, Text, TextInput, Title } from '@mantine/core';
+import { IconImageInPicture } from '@tabler/icons-react';
+import React from 'react';
+import { KesehatanEditor } from '../../../_com/kesehatanEditor';
+
+function CreatePenangananDarurat() {
+ return (
+
+
+
+
+
+
+ Tambah Penanganan Darurat
+
+ Masukkan Image
+
+
+ Nama Penanganan Darurat}
+ placeholder='Masukkan nama penanganan darurat'
+ />
+
+ Deskripsi Penanganan Darurat
+
+
+
+ Submit
+
+
+
+
+
+
+
+
+
+
+ );
+}
+
+export default CreatePenangananDarurat;
diff --git a/src/app/admin/(dashboard)/kesehatan/posyandu/page.tsx b/src/app/admin/(dashboard)/kesehatan/posyandu/page.tsx
index a7049254..b611b965 100644
--- a/src/app/admin/(dashboard)/kesehatan/posyandu/page.tsx
+++ b/src/app/admin/(dashboard)/kesehatan/posyandu/page.tsx
@@ -1,11 +1,54 @@
+import colors from '@/con/colors';
+import { Box, Button, Group, Paper, SimpleGrid, Stack, Text, TextInput, Title } from '@mantine/core';
import React from 'react';
+import { KesehatanEditor } from '../_com/kesehatanEditor';
-function Page() {
+function Posyandu() {
return (
-
- Posyandu
-
+
+ Kesehatan
+
+
+
+
+ Posyandu
+ Nama Posyandu}
+ placeholder='masukkan nama posyandu'
+ />
+ Nomor Telepon Posyandu}
+ placeholder='masukkan nomor telepon posyandu'
+ />
+
+ Deskripsi Posyandu
+
+
+
+ Pelayanan Posyandu
+
+
+
+ Submit
+
+
+
+
+
+
+
+
+ Preview Data Posyandu
+
+
+
+
+
);
}
-export default Page;
+export default Posyandu;
diff --git a/src/app/admin/(dashboard)/kesehatan/program-kesehatan/page.tsx b/src/app/admin/(dashboard)/kesehatan/program-kesehatan/page.tsx
index e939d3da..90cfcc23 100644
--- a/src/app/admin/(dashboard)/kesehatan/program-kesehatan/page.tsx
+++ b/src/app/admin/(dashboard)/kesehatan/program-kesehatan/page.tsx
@@ -1,10 +1,33 @@
-import React from 'react';
+import colors from '@/con/colors';
+import { Box, Stack, Tabs, TabsList, TabsPanel, TabsTab, Title } from '@mantine/core';
+import CreateProgramKesehatan from './ui/tambah_program_kesehatan/page';
+import ListProgramKesehatan from './ui/list_program_kesehatan/page';
function Page() {
return (
-
- Program Kesehatan
-
+
+
+ Program Kesehatan
+
+
+
+ Tambah Program Kesehatan
+
+
+ List Program Kesehatan
+
+
+
+
+
+
+
+
+
+
+
+
+
);
}
diff --git a/src/app/admin/(dashboard)/kesehatan/program-kesehatan/ui/detail_program_kesehatan/page.tsx b/src/app/admin/(dashboard)/kesehatan/program-kesehatan/ui/detail_program_kesehatan/page.tsx
new file mode 100644
index 00000000..4794e2a6
--- /dev/null
+++ b/src/app/admin/(dashboard)/kesehatan/program-kesehatan/ui/detail_program_kesehatan/page.tsx
@@ -0,0 +1,11 @@
+import React from 'react';
+
+function DetailProgramKesehatan() {
+ return (
+
+ Page
+
+ );
+}
+
+export default DetailProgramKesehatan;
diff --git a/src/app/admin/(dashboard)/kesehatan/program-kesehatan/ui/list_program_kesehatan/page.tsx b/src/app/admin/(dashboard)/kesehatan/program-kesehatan/ui/list_program_kesehatan/page.tsx
new file mode 100644
index 00000000..a43e513c
--- /dev/null
+++ b/src/app/admin/(dashboard)/kesehatan/program-kesehatan/ui/list_program_kesehatan/page.tsx
@@ -0,0 +1,33 @@
+import { Box, Paper, Stack, Table, TableTbody, TableTh, TableThead, TableTr, Title } from '@mantine/core';
+import colors from '@/con/colors';
+import React from 'react';
+
+function ListProgramKesehatan() {
+ return (
+
+
+
+ List Program Kesehatan
+
+
+
+
+ Deskripsi Program Kesehatan
+ Nama Konten Program Kesehatan
+ Deskripsi Konten Program Kesehatan
+ Aksi
+ Detail
+
+
+
+
+
+
+
+
+
+
+ );
+}
+
+export default ListProgramKesehatan;
diff --git a/src/app/admin/(dashboard)/kesehatan/program-kesehatan/ui/tambah_program_kesehatan/page.tsx b/src/app/admin/(dashboard)/kesehatan/program-kesehatan/ui/tambah_program_kesehatan/page.tsx
new file mode 100644
index 00000000..6096fd81
--- /dev/null
+++ b/src/app/admin/(dashboard)/kesehatan/program-kesehatan/ui/tambah_program_kesehatan/page.tsx
@@ -0,0 +1,62 @@
+import colors from '@/con/colors';
+import { Box, Button, Group, Paper, SimpleGrid, Stack, Text, TextInput, Title } from '@mantine/core';
+import React from 'react';
+import { KesehatanEditor } from '../../../_com/kesehatanEditor';
+import { IconImageInPicture } from '@tabler/icons-react';
+
+function CreateProgramKesehatan() {
+ return (
+
+
+
+
+
+
+ Tambah Program Kesehatan
+
+ Deskripsi Program Kesehatan
+
+
+
+ Masukkan Image
+
+
+ Nama Konten Program Kesehatan}
+ placeholder='Masukkan nama konten program kesehatan'
+ />
+
+ Deskripsi Konten Program Kesehatan
+
+
+
+ Submit
+
+
+
+
+
+
+
+ Preview Data Program Kesehatan
+ Deskripsi Program Kesehatan
+
+ Image
+
+
+ Nama Konten Program Kesehatan
+ Deskripsi Konten Program Kesehatan
+
+
+
+
+
+
+ );
+}
+
+export default CreateProgramKesehatan;
diff --git a/src/app/admin/(dashboard)/kesehatan/puskesmas/page.tsx b/src/app/admin/(dashboard)/kesehatan/puskesmas/page.tsx
index 6e8c7851..269c4c2a 100644
--- a/src/app/admin/(dashboard)/kesehatan/puskesmas/page.tsx
+++ b/src/app/admin/(dashboard)/kesehatan/puskesmas/page.tsx
@@ -1,11 +1,34 @@
-import React from 'react';
+import colors from '@/con/colors';
+import { Box, Stack, Tabs, TabsList, TabsPanel, TabsTab, Title } from '@mantine/core';
+import UpdatePuskesmas from './ui/Edit-Puskesmas/updatePuskesmas';
+import CreatePuskesmas from './ui/Tambah-Puskesmas/createPuskesmas';
-function Page() {
+function Puskesmas() {
return (
-
- Puskesmas
-
+
+
+ Puskesmas
+
+
+
+ Tambah Puskesmas
+
+
+ Edit Puskesmas
+
+
+
+
+
+
+
+
+
+
+
+
+
);
}
-export default Page;
+export default Puskesmas;
diff --git a/src/app/admin/(dashboard)/kesehatan/puskesmas/ui/Edit-Puskesmas/updatePuskesmas.tsx b/src/app/admin/(dashboard)/kesehatan/puskesmas/ui/Edit-Puskesmas/updatePuskesmas.tsx
new file mode 100644
index 00000000..0b0c0f8e
--- /dev/null
+++ b/src/app/admin/(dashboard)/kesehatan/puskesmas/ui/Edit-Puskesmas/updatePuskesmas.tsx
@@ -0,0 +1,55 @@
+import colors from '@/con/colors';
+import { Box, Stack, SimpleGrid, Paper, Title, TextInput, Text } from '@mantine/core';
+import React from 'react';
+import { KesehatanEditor } from '../../../_com/kesehatanEditor';
+
+function UpdatePuskesmas() {
+ return (
+
+
+
+
+
+
+ Edit Puskesmas
+ Nama Puskesmas}
+ placeholder='Masukkan nama puskesmas'
+ />
+ No Telp Puskesmas}
+ placeholder='Masukkan no telp puskesmas'
+ />
+
+ Deskripsi
+
+
+
+ Pelayanan Posyandu
+
+
+
+
+
+
+
+
+ Preview Data Puskesmas
+ Nama Puskesmas
+ No Telp Puskesmas
+ Deskripsi
+ Pelayanan Posyandu
+
+
+
+
+
+
+ );
+}
+
+export default UpdatePuskesmas;
diff --git a/src/app/admin/(dashboard)/kesehatan/puskesmas/ui/Tambah-Puskesmas/createPuskesmas.tsx b/src/app/admin/(dashboard)/kesehatan/puskesmas/ui/Tambah-Puskesmas/createPuskesmas.tsx
new file mode 100644
index 00000000..dd54cee4
--- /dev/null
+++ b/src/app/admin/(dashboard)/kesehatan/puskesmas/ui/Tambah-Puskesmas/createPuskesmas.tsx
@@ -0,0 +1,55 @@
+import colors from '@/con/colors';
+import { Box, Paper, SimpleGrid, Stack, Text, TextInput, Title } from '@mantine/core';
+import React from 'react';
+import { KesehatanEditor } from '../../../_com/kesehatanEditor';
+
+function CreatePuskesmas() {
+ return (
+
+
+
+
+
+
+ Tambah Puskesmas
+ Nama Puskesmas}
+ placeholder='Masukkan nama puskesmas'
+ />
+ No Telp Puskesmas}
+ placeholder='Masukkan no telp puskesmas'
+ />
+
+ Deskripsi
+
+
+
+ Pelayanan Posyandu
+
+
+
+
+
+
+
+
+ Preview Data Puskesmas
+ Nama Puskesmas
+ No Telp Puskesmas
+ Deskripsi
+ Pelayanan Posyandu
+
+
+
+
+
+
+ );
+}
+
+export default CreatePuskesmas;
diff --git a/src/app/admin/(dashboard)/ppid/_com/PPIDTextEditor.tsx b/src/app/admin/(dashboard)/ppid/_com/PPIDTextEditor.tsx
new file mode 100644
index 00000000..2e6629aa
--- /dev/null
+++ b/src/app/admin/(dashboard)/ppid/_com/PPIDTextEditor.tsx
@@ -0,0 +1,100 @@
+'use client'
+import { Button, Stack } from '@mantine/core';
+import { Link, RichTextEditor } from '@mantine/tiptap';
+import Highlight from '@tiptap/extension-highlight';
+import SubScript from '@tiptap/extension-subscript';
+import Superscript from '@tiptap/extension-superscript';
+import TextAlign from '@tiptap/extension-text-align';
+import Underline from '@tiptap/extension-underline';
+import { useEditor } from '@tiptap/react';
+import StarterKit from '@tiptap/starter-kit';
+import { useEffect } from 'react';
+
+
+export function PPIDTextEditor({ onSubmit, onChange, showSubmit = true, initialContent = '', }: {
+ onSubmit?: (val: string) => void,
+ onChange: (val: string) => void,
+ showSubmit?: boolean,
+ initialContent?: string }) {
+ const editor = useEditor({
+ extensions: [
+ StarterKit,
+ Underline,
+ Link,
+ Superscript,
+ SubScript,
+ Highlight,
+ TextAlign.configure({ types: ['heading', 'paragraph'] }),
+ ],
+ immediatelyRender: false,
+ content: initialContent,
+ onUpdate : ({editor}) => {
+ onChange(editor.getHTML())
+ }
+ });
+
+ useEffect(() => {
+ if (editor && initialContent !== editor.getHTML()) {
+ editor.commands.setContent(initialContent || '
');
+ }
+ }, [initialContent, editor]);
+
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {showSubmit && (
+ {
+ if (!editor) return
+ onSubmit?.(editor?.getHTML())
+ }}>Submit
+ )}
+
+ );
+}
\ No newline at end of file
diff --git a/src/app/admin/(dashboard)/ppid/_com/ppid_Editor.tsx b/src/app/admin/(dashboard)/ppid/_com/ppid_Editor.tsx
new file mode 100644
index 00000000..b261c75a
--- /dev/null
+++ b/src/app/admin/(dashboard)/ppid/_com/ppid_Editor.tsx
@@ -0,0 +1,94 @@
+'use client'
+import { Button, Stack } from '@mantine/core';
+import { Link, RichTextEditor } from '@mantine/tiptap';
+import Highlight from '@tiptap/extension-highlight';
+import SubScript from '@tiptap/extension-subscript';
+import Superscript from '@tiptap/extension-superscript';
+import TextAlign from '@tiptap/extension-text-align';
+import Underline from '@tiptap/extension-underline';
+import { useEditor } from '@tiptap/react';
+import StarterKit from '@tiptap/starter-kit';
+
+const content =
+ 'Dokumen yang berisi kebijakan dan regulasi desa
';
+
+export function PPIDEditor({ onSubmit, onChange, showSubmit = true }: {
+ onSubmit?: (val: string) => void,
+ onChange: (val: string) => void,
+ showSubmit?: boolean }) {
+ const editor = useEditor({
+ extensions: [
+ StarterKit,
+ Underline,
+ Link,
+ Superscript,
+ SubScript,
+ Highlight,
+ TextAlign.configure({ types: ['heading', 'paragraph'] }),
+ ],
+ immediatelyRender: false,
+ content,
+ onUpdate : ({editor}) => {
+ onChange(editor.getHTML())
+ }
+ });
+
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {showSubmit && (
+ {
+ if (!editor) return
+ onSubmit?.(editor?.getHTML())
+ }}>Submit
+ )}
+
+ );
+}
\ No newline at end of file
diff --git a/src/app/admin/(dashboard)/ppid/daftar-informasi-publik-desa-darmasaba/page.tsx b/src/app/admin/(dashboard)/ppid/daftar-informasi-publik-desa-darmasaba/page.tsx
index 2ea8f73f..756426ac 100644
--- a/src/app/admin/(dashboard)/ppid/daftar-informasi-publik-desa-darmasaba/page.tsx
+++ b/src/app/admin/(dashboard)/ppid/daftar-informasi-publik-desa-darmasaba/page.tsx
@@ -1,11 +1,116 @@
-import React from 'react';
+'use client'
+import colors from '@/con/colors';
+import { Box, Button, Group, Paper, SimpleGrid, Skeleton, Stack, Table, TableTbody, TableTd, TableTh, TableThead, TableTr, TextInput, Title } from '@mantine/core';
+import { useShallowEffect } from '@mantine/hooks';
+import { useProxy } from 'valtio/utils';
+import stateDaftarInformasiPublik from '../../_state/ppid/daftar_informasi_publik/daftarInformasiPublik';
+import { PPIDTextEditor } from '../_com/PPIDTextEditor';
function Page() {
+ const daftarInformasi = useProxy(stateDaftarInformasiPublik.daftarInformasi)
+ const submit = () => {
+ if (daftarInformasi.create.form.jenisInformasi &&
+ daftarInformasi.create.form.deskripsi &&
+ daftarInformasi.create.form.tanggal) {
+ daftarInformasi.create.create()
+ }
+ }
return (
-
- daftar-informasi-publik-desa-darmasaba
-
+
+
+
+
+
+ Daftar Informasi Publik Desa Darmasaba
+ {
+ daftarInformasi.create.form.jenisInformasi = val.target.value
+ }}
+ />
+ {
+ daftarInformasi.create.form.deskripsi = val
+ }}
+ />
+ {
+ daftarInformasi.create.form.tanggal = val.target.value
+ }}
+ />
+
+ Submit
+
+
+
+
+
+
+
+
+
);
}
+function ListDaftarInformasi() {
+ const listData = useProxy(stateDaftarInformasiPublik.daftarInformasi)
+ useShallowEffect(() => {
+ listData.findMany.load()
+ }, [])
+ if (!listData.findMany.data) return
+ {Array.from({ length: 10 }).map((v, k) => )}
+
+ return (
+
+
+
+ List Daftar Informasi Publik Desa Darmasaba
+
+
+
+
+ No
+
+
+ Jenis Informasi
+
+
+ Deskripsi
+
+
+ Tanggal Publikasi
+
+
+
+
+ {listData.findMany.data?.map((item) => (
+
+ {item.nomor}
+ {item.jenisInformasi}
+
+ {item.tanggal}
+
+ ))}
+
+
+
+
+
+ )
+}
+
export default Page;
diff --git a/src/app/admin/(dashboard)/ppid/dasar-hukum/create/create.tsx b/src/app/admin/(dashboard)/ppid/dasar-hukum/create/create.tsx
new file mode 100644
index 00000000..4783166a
--- /dev/null
+++ b/src/app/admin/(dashboard)/ppid/dasar-hukum/create/create.tsx
@@ -0,0 +1,44 @@
+'use client'
+import { Box, Stack, Text } from '@mantine/core';
+import dynamic from 'next/dynamic';
+
+const PPIDTextEditor = dynamic(() => import('../../_com/PPIDTextEditor').then(mod => mod.PPIDTextEditor), {
+ ssr: false,
+});
+
+function CreateDasarHukum({
+ valueJudul,
+ valueContent,
+ onJudulChange,
+ onContentChange,
+ error
+} : {
+ valueJudul: string;
+ valueContent: string;
+ onJudulChange: (val: string) => void;
+ onContentChange: (val: string) => void;
+ error?: string;
+}) {
+
+ return (
+
+
+ Judul
+
+ Content
+
+ {error && {error} }
+
+
+ );
+}
+
+export default CreateDasarHukum;
diff --git a/src/app/admin/(dashboard)/ppid/dasar-hukum/listData/page.tsx b/src/app/admin/(dashboard)/ppid/dasar-hukum/listData/page.tsx
new file mode 100644
index 00000000..e1d7af57
--- /dev/null
+++ b/src/app/admin/(dashboard)/ppid/dasar-hukum/listData/page.tsx
@@ -0,0 +1,40 @@
+'use client'
+import React from 'react';
+import { useProxy } from 'valtio/utils';
+import stateDasarHukumPPID from '../../../_state/ppid/dasar_hukum/dasarHukum';
+import { useShallowEffect } from '@mantine/hooks';
+import { Box, Paper, Skeleton, Stack, Text, Title } from '@mantine/core';
+import colors from '@/con/colors';
+
+function ListDataDasarHukum() {
+ const dataList = useProxy(stateDasarHukumPPID)
+ useShallowEffect(() => {
+ dataList.findById.load("")
+ }, [])
+
+ if(!dataList.findById.data) return
+ {Array.from({length: 10}).map((v, k) => )}
+
+
+const dataArray = Array.isArray(dataList.findById.data)
+ ? dataList.findById.data
+ : [dataList.findById.data];
+
+ return (
+
+
+ List Dasar Hukum PPID
+ {dataArray.map((item) => (
+
+ Judul
+
+ Content
+
+
+ ))}
+
+
+ );
+}
+
+export default ListDataDasarHukum;
diff --git a/src/app/admin/(dashboard)/ppid/dasar-hukum/page.tsx b/src/app/admin/(dashboard)/ppid/dasar-hukum/page.tsx
index f9cdac0d..dcb5c899 100644
--- a/src/app/admin/(dashboard)/ppid/dasar-hukum/page.tsx
+++ b/src/app/admin/(dashboard)/ppid/dasar-hukum/page.tsx
@@ -1,11 +1,62 @@
-import React from 'react';
+'use client'
+import colors from '@/con/colors';
+import { Box, Button, Group, Paper, SimpleGrid, Stack, Title } from '@mantine/core';
+import CreateDasarHukum from './create/create';
+import ListDataDasarHukum from './listData/page';
+import { useShallowEffect } from '@mantine/hooks';
+import { useProxy } from 'valtio/utils';
+import stateDasarHukumPPID from '../../_state/ppid/dasar_hukum/dasarHukum';
+import { useEffect, useState } from 'react';
function Page() {
+ const dasarHukumState = useProxy(stateDasarHukumPPID)
+ const [judul, setJudul] = useState('');
+ const [content, setContent] = useState('');
+
+ useShallowEffect(() => {
+ if (!dasarHukumState.findById.data) {
+ dasarHukumState.findById.initialize(); // biar masuk ke `findFirst` route kamu
+ }
+ }, []);
+
+ useEffect(() => {
+ if (dasarHukumState.findById.data) {
+ setJudul(dasarHukumState.findById.data.judul ?? '')
+ setContent(dasarHukumState.findById.data.content ?? '')
+ }
+ }, [dasarHukumState.findById.data])
+
+ const submit = () => {
+ if (dasarHukumState.findById.data) {
+ dasarHukumState.findById.data.judul = judul;
+ dasarHukumState.findById.data.content = content;
+ dasarHukumState.update.save(dasarHukumState.findById.data)
+ }
+ }
+
return (
-
- dasar-hukum
-
- );
+
+
+
+
+ Dasar Hukum PPID
+
+
+
+ Submit
+
+
+
+
+
+
+
+ )
}
export default Page;
diff --git a/src/app/admin/(dashboard)/ppid/ikm-desa-darmasaba/_ui/grafik_berdasarkan_jenis_kelamin_responden/page.tsx b/src/app/admin/(dashboard)/ppid/ikm-desa-darmasaba/_ui/grafik_berdasarkan_jenis_kelamin_responden/page.tsx
new file mode 100644
index 00000000..18a8bf35
--- /dev/null
+++ b/src/app/admin/(dashboard)/ppid/ikm-desa-darmasaba/_ui/grafik_berdasarkan_jenis_kelamin_responden/page.tsx
@@ -0,0 +1,142 @@
+/* eslint-disable @typescript-eslint/no-explicit-any */
+'use client'
+import stateGrafikBerdasarkanJenisKelamin from '@/app/admin/(dashboard)/_state/ppid/indeks_kepuasan_masyarakat/grafikBerdasarkanJenisKelamin';
+import colors from '@/con/colors';
+import { Box, Button, Center, Flex, Paper, Stack, Text, TextInput, Title } from '@mantine/core';
+import { useShallowEffect } from '@mantine/hooks';
+import { useEffect, useState } from 'react';
+import { Cell, Pie, PieChart } from 'recharts';
+import { useProxy } from 'valtio/utils';
+
+function GrafikBerdasarkanJenisKelamin() {
+ const grafikBerdasarkanJenisKelamin = useProxy(stateGrafikBerdasarkanJenisKelamin.grafikBerdasarkanJenisKelamin)
+ const [donutData, setDonutData] = useState([]);
+ const [mounted, setMounted] = useState(false);
+
+ useEffect(() => {
+ setMounted(true);
+ }, [])
+
+ const updateChartData = (data: any) => {
+ if (data && data.length > 0) {
+ const totalLaki = data.reduce((acc: number, cur: any) => acc + Number(cur.laki || 0), 0);
+ const totalPerempuan = data.reduce((acc: number, cur: any) => acc + Number(cur.perempuan || 0), 0);
+
+ setDonutData([
+ { name: 'Laki-laki', value: totalLaki, color: colors['blue-button'], key: 'laki-laki' },
+ { name: 'Perempuan', value: totalPerempuan, color: '#FF6384', key: 'perempuan' }
+ ]);
+ }
+ };
+
+ useShallowEffect(() => {
+ fetchData();
+ }, []);
+
+ const fetchData = async () => {
+ await grafikBerdasarkanJenisKelamin.findMany.load();
+ if (grafikBerdasarkanJenisKelamin.findMany.data) {
+ updateChartData(grafikBerdasarkanJenisKelamin.findMany.data);
+ }
+ };
+
+ const handleSubmit = async () => {
+ try {
+ // Simpan data baru
+ await grafikBerdasarkanJenisKelamin.create.create();
+
+ // Muat ulang data
+ await grafikBerdasarkanJenisKelamin.findMany.load();
+
+ // Update chart dengan data baru
+ if (grafikBerdasarkanJenisKelamin.findMany.data) {
+ updateChartData(grafikBerdasarkanJenisKelamin.findMany.data);
+ }
+
+ // Reset form setelah submit
+ grafikBerdasarkanJenisKelamin.create.form.laki = '';
+ grafikBerdasarkanJenisKelamin.create.form.perempuan = '';
+ } catch (error) {
+ console.error("Error submitting data:", error);
+ }
+ };
+
+ return (
+
+
+
+ Grafik Hasil Kepuasan Masyarakat Terhadap Pelayanan Publik
+ {
+ grafikBerdasarkanJenisKelamin.create.form.laki = val.currentTarget.value;
+ }}
+ />
+ {
+ grafikBerdasarkanJenisKelamin.create.form.perempuan = val.currentTarget.value;
+ }}
+ />
+
+ Submit
+
+
+
+
+ {/* Chart */}
+
+
+
+ Grafik Berdasarkan Jenis Kelamin Responden
+ {mounted && donutData.length > 0 && (
+
+
+
+
+
+ {donutData.map((entry, index) => (
+ |
+ ))}
+
+
+
+
+
+ Perempuan: {donutData.find((entry) => entry.name === 'Perempuan')?.value}
+
+
+
+ Laki-laki: {donutData.find((entry) => entry.name === 'Laki-laki')?.value}
+
+
+ )}
+
+
+
+
+ );
+}
+
+export default GrafikBerdasarkanJenisKelamin;
diff --git a/src/app/admin/(dashboard)/ppid/ikm-desa-darmasaba/_ui/grafik_berdasarkan_responden/page.tsx b/src/app/admin/(dashboard)/ppid/ikm-desa-darmasaba/_ui/grafik_berdasarkan_responden/page.tsx
new file mode 100644
index 00000000..1a578cba
--- /dev/null
+++ b/src/app/admin/(dashboard)/ppid/ikm-desa-darmasaba/_ui/grafik_berdasarkan_responden/page.tsx
@@ -0,0 +1,173 @@
+'use client'
+/* eslint-disable @typescript-eslint/no-explicit-any */
+import stateGrafikResponden from '@/app/admin/(dashboard)/_state/ppid/indeks_kepuasan_masyarakat/grafikBerdasarkanResponden';
+import colors from '@/con/colors';
+import { Box, Button, Center, Flex, Group, Paper, Stack, Text, TextInput, Title } from '@mantine/core';
+import { useShallowEffect } from '@mantine/hooks';
+import React, { useEffect, useState } from 'react';
+import { PieChart, Pie, Cell } from 'recharts';
+import { useProxy } from 'valtio/utils';
+
+function GrafikBerdasarkanResponden() {
+ const grafikBerdasarkanResponden = useProxy(stateGrafikResponden.grafikBerdasarkanResponden)
+ const [donutData, setDonutData] = useState([]);
+ const [mounted, setMounted] = useState(false);
+
+ useEffect(() => {
+ setMounted(true);
+ }, [])
+
+ const updateChartData = (data: any) => {
+ if (data && data.length > 0) {
+ const totalSangatBaik = data.reduce((acc: number, cur: any) => acc + Number(cur.sangatbaik || 0), 0);
+ const totalBaik = data.reduce((acc: number, cur: any) => acc + Number(cur.baik || 0), 0);
+ const totalKurangBaik = data.reduce((acc: number, cur: any) => acc + Number(cur.kurangbaik || 0), 0);
+ const totalTidakBaik = data.reduce((acc: number, cur: any) => acc + Number(cur.tidakbaik || 0), 0);
+ setDonutData([
+ { name: 'sangatbaik', value: totalSangatBaik, color: colors['blue-button'], key: 'sangatbaik' },
+ { name: 'baik', value: totalBaik, color: '#10A85AFF', key: 'baik' },
+ { name: 'kurangbaik', value: totalKurangBaik, color: '#B3AA12FF', key: 'kurangbaik' },
+ { name: 'tidakbaik', value: totalTidakBaik, color: '#B21313FF', key: 'tidakbaik' }
+ ]);
+ }
+ };
+
+ useShallowEffect(() => {
+ fetchData();
+ }, []);
+
+ const fetchData = async () => {
+ await grafikBerdasarkanResponden.findMany.load();
+ if (grafikBerdasarkanResponden.findMany.data) {
+ updateChartData(grafikBerdasarkanResponden.findMany.data);
+ }
+ };
+
+ const handleSubmit = async () => {
+ try {
+ // Simpan data baru
+ await grafikBerdasarkanResponden.create.create();
+
+ // Muat ulang data
+ await grafikBerdasarkanResponden.findMany.load();
+
+ // Update chart dengan data baru
+ if (grafikBerdasarkanResponden.findMany.data) {
+ updateChartData(grafikBerdasarkanResponden.findMany.data);
+ }
+
+ // Reset form setelah submit
+ grafikBerdasarkanResponden.create.form.sangatbaik = '';
+ grafikBerdasarkanResponden.create.form.baik = '';
+ grafikBerdasarkanResponden.create.form.kurangbaik = '';
+ grafikBerdasarkanResponden.create.form.tidakbaik = '';
+ } catch (error) {
+ console.error("Error submitting data:", error);
+ }
+ };
+ return (
+
+
+
+
+ Grafik Berdasarkan Responden
+ {
+ grafikBerdasarkanResponden.create.form.sangatbaik = val.currentTarget.value;
+ }}
+ />
+ {
+ grafikBerdasarkanResponden.create.form.baik = val.currentTarget.value;
+ }}
+ />
+ {
+ grafikBerdasarkanResponden.create.form.kurangbaik = val.currentTarget.value;
+ }}
+ />
+ {
+ grafikBerdasarkanResponden.create.form.tidakbaik = val.currentTarget.value;
+ }}
+ />
+
+
+ Submit
+
+
+
+
+
+
+ {/* Chart */}
+
+
+
+ Grafik Berdasarkan Responden
+ {mounted && donutData.length > 0 && (
+
+
+
+
+ {donutData.map((entry, index) => (
+ |
+ ))}
+
+
+
+
+
+ Sangat Baik: {donutData.find((entry) => entry.name === 'sangatbaik')?.value}
+
+
+
+ Baik: {donutData.find((entry) => entry.name === 'baik')?.value}
+
+
+
+ Kurang Baik: {donutData.find((entry) => entry.name === 'kurangbaik')?.value}
+
+
+
+ Tidak Baik: {donutData.find((entry) => entry.name === 'tidakbaik')?.value}
+
+
+ )}
+
+
+
+
+ );
+}
+
+export default GrafikBerdasarkanResponden;
diff --git a/src/app/admin/(dashboard)/ppid/ikm-desa-darmasaba/_ui/grafik_berdasarkan_umur/page.tsx b/src/app/admin/(dashboard)/ppid/ikm-desa-darmasaba/_ui/grafik_berdasarkan_umur/page.tsx
new file mode 100644
index 00000000..5e3d0e1f
--- /dev/null
+++ b/src/app/admin/(dashboard)/ppid/ikm-desa-darmasaba/_ui/grafik_berdasarkan_umur/page.tsx
@@ -0,0 +1,164 @@
+'use client'
+/* eslint-disable @typescript-eslint/no-explicit-any */
+import colors from '@/con/colors';
+import { Box, Button, Center, Flex, Group, Paper, Stack, Text, TextInput, Title } from '@mantine/core';
+import React, { useEffect, useState } from 'react';
+import { useProxy } from 'valtio/utils';
+import stateGrafikBerdasarkanUmur from '@/app/admin/(dashboard)/_state/ppid/indeks_kepuasan_masyarakat/grafikBerdasarkanUmur';
+import { useShallowEffect } from '@mantine/hooks';
+import { PieChart, Pie, Cell } from 'recharts';
+
+function GrafikBerdasarakanUmur() {
+ const grafikBerdasarkanUmur = useProxy(stateGrafikBerdasarkanUmur.grafikBerdasarkanUmur)
+ const [donutData, setDonutData] = useState([]);
+ const [mounted, setMounted] = useState(false);
+
+ useEffect(() => {
+ setMounted(true);
+ }, []);
+
+ const updateChartData = (data: any) => {
+ if (data && data.length > 0) {
+ const totalRemaja = data.reduce((acc: number, cur: any) => acc + Number(cur.remaja || 0), 0);
+ const totalDewasa = data.reduce((acc: number, cur: any) => acc + Number(cur.dewasa || 0), 0);
+ const totalOrangtua = data.reduce((acc: number, cur: any) => acc + Number(cur.orangtua || 0), 0);
+ const totalLansia = data.reduce((acc: number, cur: any) => acc + Number(cur.lansia || 0), 0);
+
+ setDonutData([
+ { name: 'Remaja', value: totalRemaja, color: colors['blue-button'], key: 'remaja' },
+ { name: 'Dewasa', value: totalDewasa, color: '#D32711FF', key: 'dewasa' },
+ { name: 'Orangtua', value: totalOrangtua, color: '#B46B04FF', key: 'orangtua' },
+ { name: 'Lansia', value: totalLansia, color: '#038617FF', key: 'lansia' }
+ ]);
+ }
+ };
+
+ useShallowEffect(() => {
+ fetchData();
+ }, []);
+
+ const fetchData = async () => {
+ await grafikBerdasarkanUmur.findMany.load();
+ if (grafikBerdasarkanUmur.findMany.data) {
+ updateChartData(grafikBerdasarkanUmur.findMany.data);
+ }
+ }
+
+ const handleSubmit = async () => {
+ try {
+ await grafikBerdasarkanUmur.create.create();
+ await grafikBerdasarkanUmur.findMany.load();
+ if (grafikBerdasarkanUmur.findMany.data) {
+ updateChartData(grafikBerdasarkanUmur.findMany.data);
+ }
+ } catch (error) {
+ console.error("Error submitting data:", error);
+ }
+ }
+ return (
+
+
+
+
+ Grafik Berdasarkan Umur Responden
+ {
+ grafikBerdasarkanUmur.create.form.remaja = val.currentTarget.value;
+ }}
+ />
+ {
+ grafikBerdasarkanUmur.create.form.dewasa = val.currentTarget.value;
+ }}
+ />
+ {
+ grafikBerdasarkanUmur.create.form.orangtua = val.currentTarget.value;
+ }}
+ />
+ {
+ grafikBerdasarkanUmur.create.form.lansia = val.currentTarget.value;
+ }}
+ />
+
+
+ Submit
+
+
+
+
+
+
+ {/* Chart */}
+
+
+
+ Grafik Berdasarkan Umur Responden
+ {mounted && donutData.length > 0 && (
+
+
+
+
+ {donutData.map((entry, index) => (
+ |
+ ))}
+
+
+
+
+
+ 17 - 25 tahun: {donutData.find((entry) => entry.name === 'remaja')?.value}
+
+
+
+ 26 - 45 tahun: {donutData.find((entry) => entry.name === 'dewasa')?.value}
+
+
+
+ 46 - 60 tahun: {donutData.find((entry) => entry.name === 'orangtua')?.value}
+
+
+
+ di atas 60 tahun: {donutData.find((entry) => entry.name === 'lansia')?.value}
+
+
+ )}
+
+
+
+
+ );
+}
+
+export default GrafikBerdasarakanUmur;
diff --git a/src/app/admin/(dashboard)/ppid/ikm-desa-darmasaba/_ui/grafik_hasil_kepuasan_masyarakat/page.tsx b/src/app/admin/(dashboard)/ppid/ikm-desa-darmasaba/_ui/grafik_hasil_kepuasan_masyarakat/page.tsx
new file mode 100644
index 00000000..b114d94e
--- /dev/null
+++ b/src/app/admin/(dashboard)/ppid/ikm-desa-darmasaba/_ui/grafik_hasil_kepuasan_masyarakat/page.tsx
@@ -0,0 +1,94 @@
+/* eslint-disable @typescript-eslint/no-explicit-any */
+'use client'
+import stateGrafikHasilKepuasanMasyarakat from '@/app/admin/(dashboard)/_state/ppid/indeks_kepuasan_masyarakat/grafikHasilKepuasan';
+import colors from '@/con/colors';
+import { Box, Button, Paper, Stack, TextInput, Title } from '@mantine/core';
+import { useMediaQuery, useShallowEffect } from '@mantine/hooks';
+import React, { useEffect, useState } from 'react';
+import { Bar, BarChart, Legend, Tooltip, XAxis, YAxis } from 'recharts';
+import { useProxy } from 'valtio/utils';
+
+function GrafikHasilKepuasan() {
+ const grafikHasilKepuasan = useProxy(stateGrafikHasilKepuasanMasyarakat.grafikHasilKepuasanMasyarakat)
+ const [chartData, setChartData] = useState([]);
+ const [mounted, setMounted] = useState(false);
+ const isTablet = useMediaQuery('(max-width: 1024px)')
+ const isMobile = useMediaQuery('(max-width: 768px)')
+
+ useEffect(() => {
+ setMounted(true);
+ }, [])
+
+ useShallowEffect(() => {
+ const fetchData = async () => {
+ await grafikHasilKepuasan.findMany.load();
+ if (grafikHasilKepuasan.findMany.data && grafikHasilKepuasan.findMany.data.length > 0) {
+ setChartData(grafikHasilKepuasan.findMany.data);
+ }
+ };
+ fetchData();
+ }, []);
+
+ return (
+
+
+
+
+ Grafik Hasil Kepuasan Masyarakat Terhadap Pelayanan Publik
+ {
+ grafikHasilKepuasan.create.form.label = val.currentTarget.value;
+ }}
+ />
+ {
+ grafikHasilKepuasan.create.form.kepuasan = val.currentTarget.value;
+ }}
+ />
+ {
+ await grafikHasilKepuasan.create.create();
+ await grafikHasilKepuasan.findMany.load();
+ if (grafikHasilKepuasan.findMany.data) {
+ setChartData(grafikHasilKepuasan.findMany.data);
+ }
+ }}
+ >
+ Submit
+
+
+
+
+
+ {/* Chart */}
+
+
+
+ Data Kepuasan Masyarakat
+ {mounted && chartData.length > 0 && (
+
+
+
+
+
+
+
+ )}
+
+
+
+
+
+ );
+}
+
+export default GrafikHasilKepuasan;
diff --git a/src/app/admin/(dashboard)/ppid/ikm-desa-darmasaba/page.tsx b/src/app/admin/(dashboard)/ppid/ikm-desa-darmasaba/page.tsx
index c5444919..dbc9bdb3 100644
--- a/src/app/admin/(dashboard)/ppid/ikm-desa-darmasaba/page.tsx
+++ b/src/app/admin/(dashboard)/ppid/ikm-desa-darmasaba/page.tsx
@@ -1,10 +1,45 @@
+import { Stack, Tabs, TabsList, TabsPanel, TabsTab, Title } from '@mantine/core';
import React from 'react';
+import colors from '@/con/colors';
+import GrafikHasilKepuasan from './_ui/grafik_hasil_kepuasan_masyarakat/page';
+import GrafikBerdasarkanJenisKelamin from './_ui/grafik_berdasarkan_jenis_kelamin_responden/page';
+import GrafikBerdasarkanResponden from './_ui/grafik_berdasarkan_responden/page';
+import GrafikBerdasarakanUmur from './_ui/grafik_berdasarkan_umur/page';
function Page() {
return (
-
- ikm-desa-darmasaba
-
+
+ Indeks Kepuasan Masyarakat (IKM) Desa Darmasaba
+
+
+
+ Grafik Hasil Kepuasan Masyarakat Terhadap Pelayanan Publik
+
+
+ Grafik Berdasarkan Jenis Kelamin Responden
+
+
+ Grafik Berdasarkan Pilihan Responden
+
+
+ Grafik Berdasarkan Umur Responden
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
);
}
diff --git a/src/app/admin/(dashboard)/ppid/permohonan-informasi-publik/page.tsx b/src/app/admin/(dashboard)/ppid/permohonan-informasi-publik/page.tsx
index d6988a3f..020e782f 100644
--- a/src/app/admin/(dashboard)/ppid/permohonan-informasi-publik/page.tsx
+++ b/src/app/admin/(dashboard)/ppid/permohonan-informasi-publik/page.tsx
@@ -1,11 +1,57 @@
-import React from 'react';
+'use client'
+import colors from '@/con/colors';
+import { Box, Paper, Skeleton, Stack, Table, TableTbody, TableTd, TableTh, TableThead, TableTr, Title } from '@mantine/core';
+import { useProxy } from 'valtio/utils';
+import { useShallowEffect } from '@mantine/hooks';
+import statepermohonanInformasiPublikForm from '../../_state/ppid/permohonan_informasi_publik/permohonanInformasiPublik';
function Page() {
+ const permohonanInformasiPublikState = useProxy(statepermohonanInformasiPublikForm)
+ useShallowEffect(() => {
+ permohonanInformasiPublikState.statepermohonanInformasiPublik.findMany.load()
+ }, [])
+ if (!permohonanInformasiPublikState.statepermohonanInformasiPublik.findMany.data) return
+ {Array.from({ length: 10 }).map((v, k) => )}
+
+
return (
-
- permohonan-informasi-publik
-
+
+
+
+ Permohonan Informasi Publik
+
+
+
+
+ No
+ Nama
+ NIK
+ Telepon
+ Email
+ Jenis Informasi
+ Cara Memperoleh Informasi
+ Cara Memperoleh Salinan Informasi
+
+
+
+ {permohonanInformasiPublikState.statepermohonanInformasiPublik.findMany.data?.map((item, index) => (
+
+ {index + 1}
+ {item.name}
+ {item.nik}
+ {item.notelp}
+ {item.email}
+ {item.jenisInformasiDiminta?.name}
+ {item.caraMemperolehInformasi?.name}
+ {item.caraMemperolehSalinanInformasi?.name}
+
+ ))}
+
+
+
+
+
);
}
-export default Page;
+export default Page;
\ No newline at end of file
diff --git a/src/app/admin/(dashboard)/ppid/permohonan-keberatan-informasi-publik/page.tsx b/src/app/admin/(dashboard)/ppid/permohonan-keberatan-informasi-publik/page.tsx
index 92caf14c..a367b20d 100644
--- a/src/app/admin/(dashboard)/ppid/permohonan-keberatan-informasi-publik/page.tsx
+++ b/src/app/admin/(dashboard)/ppid/permohonan-keberatan-informasi-publik/page.tsx
@@ -1,11 +1,49 @@
-import React from 'react';
+'use client'
+import colors from '@/con/colors';
+import { Box, Paper, Skeleton, Stack, Table, TableTbody, TableTd, TableTh, TableThead, TableTr, Title } from '@mantine/core';
+import { useShallowEffect } from '@mantine/hooks';
+import { useProxy } from 'valtio/utils';
+import statePermohonanKeberatan from '../../_state/ppid/permohonan_keberatan_informasi_publik/permohonanKeberatanInformasi';
function Page() {
+ const listState = useProxy(statePermohonanKeberatan)
+ useShallowEffect(() => {
+ listState.findMany.load()
+ }, [])
+
+ if (!listState.findMany.data) return
+ {Array.from({ length: 10 }).map((v, k) => )}
+
return (
-
- permohonan-keberatan-informasi-publik
-
+
+
+
+ Permohonan Keberatan Informasi Publik
+
+
+
+ No
+ Nama
+ Email
+ Telepon
+ Alasan
+
+
+
+ {listState.findMany.data?.map((item, index) => (
+
+ {index + 1}
+ {item.name}
+ {item.email}
+ {item.notelp}
+
+
+ ))}
+
+
+
+
+
);
}
-
export default Page;
diff --git a/src/app/admin/(dashboard)/ppid/profile-ppid/_com/biodata.ts b/src/app/admin/(dashboard)/ppid/profile-ppid/_com/biodata.ts
new file mode 100644
index 00000000..418aeb48
--- /dev/null
+++ b/src/app/admin/(dashboard)/ppid/profile-ppid/_com/biodata.ts
@@ -0,0 +1,10 @@
+const biodata = {
+ id: "1",
+ name: "I.B Surya Prabhawa Manuaba, S.H., M.H.
",
+ biodata: "Biodata ....
",
+ riwayat: "Riwayat Karir ",
+ pengalaman: "Pengalaman Organisasi ",
+ unggulan: "Program Kerja Unggulan ... ",
+}
+
+export default biodata
diff --git a/src/app/admin/(dashboard)/ppid/profile-ppid/biodata/page.tsx b/src/app/admin/(dashboard)/ppid/profile-ppid/biodata/page.tsx
new file mode 100644
index 00000000..bde2d57d
--- /dev/null
+++ b/src/app/admin/(dashboard)/ppid/profile-ppid/biodata/page.tsx
@@ -0,0 +1,76 @@
+'use client'
+import { Box, Group, Text } from '@mantine/core';
+import { useState } from 'react';
+
+import ApiFetch from '@/lib/api-fetch';
+import { Dropzone, MIME_TYPES } from '@mantine/dropzone';
+import { IconPhoto, IconUpload, IconX } from '@tabler/icons-react';
+import { useProxy } from 'valtio/utils';
+import stateProfilePPID from '../../../_state/ppid/profile_ppid/profile_PPID';
+import { PPIDTextEditor } from '../../_com/PPIDTextEditor';
+
+function Biodata() {
+ const biodataState = useProxy(stateProfilePPID)
+ const [loading, setLoading] = useState(false);
+
+ return (
+ Biodata
+ {
+ setLoading(true);
+ for (const file of droppedFiles) {
+ await ApiFetch.api.ppid.profileppid["edit-img"].post({
+ file: file,
+ id: biodataState.findById.data?.id,
+ });
+ }
+
+ setLoading(false);
+ if (biodataState.findById.data?.id) {
+ biodataState.findById.load(biodataState.findById.data.id);
+ }
+ }}
+ accept={[MIME_TYPES.jpeg, MIME_TYPES.png, MIME_TYPES.webp]}
+ loading={loading}
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Drag & drop gambar di sini atau klik untuk pilih file
+
+
+ Maksimal ukuran file 5MB. Format: JPG, PNG, WebP
+
+
+
+
+
+
+
+ {
+ if (biodataState.findById.data) {
+ biodataState.findById.data.biodata = val;
+ }
+ }}
+ initialContent={biodataState.findById.data?.biodata ?? ''}
+ />
+
+
+ );
+}
+
+export default Biodata;
\ No newline at end of file
diff --git a/src/app/admin/(dashboard)/ppid/profile-ppid/listPage.tsx b/src/app/admin/(dashboard)/ppid/profile-ppid/listPage.tsx
new file mode 100644
index 00000000..76120428
--- /dev/null
+++ b/src/app/admin/(dashboard)/ppid/profile-ppid/listPage.tsx
@@ -0,0 +1,65 @@
+import colors from '@/con/colors';
+import { Stack, Skeleton, Paper, Title, Box, Text, Image } from '@mantine/core';
+import { useShallowEffect } from '@mantine/hooks';
+import React from 'react';
+import { useProxy } from 'valtio/utils';
+import stateProfilePPID from '../../_state/ppid/profile_ppid/profile_PPID';
+
+function ProfileList() {
+ const allList = useProxy(stateProfilePPID)
+ useShallowEffect(() => {
+ allList.findById.load("1") // Assuming "1" is your default ID, adjust as needed
+ }, [])
+
+ if (!allList.findById.data) return
+ {Array.from({ length: 10 }).map((v, k) => )}
+
+
+ const dataArray = Array.isArray(allList.findById.data)
+ ? allList.findById.data
+ : [allList.findById.data];
+
+ return (
+
+
+ List Profile PPID
+ {dataArray.map((item) => (
+
+ {item.imageUrl && (
+
+ Preview Gambar:
+
+
+ )}
+
+ Nama
+
+
+
+ Biodata
+
+
+
+ Riwayat
+
+
+
+ Pengalaman
+
+
+
+ Program Kerja Unggulan
+
+
+
+ ))}
+
+
+ )
+}
+
+export default ProfileList;
diff --git a/src/app/admin/(dashboard)/ppid/profile-ppid/page.tsx b/src/app/admin/(dashboard)/ppid/profile-ppid/page.tsx
index 7f8eda91..de1a55a3 100644
--- a/src/app/admin/(dashboard)/ppid/profile-ppid/page.tsx
+++ b/src/app/admin/(dashboard)/ppid/profile-ppid/page.tsx
@@ -1,11 +1,89 @@
-import React from 'react';
+'use client'
+import colors from '@/con/colors';
+import { Box, Button, Group, Paper, SimpleGrid, Stack, Text, TextInput, Title } from '@mantine/core';
+import Biodata from './biodata/page';
+import PengalamanOrganisasi from './pengalaman_organisasi/page';
+import RiwayatKarir from './riwayat_karir/page';
+import ProgramKerjaUnggulan from './program_kerja_unggulan/page';
+import { useProxy } from 'valtio/utils';
+import stateProfilePPID from '../../_state/ppid/profile_ppid/profile_PPID';
+import { useShallowEffect } from '@mantine/hooks';
+import ProfileList from './listPage';
+import { useState } from 'react';
+import { toast } from 'react-toastify';
+
function Page() {
return (
-
- profile-ppid
-
+
+
+
+
+
+
);
}
-export default Page;
+function ProfileCreate() {
+ const [isLoading, setIsLoading] = useState(false)
+ const allState = useProxy(stateProfilePPID)
+
+ // Initialize data if it doesn't exist
+ useShallowEffect(() => {
+ if (!allState.findById.data && isLoading) {
+ allState.findById.initialize()
+ setIsLoading(false)
+ }
+ }, [isLoading])
+
+ const submit = () => {
+ if (
+ allState.findById.data?.name &&
+ allState.findById.data?.biodata &&
+ allState.findById.data?.riwayat &&
+ allState.findById.data?.pengalaman &&
+ allState.findById.data?.unggulan
+ ) {
+ allState.update.save(allState.findById.data)
+ setIsLoading(true)
+ toast.success("success")
+ console.log("[SUBMIT SUCCESS]", JSON.stringify(allState.findById.data, null, 2))
+ allState.findById.initialize()
+ } else {
+ toast.error("error")
+ }
+ }
+
+ return (
+
+
+ Profile PPID
+ Nama Perbekel}
+ placeholder="masukkan nama perbekel"
+ value={allState.findById.data?.name || ''}
+ onChange={(val) => {
+ if (allState.findById.data) {
+ allState.findById.data.name = val.currentTarget.value
+ }
+ }}
+ />
+
+
+
+
+
+
+ Submit
+
+
+
+
+ )
+}
+
+export default Page;
\ No newline at end of file
diff --git a/src/app/admin/(dashboard)/ppid/profile-ppid/pengalaman_organisasi/page.tsx b/src/app/admin/(dashboard)/ppid/profile-ppid/pengalaman_organisasi/page.tsx
new file mode 100644
index 00000000..20be1859
--- /dev/null
+++ b/src/app/admin/(dashboard)/ppid/profile-ppid/pengalaman_organisasi/page.tsx
@@ -0,0 +1,26 @@
+'use client'
+import { Box, Text } from '@mantine/core';
+import React from 'react';
+import { useProxy } from 'valtio/utils';
+import stateProfilePPID from '../../../_state/ppid/profile_ppid/profile_PPID';
+import { PPIDTextEditor } from '../../_com/PPIDTextEditor';
+
+function PengalamanOrganisasi() {
+ const pengalamanOrganisasiState = useProxy(stateProfilePPID)
+ return (
+ Pengalaman Organisasi
+ {
+ if (pengalamanOrganisasiState.findById.data) {
+ pengalamanOrganisasiState.findById.data.pengalaman = val;
+ }
+ }}
+ initialContent={pengalamanOrganisasiState.findById.data?.pengalaman ?? ''}
+ />
+
+ );
+}
+
+export default PengalamanOrganisasi;
diff --git a/src/app/admin/(dashboard)/ppid/profile-ppid/program_kerja_unggulan/page.tsx b/src/app/admin/(dashboard)/ppid/profile-ppid/program_kerja_unggulan/page.tsx
new file mode 100644
index 00000000..c643f51e
--- /dev/null
+++ b/src/app/admin/(dashboard)/ppid/profile-ppid/program_kerja_unggulan/page.tsx
@@ -0,0 +1,26 @@
+'use client'
+import { Box, Text } from '@mantine/core';
+import React from 'react';
+import { useProxy } from 'valtio/utils';
+import stateProfilePPID from '../../../_state/ppid/profile_ppid/profile_PPID';
+import { PPIDTextEditor } from '../../_com/PPIDTextEditor';
+
+function ProgramKerjaUnggulan() {
+ const programKerjaUnggulanState = useProxy(stateProfilePPID)
+ return (
+ Program Kerja Unggulan
+ {
+ if (programKerjaUnggulanState.findById.data) {
+ programKerjaUnggulanState.findById.data.unggulan = val;
+ }
+ }}
+ initialContent={programKerjaUnggulanState.findById.data?.unggulan ?? ''}
+ />
+
+ );
+}
+
+export default ProgramKerjaUnggulan;
diff --git a/src/app/admin/(dashboard)/ppid/profile-ppid/riwayat_karir/page.tsx b/src/app/admin/(dashboard)/ppid/profile-ppid/riwayat_karir/page.tsx
new file mode 100644
index 00000000..f1ecd870
--- /dev/null
+++ b/src/app/admin/(dashboard)/ppid/profile-ppid/riwayat_karir/page.tsx
@@ -0,0 +1,33 @@
+'use client';
+
+import { Box, Text } from '@mantine/core';
+import React from 'react';
+import { useProxy } from 'valtio/utils';
+import dynamic from 'next/dynamic';
+import stateProfilePPID from '../../../_state/ppid/profile_ppid/profile_PPID';
+
+// ini penting
+const PPIDTextEditor = dynamic(() => import('../../_com/PPIDTextEditor').then(mod => mod.PPIDTextEditor), {
+ ssr: false, // disable server side rendering
+});
+function RiwayatKarir() {
+ const riwayatKarirState = useProxy(stateProfilePPID);
+
+ return (
+
+ Riwayat Karir
+ {
+ if (riwayatKarirState.findById.data) {
+ riwayatKarirState.findById.data.riwayat = val;
+ }
+ }}
+ initialContent={riwayatKarirState.findById.data?.riwayat ?? ''}
+ />
+
+ );
+}
+
+export default RiwayatKarir;
diff --git a/src/app/admin/(dashboard)/ppid/visi-misi-ppid/misiPPID/misi-PPID.tsx b/src/app/admin/(dashboard)/ppid/visi-misi-ppid/misiPPID/misi-PPID.tsx
new file mode 100644
index 00000000..a59a5f94
--- /dev/null
+++ b/src/app/admin/(dashboard)/ppid/visi-misi-ppid/misiPPID/misi-PPID.tsx
@@ -0,0 +1,27 @@
+'use client'
+import { Box, Text } from '@mantine/core';
+import { PPIDTextEditor } from '../../_com/PPIDTextEditor';
+
+function MisiPPID({
+ value,
+ onChange,
+ error,
+}: {
+ value: string;
+ onChange: (val: string) => void;
+ error?: string;
+}) {
+ return (
+
+ Misi PPID
+
+ {error && {error} }
+
+ );
+}
+
+export default MisiPPID;
diff --git a/src/app/admin/(dashboard)/ppid/visi-misi-ppid/page.tsx b/src/app/admin/(dashboard)/ppid/visi-misi-ppid/page.tsx
index bdfc7eea..5cbdbbb5 100644
--- a/src/app/admin/(dashboard)/ppid/visi-misi-ppid/page.tsx
+++ b/src/app/admin/(dashboard)/ppid/visi-misi-ppid/page.tsx
@@ -1,10 +1,113 @@
-import React from 'react';
+'use client'
+import colors from '@/con/colors';
+import {
+ Box, Button, Group, Paper, SimpleGrid, Skeleton, Stack, Text, Title
+} from '@mantine/core';
+import { useShallowEffect } from '@mantine/hooks';
+import { useProxy } from 'valtio/utils';
+import { useEffect, useState } from 'react';
+import stateVisiMisiPPID from '../../_state/ppid/visi_misi_ppid/visimisiPPID';
+import VisiPPID from './visiPPID/visi-PPID';
+import MisiPPID from './misiPPID/misi-PPID';
+
+
function Page() {
return (
-
- visi-misi-ppid
-
+
+
+
+
+
+
+ );
+}
+
+function VisiMisiPPIDCreate() {
+ const visiMisi = useProxy(stateVisiMisiPPID);
+ const [draftVisi, setDraftVisi] = useState('');
+ const [draftMisi, setDraftMisi] = useState('');
+
+ useShallowEffect(() => {
+ if (!visiMisi.findById.data) {
+ visiMisi.findById.initialize();
+ }
+ }, []);
+
+ useEffect(() => {
+ if (visiMisi.findById.data) {
+ setDraftVisi(visiMisi.findById.data.visi ?? '');
+ setDraftMisi(visiMisi.findById.data.misi ?? '');
+ }
+ }, [visiMisi.findById.data]);
+
+ const submit = () => {
+ if (visiMisi.findById.data) {
+ // update nilai di state global hanya saat submit
+ visiMisi.findById.data.visi = draftVisi;
+ visiMisi.findById.data.misi = draftMisi;
+ visiMisi.update.save(visiMisi.findById.data);
+ }
+ };
+
+ return (
+
+
+ Visi Misi PPID
+
+
+
+
+ Submit
+
+
+
+
+ );
+}
+
+function VisiMisiPPIDList() {
+ const listVisiMisi = useProxy(stateVisiMisiPPID);
+ useShallowEffect(() => {
+ listVisiMisi.findById.load('1');
+ }, []);
+
+ if (!listVisiMisi.findById.data) {
+ return (
+
+ {Array.from({ length: 10 }).map((_, k) => (
+
+ ))}
+
+ );
+ }
+
+ return (
+
+
+ List Visi Misi PPID
+
+ Visi PPID
+
+
+
+ Misi PPID
+
+
+
+
);
}
diff --git a/src/app/admin/(dashboard)/ppid/visi-misi-ppid/visiPPID/visi-PPID.tsx b/src/app/admin/(dashboard)/ppid/visi-misi-ppid/visiPPID/visi-PPID.tsx
new file mode 100644
index 00000000..15513d3c
--- /dev/null
+++ b/src/app/admin/(dashboard)/ppid/visi-misi-ppid/visiPPID/visi-PPID.tsx
@@ -0,0 +1,27 @@
+'use client'
+import { Box, Text } from '@mantine/core';
+import { PPIDTextEditor } from '../../_com/PPIDTextEditor';
+
+function VisiPPID({
+ value,
+ onChange,
+ error,
+}: {
+ value: string;
+ onChange: (val: string) => void;
+ error?: string;
+}) {
+ return (
+
+ Visi PPID
+
+ {error && {error} }
+
+ );
+}
+
+export default VisiPPID;
diff --git a/src/app/admin/layout.tsx b/src/app/admin/layout.tsx
index 50cc1980..1d535de2 100644
--- a/src/app/admin/layout.tsx
+++ b/src/app/admin/layout.tsx
@@ -1,6 +1,19 @@
'use client'
+
import colors from "@/con/colors";
-import { ActionIcon, AppShell, AppShellHeader, AppShellMain, AppShellNavbar, Burger, Group, Image, NavLink, ScrollArea, Text } from "@mantine/core";
+import {
+ ActionIcon,
+ AppShell,
+ AppShellHeader,
+ AppShellMain,
+ AppShellNavbar,
+ Burger,
+ Group,
+ Image,
+ NavLink,
+ ScrollArea,
+ Text
+} from "@mantine/core";
import { useDisclosure } from "@mantine/hooks";
import { IconChevronLeft, IconChevronRight } from "@tabler/icons-react";
import _ from 'lodash';
@@ -10,75 +23,106 @@ import { navBar } from "./_com/list_PageAdmin";
export default function Layout({ children }: { children: React.ReactNode }) {
const [opened, { toggle }] = useDisclosure();
- const [desktopOpened, { toggle: toggleDesktop }] =
- useDisclosure(true);
+ const [desktopOpened, { toggle: toggleDesktop }] = useDisclosure(true);
+ // Normalisasi semua segmen jadi lowercase
+ const segments = useSelectedLayoutSegments().map(s => _.lowerCase(s));
- const segments = useSelectedLayoutSegments()
return (
- {!desktopOpened && }
-
-
-
+ {!desktopOpened && (
+
+
+
+ )}
+
+
+
- Dashboard Admin
+
+ Dashboard Admin
+
-
-
+
+
{navBar.map((v, k) => {
+ const isParentActive = segments.includes(_.lowerCase(v.name));
+
return (
setActive(k)}
- label={{v.name} }
+ defaultOpened={isParentActive}
+ c={isParentActive ? colors["blue-button"] : "grey"}
+ label={
+
+ {v.name}
+
+ }
>
{v.children.map((child, key) => {
+ const isChildActive = segments.includes(_.lowerCase(child.name));
+
return (
setActive(Number(child.id))}
- label={{child.name} }
+ c={isChildActive ? colors["blue-button"] : "grey"}
+ label={
+
+ {child.name}
+
+ }
/>
- )
+ );
})}
- )
+ );
})}
-
+
+
+
-
- {children}
-
+
+ {children}
);
-}
\ No newline at end of file
+}
diff --git a/src/app/api/[[...slugs]]/_lib/desa/berita/category.ts b/src/app/api/[[...slugs]]/_lib/desa/berita/category.ts
index b7c16687..916e37ea 100644
--- a/src/app/api/[[...slugs]]/_lib/desa/berita/category.ts
+++ b/src/app/api/[[...slugs]]/_lib/desa/berita/category.ts
@@ -1,9 +1,9 @@
import prisma from "@/lib/prisma";
- async function katagoryBeritaFindMany() {
- const data = await prisma.katagoryBerita.findMany();
+ async function kategoriBeritaFindMany() {
+ const data = await prisma.kategoriBerita.findMany();
return { data };
}
-export default katagoryBeritaFindMany
+export default kategoriBeritaFindMany
diff --git a/src/app/api/[[...slugs]]/_lib/desa/berita/create.ts b/src/app/api/[[...slugs]]/_lib/desa/berita/create.ts
index a2c695e7..632634a7 100644
--- a/src/app/api/[[...slugs]]/_lib/desa/berita/create.ts
+++ b/src/app/api/[[...slugs]]/_lib/desa/berita/create.ts
@@ -6,13 +6,14 @@ type FormCreate = Prisma.BeritaGetPayload<{
select: {
judul: true;
deskripsi: true;
- image: true;
content: true;
- katagoryBeritaId: true;
+ kategoriBeritaId: true;
+ imageId: true;
};
}>;
async function beritaCreate(context: Context) {
const body = context.body as FormCreate;
+ console.log(body)
// console.log(body)
@@ -20,9 +21,9 @@ async function beritaCreate(context: Context) {
data: {
content: body.content,
deskripsi: body.deskripsi,
- image: body.image,
+ imageId: body.imageId,
judul: body.judul,
- katagoryBeritaId: body.katagoryBeritaId,
+ kategoriBeritaId: body.kategoriBeritaId,
},
});
diff --git a/src/app/api/[[...slugs]]/_lib/desa/berita/del.ts b/src/app/api/[[...slugs]]/_lib/desa/berita/del.ts
new file mode 100644
index 00000000..bb5df949
--- /dev/null
+++ b/src/app/api/[[...slugs]]/_lib/desa/berita/del.ts
@@ -0,0 +1,55 @@
+import prisma from "@/lib/prisma";
+import { Context } from "elysia";
+import fs from "fs/promises";
+import path from "path";
+
+const beritaDelete = async (context: Context) => {
+ const id = context.params?.id as string;
+
+ if (!id) {
+ return {
+ status: 400,
+ body: "ID tidak diberikan",
+ };
+ }
+
+ const berita = await prisma.berita.findUnique({
+ where: { id },
+ include: {
+ image: true,
+ kategoriBerita: true, // pastikan relasi image sudah ada di prisma schema
+ },
+ });
+
+ if (!berita) {
+ return {
+ status: 404,
+ body: "Berita tidak ditemukan",
+ };
+ }
+
+ // Hapus file gambar dari filesystem jika ada
+ if (berita.image) {
+ try {
+ const filePath = path.join(berita.image.path, berita.image.name);
+ await fs.unlink(filePath);
+ await prisma.fileStorage.delete({
+ where: { id: berita.image.id },
+ });
+ } catch (err) {
+ console.error("Gagal hapus file image:", err);
+ }
+ }
+
+ // Hapus berita dari DB
+ await prisma.berita.delete({
+ where: { id },
+ });
+
+ return {
+ success: true,
+ message: "Berita dan file terkait berhasil dihapus",
+ };
+};
+
+export default beritaDelete;
diff --git a/src/app/api/[[...slugs]]/_lib/desa/berita/find-many.ts b/src/app/api/[[...slugs]]/_lib/desa/berita/find-many.ts
index c745b28c..5d8fb601 100644
--- a/src/app/api/[[...slugs]]/_lib/desa/berita/find-many.ts
+++ b/src/app/api/[[...slugs]]/_lib/desa/berita/find-many.ts
@@ -1,8 +1,27 @@
import prisma from "@/lib/prisma";
-export default async function beritaFindMany() {
- const res = await prisma.berita.findMany();
- return {
- data: res,
- };
+async function beritaFindMany() {
+ try {
+ const data = await prisma.berita.findMany({
+ where: { isActive: true },
+ include: {
+ image: true,
+ kategoriBerita: true,
+ },
+ });
+
+ return {
+ success: true,
+ message: "Success fetch berita",
+ data,
+ };
+ } catch (e) {
+ console.error("Find many error:", e);
+ return {
+ success: false,
+ message: "Failed fetch berita",
+ };
+ }
}
+
+export default beritaFindMany;
diff --git a/src/app/api/[[...slugs]]/_lib/desa/berita/index.ts b/src/app/api/[[...slugs]]/_lib/desa/berita/index.ts
index 521b513c..dace0724 100644
--- a/src/app/api/[[...slugs]]/_lib/desa/berita/index.ts
+++ b/src/app/api/[[...slugs]]/_lib/desa/berita/index.ts
@@ -1,18 +1,30 @@
import Elysia, { t } from "elysia";
-import katagoryBeritaFindMany from "./category";
+import kategoriBeritaFindMany from "./category";
import beritaFindMany from "./find-many";
import beritaCreate from "./create";
+import beritaDelete from "./del";
+import beritaUpdate from "./updt";
const Berita = new Elysia({ prefix: "/berita", tags: ["Desa/Berita"] })
- .get("/category/find-many", katagoryBeritaFindMany)
+ .get("/category/find-many", kategoriBeritaFindMany)
.get("/find-many", beritaFindMany)
.post("/create", beritaCreate, {
body: t.Object({
judul: t.String(),
deskripsi: t.String(),
- image: t.String(),
+ imageId: t.String(),
content: t.String(),
- katagoryBeritaId: t.Union([t.String(), t.Null()]),
+ kategoriBeritaId: t.Union([t.String(), t.Null()]),
+ }),
+ })
+ .delete("/delete/:id", beritaDelete)
+ .put("/update/:id", beritaUpdate, {
+ body: t.Object({
+ judul: t.String(),
+ deskripsi: t.String(),
+ imageId: t.String(),
+ content: t.String(),
+ kategoriBeritaId: t.Union([t.String(), t.Null()]),
}),
});
diff --git a/src/app/api/[[...slugs]]/_lib/desa/berita/updt.ts b/src/app/api/[[...slugs]]/_lib/desa/berita/updt.ts
new file mode 100644
index 00000000..1d33a88b
--- /dev/null
+++ b/src/app/api/[[...slugs]]/_lib/desa/berita/updt.ts
@@ -0,0 +1,153 @@
+import prisma from "@/lib/prisma";
+import { Context } from "elysia";
+import { Prisma } from "@prisma/client";
+import fs from "fs/promises";
+import path from "path";
+
+type FormUpdate = Prisma.BeritaGetPayload<{
+ select: {
+ id: true;
+ judul: true;
+ deskripsi: true;
+ content: true;
+ kategoriBeritaId: true;
+ imageId: true;
+ };
+}>;
+
+// async function beritaUpdate(context: Context) {
+// const body = (await context.body) as FormUpdate;
+
+// const {
+// id,
+// judul,
+// deskripsi,
+// content,
+// kategoriBeritaId,
+// imageId,
+// } = body;
+
+// if (!id) {
+// return {
+// status: 400,
+// body: "ID tidak boleh kosong",
+// };
+// }
+
+// const existing = await prisma.berita.findUnique({
+// where: { id },
+// include: {
+// image: true,
+// },
+// });
+
+// if (!existing) {
+// return {
+// status: 404,
+// body: "Berita tidak ditemukan",
+// };
+// }
+
+// // Cek jika imageId diubah
+// if (existing.imageId && existing.imageId !== imageId) {
+// const oldImage = existing.image;
+// if (oldImage) {
+// try {
+// const filePath = path.join(oldImage.path, oldImage.name);
+// await fs.unlink(filePath); // hapus file dari filesystem
+// await prisma.fileStorage.delete({
+// where: { id: oldImage.id }, // hapus record dari DB
+// });
+// } catch (err) {
+// console.error("Gagal hapus gambar lama:", err);
+// }
+// }
+// }
+
+// const updated = await prisma.berita.update({
+// where: { id },
+// data: {
+// judul,
+// deskripsi,
+// content,
+// kategoriBeritaId,
+// imageId,
+// },
+// });
+
+// return {
+// success: true,
+// message: "Berita berhasil diupdate (gambar lama juga dihapus jika ada)",
+// data: updated,
+// };
+// }
+
+// export default beritaUpdate;
+
+
+async function beritaUpdate(context: Context) {
+ const id = context.params.id as string; // ambil dari URL
+ const body = (await context.body) as Omit;
+
+ const {
+ judul,
+ deskripsi,
+ content,
+ kategoriBeritaId,
+ imageId,
+ } = body;
+
+ if (!id) {
+ return {
+ status: 400,
+ body: "ID tidak boleh kosong",
+ };
+ }
+
+ const existing = await prisma.berita.findUnique({
+ where: { id },
+ include: {
+ image: true,
+ },
+ });
+
+ if (!existing) {
+ return {
+ status: 404,
+ body: "Berita tidak ditemukan",
+ };
+ }
+
+ if (existing.imageId && existing.imageId !== imageId) {
+ const oldImage = existing.image;
+ if (oldImage) {
+ try {
+ const filePath = path.join(oldImage.path, oldImage.name);
+ await fs.unlink(filePath);
+ await prisma.fileStorage.delete({
+ where: { id: oldImage.id },
+ });
+ } catch (err) {
+ console.error("Gagal hapus gambar lama:", err);
+ }
+ }
+ }
+
+ const updated = await prisma.berita.update({
+ where: { id },
+ data: {
+ judul,
+ deskripsi,
+ content,
+ kategoriBeritaId,
+ imageId,
+ },
+ });
+
+ return {
+ success: true,
+ message: "Berita berhasil diupdate",
+ data: updated,
+ };
+ }
+ export default beritaUpdate;
diff --git a/src/app/api/[[...slugs]]/_lib/desa/index.ts b/src/app/api/[[...slugs]]/_lib/desa/index.ts
index 6a57017e..18a05d7d 100644
--- a/src/app/api/[[...slugs]]/_lib/desa/index.ts
+++ b/src/app/api/[[...slugs]]/_lib/desa/index.ts
@@ -1,9 +1,12 @@
import Elysia from "elysia";
import Berita from "./berita";
import Pengumuman from "./pengumuman";
+import ProfileDesa from "./profile/profile_desa";
+
const Desa = new Elysia({ prefix: "/api/desa", tags: ["Desa"] })
.use(Berita)
.use(Pengumuman)
+ .use(ProfileDesa)
export default Desa;
diff --git a/src/app/api/[[...slugs]]/_lib/desa/profile/profilePerbekel/update.ts b/src/app/api/[[...slugs]]/_lib/desa/profile/profilePerbekel/update.ts
new file mode 100644
index 00000000..7b81bfda
--- /dev/null
+++ b/src/app/api/[[...slugs]]/_lib/desa/profile/profilePerbekel/update.ts
@@ -0,0 +1,33 @@
+import prisma from "@/lib/prisma";
+import { Prisma } from "@prisma/client";
+import { Context } from "elysia";
+
+type FormCreate = Prisma.ProfilPerbekelGetPayload<{
+ select: {
+ id: true;
+ biodata: true;
+ pengalaman: true;
+ pengalamanOrganisasi: true;
+ programUnggulan: true;
+ }
+}>
+export default async function profilePerbekelUpdate(context: Context) {
+ const body = context.body as FormCreate;
+
+ await prisma.profilPerbekel.update({
+ where: {
+ id: body.id
+ },
+ data: {
+ biodata: body.biodata,
+ pengalaman: body.pengalaman,
+ pengalamanOrganisasi: body.pengalamanOrganisasi,
+ programUnggulan: body.programUnggulan,
+ }
+ })
+
+ return {
+ success: true,
+ message: "Profile Perbekel Berhasil Diupdate",
+ }
+}
\ No newline at end of file
diff --git a/src/app/api/[[...slugs]]/_lib/desa/profile/profile_desa/find-by-id.ts b/src/app/api/[[...slugs]]/_lib/desa/profile/profile_desa/find-by-id.ts
new file mode 100644
index 00000000..6443567e
--- /dev/null
+++ b/src/app/api/[[...slugs]]/_lib/desa/profile/profile_desa/find-by-id.ts
@@ -0,0 +1,33 @@
+import prisma from "@/lib/prisma";
+import { Context } from "elysia";
+
+export default async function profileDesaFindById(context: Context) {
+ try {
+ const id = context?.params?.slugs?.[0];
+
+ // If no ID provided, get the first profile
+ if (!id) {
+ const data = await prisma.profileDesa.findFirst();
+ return {
+ success: true,
+ data,
+ };
+ }
+
+ const data = await prisma.profileDesa.findUniqueOrThrow({
+ where: { id },
+ });
+
+ return {
+ success: true,
+ data,
+ };
+ } catch (error) {
+ console.error("Error fetching profileDesa:", error);
+
+ return {
+ success: false,
+ message: error instanceof Error ? error.message : "Unknown error",
+ };
+ }
+}
diff --git a/src/app/api/[[...slugs]]/_lib/desa/profile/profile_desa/index.ts b/src/app/api/[[...slugs]]/_lib/desa/profile/profile_desa/index.ts
new file mode 100644
index 00000000..26e2e225
--- /dev/null
+++ b/src/app/api/[[...slugs]]/_lib/desa/profile/profile_desa/index.ts
@@ -0,0 +1,51 @@
+import Elysia, { t } from "elysia";
+import lambangDesaUpdate from "./lambangDesa/update";
+import maskotDesaUpdate from "./maskotDesa/update";
+import profilePerbekelUpdate from "../profilePerbekel/update";
+import sejarahDesaUpdate from "./sejarah/update";
+import visimisiDesaUpdate from "./visimisiDesa/update";
+import profileDesaFindById from "./find-by-id";
+
+const ProfileDesa = new Elysia({
+ prefix: "/profile",
+ tags: ["Desa/Profile"]
+})
+.get("/find-by-id", profileDesaFindById)
+.post("/profilePerbekel/update", profilePerbekelUpdate, {
+ body: t.Object({
+ id: t.String(),
+ biodata: t.String(),
+ pengalaman: t.String(),
+ pengalamanOrganisasi: t.String(),
+ programUnggulan: t.String(),
+ })
+})
+.post("/visimisiDesa/update", visimisiDesaUpdate, {
+ body: t.Object({
+ id: t.String(),
+ visi: t.String(),
+ misi: t.String(),
+ })
+})
+.post("/sejarah/update", sejarahDesaUpdate, {
+ body: t.Object({
+ id: t.String(),
+ sejarah: t.String(),
+ })
+})
+.post("/lambangDesa/update", lambangDesaUpdate, {
+ body: t.Object({
+ id: t.String(),
+ lambang: t.String(),
+ })
+})
+.post("/maskotDesa/update", maskotDesaUpdate, {
+ body: t.Object({
+ id: t.String(),
+ maskot: t.String(),
+ })
+})
+
+
+
+export default ProfileDesa
diff --git a/src/app/api/[[...slugs]]/_lib/desa/profile/profile_desa/lambangDesa/update.ts b/src/app/api/[[...slugs]]/_lib/desa/profile/profile_desa/lambangDesa/update.ts
new file mode 100644
index 00000000..34f1c992
--- /dev/null
+++ b/src/app/api/[[...slugs]]/_lib/desa/profile/profile_desa/lambangDesa/update.ts
@@ -0,0 +1,28 @@
+import prisma from "@/lib/prisma";
+import { Prisma } from "@prisma/client";
+import { Context } from "elysia";
+
+type FormCreate = Prisma.ProfileDesaGetPayload<{
+ select: {
+ id: true;
+ lambang: true;
+ }
+}>
+
+export default async function lambangDesaUpdate(context: Context) {
+ const body = context.body as FormCreate;
+
+ await prisma.profileDesa.update({
+ where: {
+ id: body.id
+ },
+ data: {
+ lambang: body.lambang,
+ }
+ })
+
+ return {
+ success: true,
+ message: "Profile Desa Berhasil Diupdate",
+ }
+}
\ No newline at end of file
diff --git a/src/app/api/[[...slugs]]/_lib/desa/profile/profile_desa/maskotDesa/update.ts b/src/app/api/[[...slugs]]/_lib/desa/profile/profile_desa/maskotDesa/update.ts
new file mode 100644
index 00000000..a94ff33c
--- /dev/null
+++ b/src/app/api/[[...slugs]]/_lib/desa/profile/profile_desa/maskotDesa/update.ts
@@ -0,0 +1,29 @@
+import prisma from "@/lib/prisma";
+import { Prisma } from "@prisma/client";
+import { Context } from "elysia";
+
+type FormCreate = Prisma.ProfileDesaGetPayload<{
+ select: {
+ id: true;
+ maskot: true;
+ }
+}>
+
+export default async function maskotDesaUpdate(context: Context) {
+ const body = context.body as FormCreate;
+
+ await prisma.profileDesa.update({
+ where: {
+ id: body.id
+ },
+ data: {
+ maskot: body.maskot,
+ }
+ })
+
+ return {
+ success: true,
+ message: "Profile Desa Berhasil Diupdate",
+ }
+}
+
\ No newline at end of file
diff --git a/src/app/api/[[...slugs]]/_lib/desa/profile/profile_desa/sejarah/update.ts b/src/app/api/[[...slugs]]/_lib/desa/profile/profile_desa/sejarah/update.ts
new file mode 100644
index 00000000..316ebc6f
--- /dev/null
+++ b/src/app/api/[[...slugs]]/_lib/desa/profile/profile_desa/sejarah/update.ts
@@ -0,0 +1,29 @@
+import prisma from "@/lib/prisma";
+import { Prisma } from "@prisma/client";
+import { Context } from "elysia";
+
+type FormCreate = Prisma.ProfileDesaGetPayload<{
+ select: {
+ id: true;
+ sejarah: true;
+ }
+}>
+
+export default async function sejarahDesaUpdate(context: Context) {
+ const body = context.body as FormCreate;
+
+ await prisma.profileDesa.update({
+ where: {
+ id: body.id
+ },
+ data: {
+ sejarah: body.sejarah,
+ }
+ })
+
+ return {
+ success: true,
+ message: "Profile Desa Berhasil Diupdate",
+ }
+}
+
\ No newline at end of file
diff --git a/src/app/api/[[...slugs]]/_lib/desa/profile/profile_desa/visimisiDesa/update.ts b/src/app/api/[[...slugs]]/_lib/desa/profile/profile_desa/visimisiDesa/update.ts
new file mode 100644
index 00000000..a7dedf4d
--- /dev/null
+++ b/src/app/api/[[...slugs]]/_lib/desa/profile/profile_desa/visimisiDesa/update.ts
@@ -0,0 +1,29 @@
+import prisma from "@/lib/prisma";
+import { Prisma } from "@prisma/client";
+import { Context } from "elysia";
+
+type FormCreate = Prisma.ProfileDesaGetPayload<{
+ select: {
+ id: true;
+ visi: true;
+ misi: true;
+ }
+}>
+export default async function visimisiDesaUpdate(context: Context) {
+ const body = context.body as FormCreate;
+
+ await prisma.profileDesa.update({
+ where: {
+ id: body.id
+ },
+ data: {
+ visi: body.visi,
+ misi: body.misi,
+ }
+ })
+
+ return {
+ success: true,
+ message: "Profile Desa Berhasil Diupdate",
+ }
+}
diff --git a/src/app/api/[[...slugs]]/_lib/fileStorage/_lib/create.ts b/src/app/api/[[...slugs]]/_lib/fileStorage/_lib/create.ts
new file mode 100644
index 00000000..b9397d00
--- /dev/null
+++ b/src/app/api/[[...slugs]]/_lib/fileStorage/_lib/create.ts
@@ -0,0 +1,64 @@
+import prisma from "@/lib/prisma";
+import { Context } from "elysia";
+import fs from "fs/promises";
+import path from "path";
+import { nanoid } from "nanoid";
+
+const UPLOAD_DIR = process.env.WIBU_UPLOAD_DIR;
+
+const fileStorageCreate = async (context: Context) => {
+ const body = (await context.body) as {
+ name: string;
+ file: File;
+ };
+ const file = body.file;
+ const name = body.name;
+
+ if (!file) {
+ return {
+ status: 400,
+ body: "No file uploaded",
+ };
+ }
+
+ if (!name) {
+ return {
+ status: 400,
+ body: "No name provided",
+ };
+ }
+
+ if (!UPLOAD_DIR) {
+ return {
+ status: 500,
+ body: "UPLOAD_DIR is not defined",
+ };
+ }
+ const pathName = "desa/ppid/profile-ppid";
+ const rootPath = path.join(UPLOAD_DIR, pathName);
+ await fs.mkdir(rootPath, { recursive: true });
+
+ const ext = file.name.split(".").pop();
+ const newName = nanoid() + "." + ext;
+
+ const data = await prisma.fileStorage.create({
+ data: {
+ name: newName,
+ realName: file.name, // Add the original file name as realName
+ path: rootPath,
+ mimeType: file.type,
+ link: `/api/fileStorage/findUnique/${newName}`,
+ },
+ });
+
+ await fs.writeFile(
+ path.join(rootPath, newName),
+ Buffer.from(await file.arrayBuffer())
+ );
+
+ return {
+ data,
+ };
+};
+
+export default fileStorageCreate;
\ No newline at end of file
diff --git a/src/app/api/[[...slugs]]/_lib/fileStorage/_lib/del.ts b/src/app/api/[[...slugs]]/_lib/fileStorage/_lib/del.ts
new file mode 100644
index 00000000..65d1469a
--- /dev/null
+++ b/src/app/api/[[...slugs]]/_lib/fileStorage/_lib/del.ts
@@ -0,0 +1,60 @@
+import prisma from "@/lib/prisma";
+import { Context } from "elysia";
+import fs from "fs/promises";
+import path from "path";
+
+const UPLOAD_DIR = process.env.WIBU_UPLOAD_DIR;
+
+const fileStorageDelete = async (context: Context) => {
+ const { params } = context;
+
+ const id = params?.id as string;
+
+ if (!id) {
+ return {
+ status: 400,
+ body: "ID file tidak ditemukan",
+ };
+ }
+
+ if (!UPLOAD_DIR) {
+ return {
+ status: 500,
+ body: "UPLOAD_DIR belum dikonfigurasi",
+ };
+ }
+
+ // Cek file dari database
+ const file = await prisma.fileStorage.findUnique({
+ where: { id },
+ });
+
+ if (!file) {
+ return {
+ status: 404,
+ body: "File tidak ditemukan di database",
+ };
+ }
+
+ const filePath = path.join(file.path, file.name);
+
+ try {
+ // Hapus file dari filesystem
+ await fs.unlink(filePath);
+ } catch (err) {
+ console.error("Gagal hapus file:", err);
+ // Tetap lanjutkan hapus dari database meskipun file fisik tidak ditemukan
+ }
+
+ // Hapus dari database
+ await prisma.fileStorage.delete({
+ where: { id },
+ });
+
+ return {
+ message: "File berhasil dihapus",
+ deletedId: id,
+ };
+};
+
+export default fileStorageDelete;
diff --git a/src/app/api/[[...slugs]]/_lib/fileStorage/_lib/findMany.ts b/src/app/api/[[...slugs]]/_lib/fileStorage/_lib/findMany.ts
new file mode 100644
index 00000000..ec77d0d8
--- /dev/null
+++ b/src/app/api/[[...slugs]]/_lib/fileStorage/_lib/findMany.ts
@@ -0,0 +1,6 @@
+import prisma from "@/lib/prisma";
+
+export const fileStorageFindMany = async () => {
+ const data = await prisma.fileStorage.findMany();
+ return data;
+};
diff --git a/src/app/api/[[...slugs]]/_lib/fileStorage/_lib/findUniq.ts b/src/app/api/[[...slugs]]/_lib/fileStorage/_lib/findUniq.ts
new file mode 100644
index 00000000..4969e9de
--- /dev/null
+++ b/src/app/api/[[...slugs]]/_lib/fileStorage/_lib/findUniq.ts
@@ -0,0 +1,34 @@
+import prisma from "@/lib/prisma";
+import { Context } from "elysia";
+import fs from "fs/promises";
+import path from "path";
+
+const fileStorageFindUnique = async (context: Context) => {
+ const { name } = context.params;
+
+ const data = await prisma.fileStorage.findUnique({
+ where: {
+ name,
+ },
+ });
+
+ if (!data) {
+ context.set.status = "No Content";
+ return {
+ status: 404,
+ message: "File not found",
+ };
+ }
+
+ console.log(data);
+
+ const file = await fs.readFile(path.join(data.path, data.name));
+ context.set.headers = {
+ "Content-Type": data.mimeType,
+ "Content-Length": file.length,
+ };
+
+ return file;
+};
+
+export default fileStorageFindUnique;
diff --git a/src/app/api/[[...slugs]]/_lib/fileStorage/index.ts b/src/app/api/[[...slugs]]/_lib/fileStorage/index.ts
new file mode 100644
index 00000000..45adedf6
--- /dev/null
+++ b/src/app/api/[[...slugs]]/_lib/fileStorage/index.ts
@@ -0,0 +1,21 @@
+import Elysia, { t } from "elysia";
+import fileStorageCreate from "./_lib/create";
+import fileStorageFindUnique from "./_lib/findUniq";
+import { fileStorageFindMany } from "./_lib/findMany";
+import fileStorageDelete from "./_lib/del";
+
+const FileStorage = new Elysia({
+ prefix: "/api/fileStorage",
+ tags: ["FileStorage"],
+})
+ .post("/create", fileStorageCreate, {
+ body: t.Object({
+ name: t.String(),
+ file: t.File(),
+ }),
+ })
+ .get("/findUnique/:name", fileStorageFindUnique)
+ .get("/findMany", fileStorageFindMany)
+ .delete("/delete/:id", fileStorageDelete);
+
+export default FileStorage;
diff --git a/src/app/api/[[...slugs]]/_lib/kesehatan/data_kesehatan_warga/artikel_kesehatan/doctor_sign/create.ts b/src/app/api/[[...slugs]]/_lib/kesehatan/data_kesehatan_warga/artikel_kesehatan/doctor_sign/create.ts
new file mode 100644
index 00000000..7e5200e8
--- /dev/null
+++ b/src/app/api/[[...slugs]]/_lib/kesehatan/data_kesehatan_warga/artikel_kesehatan/doctor_sign/create.ts
@@ -0,0 +1,26 @@
+import prisma from "@/lib/prisma";
+import { Prisma } from "@prisma/client";
+import { Context } from "elysia";
+
+type FormCreate = Prisma.DoctorSignGetPayload<{
+ select: {
+ content: true;
+ }
+}>
+
+export default async function doctorSignCreate(context: Context) {
+ const body = context.body as FormCreate;
+
+ await prisma.doctorSign.create({
+ data: {
+ content: body.content,
+ },
+ });
+ return {
+ success: true,
+ message: "Success create doctor sign",
+ data: {
+ ...body,
+ },
+ };
+}
\ No newline at end of file
diff --git a/src/app/api/[[...slugs]]/_lib/kesehatan/data_kesehatan_warga/artikel_kesehatan/doctor_sign/find-many.ts b/src/app/api/[[...slugs]]/_lib/kesehatan/data_kesehatan_warga/artikel_kesehatan/doctor_sign/find-many.ts
new file mode 100644
index 00000000..77668040
--- /dev/null
+++ b/src/app/api/[[...slugs]]/_lib/kesehatan/data_kesehatan_warga/artikel_kesehatan/doctor_sign/find-many.ts
@@ -0,0 +1,10 @@
+import prisma from "@/lib/prisma";
+
+export default async function doctorSignFindMany() {
+ const data = await prisma.doctorSign.findMany();
+ return {
+ success: true,
+ message: "Success get doctor sign",
+ data,
+ };
+}
\ No newline at end of file
diff --git a/src/app/api/[[...slugs]]/_lib/kesehatan/data_kesehatan_warga/artikel_kesehatan/doctor_sign/index.ts b/src/app/api/[[...slugs]]/_lib/kesehatan/data_kesehatan_warga/artikel_kesehatan/doctor_sign/index.ts
new file mode 100644
index 00000000..ed52f49f
--- /dev/null
+++ b/src/app/api/[[...slugs]]/_lib/kesehatan/data_kesehatan_warga/artikel_kesehatan/doctor_sign/index.ts
@@ -0,0 +1,15 @@
+import Elysia, { t } from "elysia"
+import doctorSignCreate from "./create"
+import doctorSignFindMany from "./find-many"
+
+const DoctorSign = new Elysia({
+ prefix: "/doctor_sign",
+ tags: ["Data Kesehatan/Artikel Kesehatan/Doctor Sign"],
+})
+ .get("/find-many", doctorSignFindMany)
+ .post("/create", doctorSignCreate, {
+ body: t.Object({
+ content: t.String(),
+ }),
+ })
+export default DoctorSign
diff --git a/src/app/api/[[...slugs]]/_lib/kesehatan/data_kesehatan_warga/artikel_kesehatan/first_aid/create.ts b/src/app/api/[[...slugs]]/_lib/kesehatan/data_kesehatan_warga/artikel_kesehatan/first_aid/create.ts
new file mode 100644
index 00000000..62c6ba4d
--- /dev/null
+++ b/src/app/api/[[...slugs]]/_lib/kesehatan/data_kesehatan_warga/artikel_kesehatan/first_aid/create.ts
@@ -0,0 +1,27 @@
+import prisma from "@/lib/prisma";
+import { Prisma } from "@prisma/client";
+import { Context } from "elysia";
+
+type FormCreate = Prisma.FirstAidGetPayload<{
+ select: {
+ title: true;
+ content: true;
+ }
+}>
+export default async function firstAidCreate(context: Context) {
+ const body = context.body as FormCreate;
+
+ await prisma.firstAid.create({
+ data: {
+ title: body.title,
+ content: body.content,
+ },
+ });
+ return {
+ success: true,
+ message: "Success create first aid",
+ data: {
+ ...body,
+ },
+ };
+}
\ No newline at end of file
diff --git a/src/app/api/[[...slugs]]/_lib/kesehatan/data_kesehatan_warga/artikel_kesehatan/first_aid/find-many.ts b/src/app/api/[[...slugs]]/_lib/kesehatan/data_kesehatan_warga/artikel_kesehatan/first_aid/find-many.ts
new file mode 100644
index 00000000..a2a07805
--- /dev/null
+++ b/src/app/api/[[...slugs]]/_lib/kesehatan/data_kesehatan_warga/artikel_kesehatan/first_aid/find-many.ts
@@ -0,0 +1,8 @@
+import prisma from "@/lib/prisma"
+
+export default async function firstAidFindMany() {
+ const res = await prisma.firstAid.findMany()
+ return {
+ data: res
+ }
+}
\ No newline at end of file
diff --git a/src/app/api/[[...slugs]]/_lib/kesehatan/data_kesehatan_warga/artikel_kesehatan/first_aid/index.ts b/src/app/api/[[...slugs]]/_lib/kesehatan/data_kesehatan_warga/artikel_kesehatan/first_aid/index.ts
new file mode 100644
index 00000000..e677c3c6
--- /dev/null
+++ b/src/app/api/[[...slugs]]/_lib/kesehatan/data_kesehatan_warga/artikel_kesehatan/first_aid/index.ts
@@ -0,0 +1,16 @@
+import Elysia, { t } from "elysia"
+import firstAidCreate from "./create"
+import firstAidFindMany from "./find-many"
+
+const FirstAid = new Elysia({
+ prefix: "/firstaid",
+ tags: ["Data Kesehatan/Artikel Kesehatan/First Aid"]
+})
+ .get("/find-many", firstAidFindMany)
+ .post("/create", firstAidCreate, {
+ body: t.Object({
+ title: t.String(),
+ content: t.String(),
+ }),
+ })
+export default FirstAid
diff --git a/src/app/api/[[...slugs]]/_lib/kesehatan/data_kesehatan_warga/artikel_kesehatan/introduction/create.ts b/src/app/api/[[...slugs]]/_lib/kesehatan/data_kesehatan_warga/artikel_kesehatan/introduction/create.ts
new file mode 100644
index 00000000..68b26645
--- /dev/null
+++ b/src/app/api/[[...slugs]]/_lib/kesehatan/data_kesehatan_warga/artikel_kesehatan/introduction/create.ts
@@ -0,0 +1,26 @@
+import prisma from "@/lib/prisma";
+import { Prisma } from "@prisma/client";
+import { Context } from "elysia";
+
+type FormCreate = Prisma.IntroductionGetPayload<{
+ select: {
+ content: true;
+ };
+}>;
+
+export default async function introductionCreate(context: Context) {
+ const body = context.body as FormCreate;
+
+ await prisma.introduction.create({
+ data: {
+ content: body.content,
+ },
+ });
+ return {
+ success: true,
+ message: "Success create introduction",
+ data: {
+ ...body,
+ },
+ };
+}
\ No newline at end of file
diff --git a/src/app/api/[[...slugs]]/_lib/kesehatan/data_kesehatan_warga/artikel_kesehatan/introduction/find-many.ts b/src/app/api/[[...slugs]]/_lib/kesehatan/data_kesehatan_warga/artikel_kesehatan/introduction/find-many.ts
new file mode 100644
index 00000000..6339bc3c
--- /dev/null
+++ b/src/app/api/[[...slugs]]/_lib/kesehatan/data_kesehatan_warga/artikel_kesehatan/introduction/find-many.ts
@@ -0,0 +1,8 @@
+import prisma from "@/lib/prisma";
+
+export default async function introductionFindMany() {
+ const res = await prisma.introduction.findMany();
+ return {
+ data: res,
+ };
+}
\ No newline at end of file
diff --git a/src/app/api/[[...slugs]]/_lib/kesehatan/data_kesehatan_warga/artikel_kesehatan/introduction/index.ts b/src/app/api/[[...slugs]]/_lib/kesehatan/data_kesehatan_warga/artikel_kesehatan/introduction/index.ts
new file mode 100644
index 00000000..babdd1a2
--- /dev/null
+++ b/src/app/api/[[...slugs]]/_lib/kesehatan/data_kesehatan_warga/artikel_kesehatan/introduction/index.ts
@@ -0,0 +1,16 @@
+import Elysia, { t } from "elysia";
+import introductionCreate from "./create";
+import introductionFindMany from "./find-many";
+
+const Introduction = new Elysia({
+ prefix: "/introduction",
+ tags: ["Data Kesehatan/Artikel Kesehatan/Introduction"]
+})
+ .get("/find-many", introductionFindMany)
+ .post("/create", introductionCreate, {
+ body: t.Object({
+ content: t.String(),
+ }),
+ })
+
+export default Introduction;
\ No newline at end of file
diff --git a/src/app/api/[[...slugs]]/_lib/kesehatan/data_kesehatan_warga/artikel_kesehatan/myth_vs_fact/create.ts b/src/app/api/[[...slugs]]/_lib/kesehatan/data_kesehatan_warga/artikel_kesehatan/myth_vs_fact/create.ts
new file mode 100644
index 00000000..c394c660
--- /dev/null
+++ b/src/app/api/[[...slugs]]/_lib/kesehatan/data_kesehatan_warga/artikel_kesehatan/myth_vs_fact/create.ts
@@ -0,0 +1,30 @@
+import prisma from "@/lib/prisma";
+import { Context } from "elysia";
+import { Prisma } from "@prisma/client";
+
+type FormCreate = Prisma.MythVsFactGetPayload<{
+ select: {
+ title: true;
+ mitos: true;
+ fakta: true;
+ }
+}>
+
+export default async function mythVsFactCreate(context: Context) {
+ const body = context.body as FormCreate;
+
+ await prisma.mythVsFact.create({
+ data: {
+ title: body.title,
+ mitos: body.mitos,
+ fakta: body.fakta,
+ },
+ });
+ return {
+ success: true,
+ message: "Success create myth vs fact",
+ data: {
+ ...body,
+ },
+ };
+}
\ No newline at end of file
diff --git a/src/app/api/[[...slugs]]/_lib/kesehatan/data_kesehatan_warga/artikel_kesehatan/myth_vs_fact/find-many.ts b/src/app/api/[[...slugs]]/_lib/kesehatan/data_kesehatan_warga/artikel_kesehatan/myth_vs_fact/find-many.ts
new file mode 100644
index 00000000..65123770
--- /dev/null
+++ b/src/app/api/[[...slugs]]/_lib/kesehatan/data_kesehatan_warga/artikel_kesehatan/myth_vs_fact/find-many.ts
@@ -0,0 +1,10 @@
+import prisma from "@/lib/prisma";
+
+export default async function mythVsFactFindMany() {
+ const mythVsFacts = await prisma.mythVsFact.findMany();
+ return {
+ success: true,
+ message: "Success get myth vs fact",
+ data: mythVsFacts,
+ };
+}
\ No newline at end of file
diff --git a/src/app/api/[[...slugs]]/_lib/kesehatan/data_kesehatan_warga/artikel_kesehatan/myth_vs_fact/index.ts b/src/app/api/[[...slugs]]/_lib/kesehatan/data_kesehatan_warga/artikel_kesehatan/myth_vs_fact/index.ts
new file mode 100644
index 00000000..933fa46f
--- /dev/null
+++ b/src/app/api/[[...slugs]]/_lib/kesehatan/data_kesehatan_warga/artikel_kesehatan/myth_vs_fact/index.ts
@@ -0,0 +1,17 @@
+import Elysia, { t } from "elysia";
+import mythVsFactCreate from "./create";
+import mythVsFactFindMany from "./find-many";
+
+const MythVsFact = new Elysia({
+ prefix: "/mythvsfact",
+ tags: ["Data Kesehatan/Artikel Kesehatan/Myth vs Fact"]
+})
+ .get("/find-many", mythVsFactFindMany)
+ .post("/create", mythVsFactCreate, {
+ body: t.Object({
+ title: t.String(),
+ mitos: t.String(),
+ fakta: t.String(),
+ }),
+ })
+export default MythVsFact
\ No newline at end of file
diff --git a/src/app/api/[[...slugs]]/_lib/kesehatan/data_kesehatan_warga/artikel_kesehatan/prevention/create.ts b/src/app/api/[[...slugs]]/_lib/kesehatan/data_kesehatan_warga/artikel_kesehatan/prevention/create.ts
new file mode 100644
index 00000000..adc0dac8
--- /dev/null
+++ b/src/app/api/[[...slugs]]/_lib/kesehatan/data_kesehatan_warga/artikel_kesehatan/prevention/create.ts
@@ -0,0 +1,28 @@
+import prisma from "@/lib/prisma";
+import { Prisma } from "@prisma/client";
+import { Context } from "elysia";
+
+type FormCreate = Prisma.PreventionGetPayload<{
+ select: {
+ title: true;
+ content: true;
+ }
+}>
+
+export default async function preventionCreate(context: Context) {
+ const body = context.body as FormCreate;
+
+ await prisma.prevention.create({
+ data: {
+ title: body.title,
+ content: body.content,
+ },
+ });
+ return {
+ success: true,
+ message: "Success create prevention",
+ data: {
+ ...body,
+ },
+ };
+}
diff --git a/src/app/api/[[...slugs]]/_lib/kesehatan/data_kesehatan_warga/artikel_kesehatan/prevention/find-many.ts b/src/app/api/[[...slugs]]/_lib/kesehatan/data_kesehatan_warga/artikel_kesehatan/prevention/find-many.ts
new file mode 100644
index 00000000..4cc7596e
--- /dev/null
+++ b/src/app/api/[[...slugs]]/_lib/kesehatan/data_kesehatan_warga/artikel_kesehatan/prevention/find-many.ts
@@ -0,0 +1,8 @@
+import prisma from "@/lib/prisma"
+
+export default async function preventionFindMany() {
+ const res = await prisma.prevention.findMany()
+ return {
+ data: res
+ }
+}
\ No newline at end of file
diff --git a/src/app/api/[[...slugs]]/_lib/kesehatan/data_kesehatan_warga/artikel_kesehatan/prevention/index.ts b/src/app/api/[[...slugs]]/_lib/kesehatan/data_kesehatan_warga/artikel_kesehatan/prevention/index.ts
new file mode 100644
index 00000000..6ab8e393
--- /dev/null
+++ b/src/app/api/[[...slugs]]/_lib/kesehatan/data_kesehatan_warga/artikel_kesehatan/prevention/index.ts
@@ -0,0 +1,16 @@
+import Elysia, { t } from "elysia"
+import preventionCreate from "./create"
+import preventionFindMany from "./find-many"
+
+const Prevention = new Elysia({
+ prefix: "/prevention",
+ tags: ["Data Kesehatan/Artikel Kesehatan/Prevention"]
+})
+ .get("/find-many", preventionFindMany)
+ .post("/create", preventionCreate, {
+ body: t.Object({
+ title: t.String(),
+ content: t.String(),
+ }),
+ })
+export default Prevention
diff --git a/src/app/api/[[...slugs]]/_lib/kesehatan/data_kesehatan_warga/artikel_kesehatan/syptom/create.ts b/src/app/api/[[...slugs]]/_lib/kesehatan/data_kesehatan_warga/artikel_kesehatan/syptom/create.ts
new file mode 100644
index 00000000..c53ec1dd
--- /dev/null
+++ b/src/app/api/[[...slugs]]/_lib/kesehatan/data_kesehatan_warga/artikel_kesehatan/syptom/create.ts
@@ -0,0 +1,27 @@
+import prisma from "@/lib/prisma";
+import { Prisma } from "@prisma/client";
+import { Context } from "elysia";
+
+type FormCreate = Prisma.SymptomGetPayload<{
+ select: {
+ title: true;
+ content: true;
+ }
+}>
+export default async function symptomCreate(context: Context) {
+ const body = context.body as FormCreate;
+
+ await prisma.symptom.create({
+ data: {
+ title: body.title,
+ content: body.content,
+ },
+ });
+ return {
+ success: true,
+ message: "Success create symptom",
+ data: {
+ ...body,
+ },
+ };
+}
\ No newline at end of file
diff --git a/src/app/api/[[...slugs]]/_lib/kesehatan/data_kesehatan_warga/artikel_kesehatan/syptom/find-many.ts b/src/app/api/[[...slugs]]/_lib/kesehatan/data_kesehatan_warga/artikel_kesehatan/syptom/find-many.ts
new file mode 100644
index 00000000..9d035742
--- /dev/null
+++ b/src/app/api/[[...slugs]]/_lib/kesehatan/data_kesehatan_warga/artikel_kesehatan/syptom/find-many.ts
@@ -0,0 +1,8 @@
+import prisma from "@/lib/prisma"
+
+export default async function symptomFindMany() {
+ const res = await prisma.symptom.findMany()
+ return {
+ data: res
+ }
+}
\ No newline at end of file
diff --git a/src/app/api/[[...slugs]]/_lib/kesehatan/data_kesehatan_warga/artikel_kesehatan/syptom/index.ts b/src/app/api/[[...slugs]]/_lib/kesehatan/data_kesehatan_warga/artikel_kesehatan/syptom/index.ts
new file mode 100644
index 00000000..6a03bc2b
--- /dev/null
+++ b/src/app/api/[[...slugs]]/_lib/kesehatan/data_kesehatan_warga/artikel_kesehatan/syptom/index.ts
@@ -0,0 +1,16 @@
+import Elysia, { t } from "elysia";
+import symptomCreate from "./create";
+import symptomFindMany from "./find-many";
+
+const Syptom = new Elysia({
+ prefix: "/symptom",
+ tags: ["Data Kesehatan/Artikel Kesehatan/Syptom"]
+})
+ .get("/find-many", symptomFindMany)
+ .post("/create", symptomCreate, {
+ body: t.Object({
+ title: t.String(),
+ content: t.String(),
+ }),
+ })
+export default Syptom
\ No newline at end of file
diff --git a/src/app/api/[[...slugs]]/_lib/kesehatan/index.ts b/src/app/api/[[...slugs]]/_lib/kesehatan/index.ts
index b064f356..f8cae369 100644
--- a/src/app/api/[[...slugs]]/_lib/kesehatan/index.ts
+++ b/src/app/api/[[...slugs]]/_lib/kesehatan/index.ts
@@ -13,6 +13,12 @@ import DokumenDiperlukan from "./data_kesehatan_warga/jadwal_kegiatan/dokumen_ya
import PendaftaranJadwal from "./data_kesehatan_warga/jadwal_kegiatan/pendaftaran";
import PersentaseKelahiranKematian from "./data_kesehatan_warga/persentase_kelahiran_kematian";
import GrafikKepuasan from "./data_kesehatan_warga/grafik_kepuasan";
+import Introduction from "./data_kesehatan_warga/artikel_kesehatan/introduction";
+import Syptom from "./data_kesehatan_warga/artikel_kesehatan/syptom";
+import Prevention from "./data_kesehatan_warga/artikel_kesehatan/prevention";
+import FirstAid from "./data_kesehatan_warga/artikel_kesehatan/first_aid";
+import MythVsFact from "./data_kesehatan_warga/artikel_kesehatan/myth_vs_fact";
+import DoctorSign from "./data_kesehatan_warga/artikel_kesehatan/doctor_sign";
const Kesehatan = new Elysia({
@@ -33,4 +39,10 @@ const Kesehatan = new Elysia({
.use(PendaftaranJadwal)
.use(PersentaseKelahiranKematian)
.use(GrafikKepuasan)
+.use(Introduction)
+.use(Syptom)
+.use(Prevention)
+.use(FirstAid)
+.use(MythVsFact)
+.use(DoctorSign)
export default Kesehatan;
diff --git a/src/app/api/[[...slugs]]/_lib/ppid/daftar_informasi_publik/create.ts b/src/app/api/[[...slugs]]/_lib/ppid/daftar_informasi_publik/create.ts
new file mode 100644
index 00000000..252c10f0
--- /dev/null
+++ b/src/app/api/[[...slugs]]/_lib/ppid/daftar_informasi_publik/create.ts
@@ -0,0 +1,32 @@
+import prisma from "@/lib/prisma";
+import { Prisma } from "@prisma/client";
+import { Context } from "elysia";
+
+type FormCreate = Prisma.DaftarInformasiPublikGetPayload<{
+ select: {
+ jenisInformasi: true;
+ deskripsi: true;
+ tanggal: true;
+ }
+}>
+export default async function daftarInformasiPublikCreate(context: Context) {
+ const body = context.body as FormCreate;
+ const jumlahData = await prisma.daftarInformasiPublik.count({
+ where: { isActive: true }, // hitung data aktif aja
+ })
+ await prisma.daftarInformasiPublik.create({
+ data: {
+ nomor: jumlahData + 1,
+ jenisInformasi: body.jenisInformasi,
+ deskripsi: body.deskripsi,
+ tanggal: body.tanggal,
+ },
+ })
+ return {
+ success: true,
+ message: "Success create daftar informasi publik",
+ data: {
+ ...body,
+ },
+ };
+}
\ No newline at end of file
diff --git a/src/app/api/[[...slugs]]/_lib/ppid/daftar_informasi_publik/find-many.ts b/src/app/api/[[...slugs]]/_lib/ppid/daftar_informasi_publik/find-many.ts
new file mode 100644
index 00000000..12bb8881
--- /dev/null
+++ b/src/app/api/[[...slugs]]/_lib/ppid/daftar_informasi_publik/find-many.ts
@@ -0,0 +1,9 @@
+import prisma from "@/lib/prisma";
+
+export default async function daftarInformasiPublikFindMany() {
+ const res = await prisma.daftarInformasiPublik.findMany();
+ return {
+ data: res
+ }
+}
+
\ No newline at end of file
diff --git a/src/app/api/[[...slugs]]/_lib/ppid/daftar_informasi_publik/index.ts b/src/app/api/[[...slugs]]/_lib/ppid/daftar_informasi_publik/index.ts
new file mode 100644
index 00000000..36b0fcf4
--- /dev/null
+++ b/src/app/api/[[...slugs]]/_lib/ppid/daftar_informasi_publik/index.ts
@@ -0,0 +1,18 @@
+import Elysia, { t } from "elysia";
+import daftarInformasiPublikCreate from "./create";
+import daftarInformasiPublikFindMany from "./find-many";
+
+const DaftarInformasiPublik = new Elysia({
+ prefix: "/daftarinformasipublik",
+ tags: ["PPID/Daftar Informasi Publik"]
+})
+ .get("/find-many", daftarInformasiPublikFindMany)
+ .post("/create", daftarInformasiPublikCreate, {
+ body: t.Object({
+ jenisInformasi: t.String(),
+ deskripsi: t.String(),
+ tanggal: t.String(),
+ }),
+ })
+
+export default DaftarInformasiPublik
\ No newline at end of file
diff --git a/src/app/api/[[...slugs]]/_lib/ppid/dasar_hukum/find-by-id.ts b/src/app/api/[[...slugs]]/_lib/ppid/dasar_hukum/find-by-id.ts
new file mode 100644
index 00000000..5c443074
--- /dev/null
+++ b/src/app/api/[[...slugs]]/_lib/ppid/dasar_hukum/find-by-id.ts
@@ -0,0 +1,33 @@
+import prisma from "@/lib/prisma";
+import { Context } from "elysia";
+
+export default async function dasarHukumPPIDFindById(context: Context) {
+ try {
+ const id = context?.params?.slugs?.[0];
+
+ // If no ID provided, get the first profile
+ if (!id) {
+ const data = await prisma.dasarHukumPPID.findFirst();
+ return {
+ success: true,
+ data,
+ };
+ }
+
+ const data = await prisma.dasarHukumPPID.findUniqueOrThrow({
+ where: { id },
+ });
+
+ return {
+ success: true,
+ data,
+ };
+ } catch (error) {
+ console.error("Error fetching profilePPID:", error);
+
+ return {
+ success: false,
+ message: error instanceof Error ? error.message : "Unknown error",
+ };
+ }
+}
\ No newline at end of file
diff --git a/src/app/api/[[...slugs]]/_lib/ppid/dasar_hukum/index.ts b/src/app/api/[[...slugs]]/_lib/ppid/dasar_hukum/index.ts
new file mode 100644
index 00000000..9ac8b873
--- /dev/null
+++ b/src/app/api/[[...slugs]]/_lib/ppid/dasar_hukum/index.ts
@@ -0,0 +1,18 @@
+import Elysia, { t } from "elysia";
+import dasarHukumPPIDFindById from "./find-by-id";
+import dasarHukumPPIDUpdate from "./update";
+
+const DasarHukumPPID = new Elysia({
+ prefix: "/dasarhukumppid",
+ tags: ["PPID/Dasar Hukum PPID"]
+})
+ .get("/find-by-id", dasarHukumPPIDFindById)
+ .post("/update", dasarHukumPPIDUpdate, {
+ body: t.Object({
+ id: t.String(),
+ judul: t.String(),
+ content: t.String(),
+ })
+ })
+
+export default DasarHukumPPID
\ No newline at end of file
diff --git a/src/app/api/[[...slugs]]/_lib/ppid/dasar_hukum/update.ts b/src/app/api/[[...slugs]]/_lib/ppid/dasar_hukum/update.ts
new file mode 100644
index 00000000..2c019ce2
--- /dev/null
+++ b/src/app/api/[[...slugs]]/_lib/ppid/dasar_hukum/update.ts
@@ -0,0 +1,29 @@
+import prisma from "@/lib/prisma";
+import { Prisma } from "@prisma/client";
+import { Context } from "elysia";
+
+type FormCreate = Prisma.DasarHukumPPIDGetPayload<{
+ select: {
+ id: true;
+ judul: true;
+ content: true;
+ }
+}>
+export default async function dasarHukumPPIDUpdate(context: Context) {
+ const body = context.body as FormCreate;
+
+ await prisma.dasarHukumPPID.update({
+ where: {
+ id: body.id
+ },
+ data: {
+ judul: body.judul,
+ content: body.content,
+ }
+ })
+
+ return {
+ success: true,
+ message: "Dasar Hukum PPID Berhasil Dibuat",
+ }
+}
\ No newline at end of file
diff --git a/src/app/api/[[...slugs]]/_lib/ppid/ikm/grafik_berdasarkan_jenis_kelamin/create.ts b/src/app/api/[[...slugs]]/_lib/ppid/ikm/grafik_berdasarkan_jenis_kelamin/create.ts
new file mode 100644
index 00000000..3c58f22d
--- /dev/null
+++ b/src/app/api/[[...slugs]]/_lib/ppid/ikm/grafik_berdasarkan_jenis_kelamin/create.ts
@@ -0,0 +1,27 @@
+import prisma from "@/lib/prisma";
+import { Prisma } from "@prisma/client";
+import { Context } from "elysia";
+
+type FormCreate = Prisma.GrafikBerdasarkanJenisKelaminGetPayload<{
+ select: {
+ perempuan: true;
+ laki: true;
+ }
+}>
+export default async function grafikBerdasarkanJenisKelaminCreate(context: Context) {
+ const body = context.body as FormCreate;
+
+ await prisma.grafikBerdasarkanJenisKelamin.create({
+ data: {
+ perempuan: body.perempuan,
+ laki: body.laki,
+ },
+ });
+ return {
+ success: true,
+ message: "Success create grafik berdasarkan jenis kelamin",
+ data: {
+ ...body,
+ },
+ };
+}
\ No newline at end of file
diff --git a/src/app/api/[[...slugs]]/_lib/ppid/ikm/grafik_berdasarkan_jenis_kelamin/find-many.ts b/src/app/api/[[...slugs]]/_lib/ppid/ikm/grafik_berdasarkan_jenis_kelamin/find-many.ts
new file mode 100644
index 00000000..0960c1d6
--- /dev/null
+++ b/src/app/api/[[...slugs]]/_lib/ppid/ikm/grafik_berdasarkan_jenis_kelamin/find-many.ts
@@ -0,0 +1,8 @@
+import prisma from "@/lib/prisma";
+
+export default async function grafikBerdasarkanJenisKelaminFindMany() {
+ const res = await prisma.grafikBerdasarkanJenisKelamin.findMany();
+ return {
+ data: res
+ }
+}
\ No newline at end of file
diff --git a/src/app/api/[[...slugs]]/_lib/ppid/ikm/grafik_berdasarkan_jenis_kelamin/index.ts b/src/app/api/[[...slugs]]/_lib/ppid/ikm/grafik_berdasarkan_jenis_kelamin/index.ts
new file mode 100644
index 00000000..88c7ddd7
--- /dev/null
+++ b/src/app/api/[[...slugs]]/_lib/ppid/ikm/grafik_berdasarkan_jenis_kelamin/index.ts
@@ -0,0 +1,17 @@
+import Elysia, { t } from "elysia";
+import grafikBerdasarkanJenisKelaminCreate from "./create";
+import grafikBerdasarkanJenisKelaminFindMany from "./find-many";
+
+
+const GrafikBerdasarkanJenisKelamin = new Elysia({
+ prefix: "/grafikberdasarkanjeniskelamin",
+ tags: ["PPID/IKM/grafikberdasarkanjeniskelamin"],
+})
+ .get("/find-many", grafikBerdasarkanJenisKelaminFindMany)
+ .post("/create", grafikBerdasarkanJenisKelaminCreate, {
+ body: t.Object({
+ perempuan: t.String(),
+ laki: t.String(),
+ }),
+ });
+export default GrafikBerdasarkanJenisKelamin;
diff --git a/src/app/api/[[...slugs]]/_lib/ppid/ikm/grafik_berdasarkan_umur/create.ts b/src/app/api/[[...slugs]]/_lib/ppid/ikm/grafik_berdasarkan_umur/create.ts
new file mode 100644
index 00000000..8444d0df
--- /dev/null
+++ b/src/app/api/[[...slugs]]/_lib/ppid/ikm/grafik_berdasarkan_umur/create.ts
@@ -0,0 +1,31 @@
+import prisma from "@/lib/prisma";
+import { Prisma } from "@prisma/client";
+import { Context } from "elysia";
+
+type FormCreate = Prisma.GrafikBerdasarkanUmurGetPayload<{
+ select: {
+ remaja: true;
+ dewasa: true;
+ orangtua: true;
+ lansia: true;
+ }
+}>
+export async function grafikBerdasarkanUmurCreate(context: Context) {
+ const body = context.body as FormCreate;
+
+ await prisma.grafikBerdasarkanUmur.create({
+ data: {
+ remaja: body.remaja,
+ dewasa: body.dewasa,
+ orangtua: body.orangtua,
+ lansia: body.lansia,
+ },
+ });
+ return {
+ success: true,
+ message: "Success create grafik berdasarkan umur",
+ data: {
+ ...body,
+ },
+ };
+}
\ No newline at end of file
diff --git a/src/app/api/[[...slugs]]/_lib/ppid/ikm/grafik_berdasarkan_umur/find-many.ts b/src/app/api/[[...slugs]]/_lib/ppid/ikm/grafik_berdasarkan_umur/find-many.ts
new file mode 100644
index 00000000..d050abfc
--- /dev/null
+++ b/src/app/api/[[...slugs]]/_lib/ppid/ikm/grafik_berdasarkan_umur/find-many.ts
@@ -0,0 +1,8 @@
+import prisma from "@/lib/prisma";
+
+export async function grafikBerdasarkanUmurFindMany(){
+ const res = await prisma.grafikBerdasarkanUmur.findMany();
+ return {
+ data: res
+ }
+}
\ No newline at end of file
diff --git a/src/app/api/[[...slugs]]/_lib/ppid/ikm/grafik_berdasarkan_umur/index.ts b/src/app/api/[[...slugs]]/_lib/ppid/ikm/grafik_berdasarkan_umur/index.ts
new file mode 100644
index 00000000..94051b31
--- /dev/null
+++ b/src/app/api/[[...slugs]]/_lib/ppid/ikm/grafik_berdasarkan_umur/index.ts
@@ -0,0 +1,19 @@
+import Elysia, { t } from "elysia";
+import { grafikBerdasarkanUmurFindMany } from "./find-many";
+import { grafikBerdasarkanUmurCreate } from "./create";
+
+const GrafikBerdasarkanUmur = new Elysia({
+ prefix: "/grafikberdasarkanumur",
+ tags: ["PPID/IKM/grafikberdasarkanumur"]
+})
+ .get("/find-many", grafikBerdasarkanUmurFindMany)
+ .post("/create", grafikBerdasarkanUmurCreate, {
+ body: t.Object({
+ remaja: t.String(),
+ dewasa: t.String(),
+ orangtua: t.String(),
+ lansia: t.String(),
+ }),
+ });
+
+export default GrafikBerdasarkanUmur;
\ No newline at end of file
diff --git a/src/app/api/[[...slugs]]/_lib/ppid/ikm/grafik_hasil_kepuasan_masyarakat/create.ts b/src/app/api/[[...slugs]]/_lib/ppid/ikm/grafik_hasil_kepuasan_masyarakat/create.ts
new file mode 100644
index 00000000..8d57d7e4
--- /dev/null
+++ b/src/app/api/[[...slugs]]/_lib/ppid/ikm/grafik_hasil_kepuasan_masyarakat/create.ts
@@ -0,0 +1,27 @@
+import prisma from "@/lib/prisma";
+import { Prisma } from "@prisma/client";
+import { Context } from "elysia";
+
+type FormCreate = Prisma.IndeksKepuasanMasyarakatGetPayload<{
+ select: {
+ label: true;
+ kepuasan: true;
+ };
+}>;
+export default async function grafikHasilKepuasanMasyarakatCreate(context: Context) {
+ const body = context.body as FormCreate;
+
+ await prisma.indeksKepuasanMasyarakat.create({
+ data: {
+ label: body.label,
+ kepuasan: body.kepuasan,
+ },
+ });
+ return {
+ success: true,
+ message: "Success create grafik hasil kepuasan masyarakat",
+ data: {
+ ...body,
+ },
+ };
+}
diff --git a/src/app/api/[[...slugs]]/_lib/ppid/ikm/grafik_hasil_kepuasan_masyarakat/find-many.ts b/src/app/api/[[...slugs]]/_lib/ppid/ikm/grafik_hasil_kepuasan_masyarakat/find-many.ts
new file mode 100644
index 00000000..6e39d8a5
--- /dev/null
+++ b/src/app/api/[[...slugs]]/_lib/ppid/ikm/grafik_hasil_kepuasan_masyarakat/find-many.ts
@@ -0,0 +1,8 @@
+import prisma from "@/lib/prisma";
+
+export default async function grafikHasilKepuasanMasyarakatFindMany() {
+ const res = await prisma.indeksKepuasanMasyarakat.findMany();
+ return {
+ data: res,
+ };
+}
diff --git a/src/app/api/[[...slugs]]/_lib/ppid/ikm/grafik_hasil_kepuasan_masyarakat/index.ts b/src/app/api/[[...slugs]]/_lib/ppid/ikm/grafik_hasil_kepuasan_masyarakat/index.ts
new file mode 100644
index 00000000..29358dd5
--- /dev/null
+++ b/src/app/api/[[...slugs]]/_lib/ppid/ikm/grafik_hasil_kepuasan_masyarakat/index.ts
@@ -0,0 +1,17 @@
+import Elysia, { t } from "elysia";
+import grafikHasilKepuasanMasyarakatCreate from "./create";
+import grafikHasilKepuasanMasyarakatFindMany from "./find-many";
+
+const GrafikHasilKepuasanMasyarakat = new Elysia({
+ prefix: "/grafikhasilkepuasamanmasyarakat",
+ tags: ["PPID/IKM/grafikhasilkepuasanmasyarakat"],
+})
+ .get("/find-many", grafikHasilKepuasanMasyarakatFindMany)
+ .post("/create", grafikHasilKepuasanMasyarakatCreate, {
+ body: t.Object({
+ label: t.String(),
+ kepuasan: t.String(),
+ }),
+ });
+
+export default GrafikHasilKepuasanMasyarakat;
diff --git a/src/app/api/[[...slugs]]/_lib/ppid/ikm/grafik_responden/create.ts b/src/app/api/[[...slugs]]/_lib/ppid/ikm/grafik_responden/create.ts
new file mode 100644
index 00000000..89c71102
--- /dev/null
+++ b/src/app/api/[[...slugs]]/_lib/ppid/ikm/grafik_responden/create.ts
@@ -0,0 +1,31 @@
+import prisma from "@/lib/prisma";
+import { Prisma } from "@prisma/client";
+import { Context } from "elysia";
+
+type FormCreate = Prisma.GrafikBerdasarkanRespondenGetPayload<{
+ select: {
+ sangatbaik: true;
+ baik: true;
+ kurangbaik: true;
+ tidakbaik: true
+ };
+}>;
+export default async function grafikRespondenCreate(context: Context) {
+ const body = context.body as FormCreate;
+
+ await prisma.grafikBerdasarkanResponden.create({
+ data: {
+ sangatbaik: body.sangatbaik,
+ baik: body.baik,
+ kurangbaik: body.kurangbaik,
+ tidakbaik: body.tidakbaik,
+ },
+ });
+ return {
+ success: true,
+ message: "Success create grafik berdasarkan responden",
+ data: {
+ ...body,
+ },
+ };
+}
\ No newline at end of file
diff --git a/src/app/api/[[...slugs]]/_lib/ppid/ikm/grafik_responden/find-many.ts b/src/app/api/[[...slugs]]/_lib/ppid/ikm/grafik_responden/find-many.ts
new file mode 100644
index 00000000..cd853f5c
--- /dev/null
+++ b/src/app/api/[[...slugs]]/_lib/ppid/ikm/grafik_responden/find-many.ts
@@ -0,0 +1,8 @@
+import prisma from "@/lib/prisma";
+
+export default async function grafikRespondenFindMany(){
+ const res = await prisma.grafikBerdasarkanResponden.findMany();
+ return{
+ data: res
+ }
+}
\ No newline at end of file
diff --git a/src/app/api/[[...slugs]]/_lib/ppid/ikm/grafik_responden/index.ts b/src/app/api/[[...slugs]]/_lib/ppid/ikm/grafik_responden/index.ts
new file mode 100644
index 00000000..4bae7832
--- /dev/null
+++ b/src/app/api/[[...slugs]]/_lib/ppid/ikm/grafik_responden/index.ts
@@ -0,0 +1,20 @@
+import Elysia, { t } from "elysia";
+import grafikRespondenCreate from "./create";
+import grafikRespondenFindMany from "./find-many";
+
+const GrafikBerdasarkanResponden = new Elysia({
+ prefix: "/grafikberdasarkanresponden",
+ tags: ["PPID/IKM/grafikberdasarkanresponden"]
+})
+.get("/find-many", grafikRespondenFindMany)
+.post("/create", grafikRespondenCreate, {
+ body: t.Object({
+ sangatbaik: t.String(),
+ baik: t.String(),
+ kurangbaik: t.String(),
+ tidakbaik: t.String(),
+ }),
+})
+
+
+export default GrafikBerdasarkanResponden
\ No newline at end of file
diff --git a/src/app/api/[[...slugs]]/_lib/ppid/index.ts b/src/app/api/[[...slugs]]/_lib/ppid/index.ts
new file mode 100644
index 00000000..d830064c
--- /dev/null
+++ b/src/app/api/[[...slugs]]/_lib/ppid/index.ts
@@ -0,0 +1,33 @@
+import Elysia from "elysia";
+import DaftarInformasiPublik from "./daftar_informasi_publik";
+import GrafikHasilKepuasanMasyarakat from "./ikm/grafik_hasil_kepuasan_masyarakat";
+import GrafikBerdasarkanJenisKelamin from "./ikm/grafik_berdasarkan_jenis_kelamin";
+import GrafikBerdasarkanResponden from "./ikm/grafik_responden";
+import GrafikBerdasarkanUmur from "./ikm/grafik_berdasarkan_umur";
+import PermohonanInformasiPublik from "./permohonan_informasi_publik";
+import PermohonanKeberatanInformasiPublik from "./permohonan_keberatan_informasi_publik";
+import ProfilePPID from "./profile_ppid";
+import VisiMisiPPID from "./visi_misi_ppid/visi_misi_ppid";
+import DasarHukumPPID from "./dasar_hukum";
+
+
+
+
+const PPID = new Elysia({ prefix: "/api/ppid", tags: ["PPID"] })
+.use(ProfilePPID)
+.use(DaftarInformasiPublik)
+.use(GrafikHasilKepuasanMasyarakat)
+.use(GrafikBerdasarkanJenisKelamin)
+.use(GrafikBerdasarkanResponden)
+.use(GrafikBerdasarkanUmur)
+.use(PermohonanInformasiPublik)
+.use(PermohonanKeberatanInformasiPublik)
+.use(VisiMisiPPID)
+.use(DasarHukumPPID)
+
+
+
+
+
+export default PPID
+
diff --git a/src/app/api/[[...slugs]]/_lib/ppid/permohonan_informasi_publik/create.ts b/src/app/api/[[...slugs]]/_lib/ppid/permohonan_informasi_publik/create.ts
new file mode 100644
index 00000000..4cc99f88
--- /dev/null
+++ b/src/app/api/[[...slugs]]/_lib/ppid/permohonan_informasi_publik/create.ts
@@ -0,0 +1,41 @@
+import prisma from "@/lib/prisma";
+import { Prisma } from "@prisma/client";
+import { Context } from "elysia";
+
+type FormCreate = Prisma.PermohonanInformasiPublikGetPayload<{
+ select: {
+ name: true;
+ nik: true;
+ email: true;
+ notelp: true;
+ alamat: true;
+ jenisInformasiDimintaId: true;
+ caraMemperolehInformasiId: true;
+ caraMemperolehSalinanInformasiId: true;
+ }
+}>
+export default async function permohonanInformasiPublikCreate(context: Context) {
+ const body = context.body as FormCreate;
+
+ await prisma.permohonanInformasiPublik.create({
+ data: {
+ name: body.name,
+ nik: body.nik,
+ email: body.email,
+ notelp: body.notelp,
+ alamat: body.alamat,
+ jenisInformasiDimintaId: body.jenisInformasiDimintaId,
+ caraMemperolehInformasiId: body.caraMemperolehInformasiId,
+ caraMemperolehSalinanInformasiId: body.caraMemperolehSalinanInformasiId,
+ }
+ })
+
+ return {
+ success: true,
+ message: "Permohonan Informasi Publik Berhasil Dibuat",
+ data: {
+ ...body,
+ }
+ }
+}
+
\ No newline at end of file
diff --git a/src/app/api/[[...slugs]]/_lib/ppid/permohonan_informasi_publik/find-many.ts b/src/app/api/[[...slugs]]/_lib/ppid/permohonan_informasi_publik/find-many.ts
new file mode 100644
index 00000000..f8f32d41
--- /dev/null
+++ b/src/app/api/[[...slugs]]/_lib/ppid/permohonan_informasi_publik/find-many.ts
@@ -0,0 +1,14 @@
+import prisma from "@/lib/prisma";
+
+export default async function permohonanInformasiPublikFindMany() {
+ const res = await prisma.permohonanInformasiPublik.findMany({
+ include: {
+ jenisInformasiDiminta: true,
+ caraMemperolehInformasi: true,
+ caraMemperolehSalinanInformasi: true,
+ }
+ });
+ return {
+ data: res,
+ };
+}
diff --git a/src/app/api/[[...slugs]]/_lib/ppid/permohonan_informasi_publik/index.ts b/src/app/api/[[...slugs]]/_lib/ppid/permohonan_informasi_publik/index.ts
new file mode 100644
index 00000000..3a7a764b
--- /dev/null
+++ b/src/app/api/[[...slugs]]/_lib/ppid/permohonan_informasi_publik/index.ts
@@ -0,0 +1,29 @@
+import Elysia, { t } from "elysia";
+import permohonanInformasiPublikCreate from "./create";
+import permohonanInformasiPublikFindMany from "./find-many";
+import jenisInformasiFindMany from "./jenisInformasi";
+import memperolehInformasiFindMany from "./memperolehInformasi";
+import salinanInformasiFindMany from "./salinanInformasi";
+
+const PermohonanInformasiPublik = new Elysia({
+ prefix: "/permohonaninformasipublik",
+ tags: ["PPID/Permohonan Informasi Publik"]
+})
+ .get("/jenisInformasi/find-many", jenisInformasiFindMany)
+ .get("/memperolehInformasi/find-many", memperolehInformasiFindMany)
+ .get("/salinanInformasi/find-many", salinanInformasiFindMany)
+ .get("/find-many", permohonanInformasiPublikFindMany)
+ .post("/create", permohonanInformasiPublikCreate, {
+ body: t.Object({
+ name: t.String(),
+ nik: t.String(),
+ notelp: t.String(),
+ alamat: t.String(),
+ email: t.String(),
+ jenisInformasiDimintaId: t.Union([t.String(), t.Null()]),
+ caraMemperolehInformasiId: t.Union([t.String(), t.Null()]),
+ caraMemperolehSalinanInformasiId: t.Union([t.String(), t.Null()]),
+ }),
+ })
+
+export default PermohonanInformasiPublik
\ No newline at end of file
diff --git a/src/app/api/[[...slugs]]/_lib/ppid/permohonan_informasi_publik/jenisInformasi.ts b/src/app/api/[[...slugs]]/_lib/ppid/permohonan_informasi_publik/jenisInformasi.ts
new file mode 100644
index 00000000..f8498c1f
--- /dev/null
+++ b/src/app/api/[[...slugs]]/_lib/ppid/permohonan_informasi_publik/jenisInformasi.ts
@@ -0,0 +1,8 @@
+import prisma from "@/lib/prisma";
+
+export default async function jenisInformasiFindMany() {
+ const res = await prisma.jenisInformasiDiminta.findMany();
+ return {
+ data: res,
+ };
+}
diff --git a/src/app/api/[[...slugs]]/_lib/ppid/permohonan_informasi_publik/memperolehInformasi.ts b/src/app/api/[[...slugs]]/_lib/ppid/permohonan_informasi_publik/memperolehInformasi.ts
new file mode 100644
index 00000000..dfd6ae52
--- /dev/null
+++ b/src/app/api/[[...slugs]]/_lib/ppid/permohonan_informasi_publik/memperolehInformasi.ts
@@ -0,0 +1,8 @@
+import prisma from "@/lib/prisma";
+
+export default async function memperolehInformasiFindMany() {
+ const res = await prisma.caraMemperolehInformasi.findMany();
+ return {
+ data: res,
+ };
+}
\ No newline at end of file
diff --git a/src/app/api/[[...slugs]]/_lib/ppid/permohonan_informasi_publik/salinanInformasi.ts b/src/app/api/[[...slugs]]/_lib/ppid/permohonan_informasi_publik/salinanInformasi.ts
new file mode 100644
index 00000000..5aa85646
--- /dev/null
+++ b/src/app/api/[[...slugs]]/_lib/ppid/permohonan_informasi_publik/salinanInformasi.ts
@@ -0,0 +1,9 @@
+import prisma from "@/lib/prisma";
+
+export default async function salinanInformasiFindMany() {
+ const res = await prisma.caraMemperolehSalinanInformasi.findMany();
+ return {
+ data: res,
+ };
+}
+
\ No newline at end of file
diff --git a/src/app/api/[[...slugs]]/_lib/ppid/permohonan_keberatan_informasi_publik/create.ts b/src/app/api/[[...slugs]]/_lib/ppid/permohonan_keberatan_informasi_publik/create.ts
new file mode 100644
index 00000000..a6f70308
--- /dev/null
+++ b/src/app/api/[[...slugs]]/_lib/ppid/permohonan_keberatan_informasi_publik/create.ts
@@ -0,0 +1,33 @@
+import prisma from "@/lib/prisma";
+import { Prisma } from "@prisma/client";
+import { Context } from "elysia";
+
+type FormCreate = Prisma.FormulirPermohonanKeberatanGetPayload<{
+ select: {
+ name: true;
+ email: true;
+ notelp: true;
+ alasan: true;
+ }
+}>
+
+export default async function permohonanKeberatanInformasiPublikCreate(context: Context) {
+ const body = context.body as FormCreate;
+
+ await prisma.formulirPermohonanKeberatan.create({
+ data: {
+ name: body.name,
+ email: body.email,
+ notelp: body.notelp,
+ alasan: body.alasan,
+ }
+ })
+
+ return {
+ success: true,
+ message: "Permohonan Keberatan Informasi Publik Berhasil Dibuat",
+ data: {
+ ...body,
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/app/api/[[...slugs]]/_lib/ppid/permohonan_keberatan_informasi_publik/find-many.ts b/src/app/api/[[...slugs]]/_lib/ppid/permohonan_keberatan_informasi_publik/find-many.ts
new file mode 100644
index 00000000..bd4b6c4d
--- /dev/null
+++ b/src/app/api/[[...slugs]]/_lib/ppid/permohonan_keberatan_informasi_publik/find-many.ts
@@ -0,0 +1,8 @@
+import prisma from "@/lib/prisma";
+
+export default async function permohonanKeberatanInformasiPublikFindMany() {
+ const res = await prisma.formulirPermohonanKeberatan.findMany();
+ return {
+ data: res,
+ };
+}
diff --git a/src/app/api/[[...slugs]]/_lib/ppid/permohonan_keberatan_informasi_publik/index.ts b/src/app/api/[[...slugs]]/_lib/ppid/permohonan_keberatan_informasi_publik/index.ts
new file mode 100644
index 00000000..4d77d9c7
--- /dev/null
+++ b/src/app/api/[[...slugs]]/_lib/ppid/permohonan_keberatan_informasi_publik/index.ts
@@ -0,0 +1,19 @@
+import Elysia, { t } from "elysia";
+import permohonanKeberatanInformasiPublikCreate from "./create";
+import permohonanKeberatanInformasiPublikFindMany from "./find-many";
+
+const PermohonanKeberatanInformasiPublik = new Elysia({
+ prefix: "/permohonankeberataninformasipublik",
+ tags: ["PPID/Permohonan Keberatan Informasi Publik"],
+})
+ .get("/find-many", permohonanKeberatanInformasiPublikFindMany)
+ .post("/create", permohonanKeberatanInformasiPublikCreate, {
+ body: t.Object({
+ name: t.String(),
+ email: t.String(),
+ notelp: t.String(),
+ alasan: t.String(),
+ }),
+ })
+
+export default PermohonanKeberatanInformasiPublik;
\ No newline at end of file
diff --git a/src/app/api/[[...slugs]]/_lib/ppid/profile_ppid/edit-img.ts b/src/app/api/[[...slugs]]/_lib/ppid/profile_ppid/edit-img.ts
new file mode 100644
index 00000000..b989b2ce
--- /dev/null
+++ b/src/app/api/[[...slugs]]/_lib/ppid/profile_ppid/edit-img.ts
@@ -0,0 +1,82 @@
+import prisma from "@/lib/prisma";
+import { Context } from "elysia";
+import { writeFile, unlink } from "fs/promises";
+import path from "path";
+import fs from "fs";
+import { mkdir } from "fs/promises";
+
+interface ProfilePPIDBody {
+ id: string;
+ file: Blob & { name: string; type: string };
+}
+
+export default async function editImageProfilePPID(context: Context<{ body: ProfilePPIDBody }>) {
+ const { id, file } = context.body;
+
+ if (!file || !id) {
+ return {
+ success: false,
+ message: "File atau ID harus disertakan",
+ };
+ }
+
+ // Validasi ekstensi file
+ const allowedTypes = ["image/jpeg", "image/png", "image/webp"];
+ if (!allowedTypes.includes(file.type)) {
+ return {
+ success: false,
+ message: "Tipe file tidak diizinkan. Hanya JPG, PNG, atau WEBP",
+ };
+ }
+
+ const bytes = await file.arrayBuffer();
+ const buffer = Buffer.from(bytes);
+ const filename = `${id}_${Date.now()}_${file.name}`;
+ const folderPath = path.resolve("public", "assets", "images", "ppid", "profile-ppid");
+
+ try {
+ await mkdir(folderPath, { recursive: true });
+
+ console.log('Folder path:', folderPath);
+ const filePath = path.join(folderPath, filename);
+ console.log('File path:', filePath);
+
+ await writeFile(filePath, buffer);
+
+ if (!fs.existsSync(filePath)) {
+ return {
+ success: false,
+ message: "Failed to write file to disk",
+ };
+ }
+
+ const imageUrl = `/assets/images/ppid/profile-ppid/${filename}`;
+
+ // Hapus file lama (opsional, kalau mau bersih)
+ const oldData = await prisma.profilePPID.findUnique({ where: { id } });
+ if (oldData?.imageUrl) {
+ const oldPath = path.resolve("public", oldData.imageUrl.replace(/^\//, ""));
+ if (fs.existsSync(oldPath)) {
+ await unlink(oldPath).catch(() => {});
+ }
+ }
+
+ // Update DB
+ await prisma.profilePPID.update({
+ where: { id },
+ data: { imageUrl },
+ });
+
+ return {
+ success: true,
+ message: "Gambar berhasil diunggah",
+ url: imageUrl,
+ };
+ } catch (error) {
+ console.error('Error uploading file:', error);
+ return {
+ success: false,
+ message: "Gagal mengunggah gambar",
+ };
+ }
+}
diff --git a/src/app/api/[[...slugs]]/_lib/ppid/profile_ppid/find-by-id.ts b/src/app/api/[[...slugs]]/_lib/ppid/profile_ppid/find-by-id.ts
new file mode 100644
index 00000000..95ea591e
--- /dev/null
+++ b/src/app/api/[[...slugs]]/_lib/ppid/profile_ppid/find-by-id.ts
@@ -0,0 +1,33 @@
+import prisma from "@/lib/prisma";
+import { Context } from "elysia";
+
+export default async function profilePPIDFindById(context: Context) {
+ try {
+ const id = context?.params?.slugs?.[0];
+
+ // If no ID provided, get the first profile
+ if (!id) {
+ const data = await prisma.profilePPID.findFirst();
+ return {
+ success: true,
+ data,
+ };
+ }
+
+ const data = await prisma.profilePPID.findUniqueOrThrow({
+ where: { id },
+ });
+
+ return {
+ success: true,
+ data,
+ };
+ } catch (error) {
+ console.error("Error fetching profilePPID:", error);
+
+ return {
+ success: false,
+ message: error instanceof Error ? error.message : "Unknown error",
+ };
+ }
+}
diff --git a/src/app/api/[[...slugs]]/_lib/ppid/profile_ppid/index.ts b/src/app/api/[[...slugs]]/_lib/ppid/profile_ppid/index.ts
new file mode 100644
index 00000000..fb274096
--- /dev/null
+++ b/src/app/api/[[...slugs]]/_lib/ppid/profile_ppid/index.ts
@@ -0,0 +1,24 @@
+import Elysia, { t } from "elysia";
+import profilePPIDFindById from "./find-by-id";
+import profilePPIDUpdate from "./update";
+import editImageProfilePPID from "./edit-img";
+
+const ProfilePPID = new Elysia({
+ prefix: "/profileppid",
+ tags: ["PPID/Profile PPID"]
+})
+ .get("/find-by-id", profilePPIDFindById)
+ .post("/update", profilePPIDUpdate, {
+ body: t.Object({
+ id: t.String(),
+ name: t.String(),
+ biodata: t.String(),
+ riwayat: t.String(),
+ pengalaman: t.String(),
+ unggulan: t.String(),
+ })
+ })
+ .post("/edit-img", editImageProfilePPID)
+
+
+export default ProfilePPID;
diff --git a/src/app/api/[[...slugs]]/_lib/ppid/profile_ppid/update.ts b/src/app/api/[[...slugs]]/_lib/ppid/profile_ppid/update.ts
new file mode 100644
index 00000000..621e98f4
--- /dev/null
+++ b/src/app/api/[[...slugs]]/_lib/ppid/profile_ppid/update.ts
@@ -0,0 +1,38 @@
+import prisma from "@/lib/prisma";
+import { Prisma } from "@prisma/client";
+import { Context } from "elysia";
+
+type FormCreate = Prisma.ProfilePPIDGetPayload<{
+ select: {
+ id: true;
+ name: true;
+ biodata: true;
+ riwayat: true;
+ pengalaman: true;
+ unggulan: true;
+ }
+}>
+export default async function profilePPIDUpdate(context: Context) {
+ const body = context.body as FormCreate;
+
+ await prisma.profilePPID.update({
+ where: {
+ id: body.id
+ },
+ data: {
+ name: body.name,
+ biodata: body.biodata,
+ riwayat: body.riwayat,
+ pengalaman: body.pengalaman,
+ unggulan: body.unggulan,
+ }
+ })
+
+ return {
+ success: true,
+ message: "Profile PPID Berhasil Dibuat",
+ data: {
+ ...body,
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/app/api/[[...slugs]]/_lib/ppid/visi_misi_ppid/visi_misi_ppid/find-by-id.ts b/src/app/api/[[...slugs]]/_lib/ppid/visi_misi_ppid/visi_misi_ppid/find-by-id.ts
new file mode 100644
index 00000000..ce37ca84
--- /dev/null
+++ b/src/app/api/[[...slugs]]/_lib/ppid/visi_misi_ppid/visi_misi_ppid/find-by-id.ts
@@ -0,0 +1,33 @@
+import prisma from "@/lib/prisma";
+import { Context } from "elysia";
+
+export default async function visimisiPPIDFindById(context: Context) {
+ try {
+ const id = context?.params?.slugs?.[0];
+
+ // If no ID provided, get the first profile
+ if (!id) {
+ const data = await prisma.visiMisiPPID.findFirst();
+ return {
+ success: true,
+ data,
+ };
+ }
+
+ const data = await prisma.visiMisiPPID.findUniqueOrThrow({
+ where: { id },
+ });
+
+ return {
+ success: true,
+ data,
+ };
+ } catch (error) {
+ console.error("Error fetching visiPPID:", error);
+
+ return {
+ success: false,
+ message: error instanceof Error ? error.message : "Unknown error",
+ };
+ }
+}
diff --git a/src/app/api/[[...slugs]]/_lib/ppid/visi_misi_ppid/visi_misi_ppid/index.ts b/src/app/api/[[...slugs]]/_lib/ppid/visi_misi_ppid/visi_misi_ppid/index.ts
new file mode 100644
index 00000000..16be7bf7
--- /dev/null
+++ b/src/app/api/[[...slugs]]/_lib/ppid/visi_misi_ppid/visi_misi_ppid/index.ts
@@ -0,0 +1,20 @@
+import Elysia from "elysia";
+import visimisiPPIDFindById from "./find-by-id";
+import visimisiPPIDUpdate from "./update";
+import { t } from "elysia";
+
+const VisiMisiPPID = new Elysia({
+ prefix: "/visimisippid",
+ tags: ["PPID/Visi Misi PPID"]
+})
+ .get("/find-by-id", visimisiPPIDFindById)
+ .post("/update", visimisiPPIDUpdate, {
+ body: t.Object({
+ id: t.String(),
+ misi: t.String(),
+ visi: t.String(),
+ })
+ })
+
+export default VisiMisiPPID
+
\ No newline at end of file
diff --git a/src/app/api/[[...slugs]]/_lib/ppid/visi_misi_ppid/visi_misi_ppid/update.ts b/src/app/api/[[...slugs]]/_lib/ppid/visi_misi_ppid/visi_misi_ppid/update.ts
new file mode 100644
index 00000000..2c736829
--- /dev/null
+++ b/src/app/api/[[...slugs]]/_lib/ppid/visi_misi_ppid/visi_misi_ppid/update.ts
@@ -0,0 +1,32 @@
+import prisma from "@/lib/prisma";
+import { Prisma } from "@prisma/client";
+import { Context } from "elysia";
+
+type FormCreate = Prisma.VisiMisiPPIDGetPayload<{
+ select: {
+ id: true;
+ misi: true;
+ visi: true;
+ }
+}>
+export default async function visimisiPPIDUpdate(context: Context) {
+ const body = context.body as FormCreate;
+
+ await prisma.visiMisiPPID.update({
+ where: {
+ id: body.id
+ },
+ data: {
+ misi: body.misi,
+ visi: body.visi,
+ }
+ })
+
+ return {
+ success: true,
+ message: "Visi PPID Berhasil Diupdate",
+ data: {
+ ...body,
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/app/api/[[...slugs]]/route.ts b/src/app/api/[[...slugs]]/route.ts
index a8913d6d..3f2fd804 100644
--- a/src/app/api/[[...slugs]]/route.ts
+++ b/src/app/api/[[...slugs]]/route.ts
@@ -1,19 +1,24 @@
import prisma from "@/lib/prisma";
import cors, { HTTPMethod } from "@elysiajs/cors";
+import { staticPlugin } from "@elysiajs/static";
import swagger from "@elysiajs/swagger";
import { Elysia, t } from "elysia";
import fs from "fs/promises";
import path from "path";
+import Desa from "./_lib/desa";
import getPotensi from "./_lib/get-potensi";
import img from "./_lib/img";
import imgDel from "./_lib/img-del";
import imgs from "./_lib/imgs";
+import Kesehatan from "./_lib/kesehatan";
+import PPID from "./_lib/ppid";
import uplCsv from "./_lib/upl-csv";
import { uplCsvSingle } from "./_lib/upl-csv-single";
import uplImg from "./_lib/upl-img";
import { uplImgSingle } from "./_lib/upl-img-single";
-import Desa from "./_lib/desa";
-import Kesehatan from "./_lib/kesehatan";
+import FileStorage from "./_lib/fileStorage";
+
+
const ROOT = process.cwd();
if (!process.env.WIBU_UPLOAD_DIR)
@@ -45,11 +50,33 @@ async function layanan() {
const data = await prisma.layanan.findMany();
return { data };
}
+
+const Utils = new Elysia({
+ prefix: "/api/utils",
+ tags: ["Utils"],
+}).get("/version", async () => {
+ const packageJson = await fs.readFile(
+ path.join(ROOT, "package.json"),
+ "utf-8"
+ );
+ const version = JSON.parse(packageJson).version;
+ return { version };
+});
+
const ApiServer = new Elysia()
.use(swagger({ path: "/api/docs" }))
+ .use(
+ staticPlugin({
+ assets: process.env.WIBU_UPLOAD_DIR || "./uploads",
+ prefix: "/uploads",
+ })
+ )
.use(cors(corsConfig))
+ .use(PPID)
.use(Kesehatan)
.use(Desa)
+ .use(Utils)
+ .use(FileStorage)
.onError(({ code }) => {
if (code === "NOT_FOUND") {
return {
@@ -60,116 +87,116 @@ const ApiServer = new Elysia()
})
.group("/api", (app) =>
app
- .get("/layanan", layanan)
- .get("/potensi", getPotensi)
- .get(
- "/img/:name",
- ({ params, query }) => {
- return img({
- name: params.name,
- UPLOAD_DIR_IMAGE,
- ROOT,
- size: query.size,
- });
- },
- {
- params: t.Object({
- name: t.String(),
- }),
- query: t.Optional(
- t.Object({
- size: t.Optional(t.Number()),
- })
- ),
- }
- )
- .delete(
- "/img/:name",
- ({ params }) => {
- return imgDel({
- name: params.name,
- UPLOAD_DIR_IMAGE,
- });
- },
- {
- params: t.Object({
- name: t.String(),
- }),
- }
- )
- .get(
- "/imgs",
- ({ query }) => {
- return imgs({
- search: query.search,
- page: query.page,
- count: query.count,
- UPLOAD_DIR_IMAGE,
- });
- },
- {
- query: t.Optional(
- t.Object({
- page: t.Number({ default: 1 }),
- count: t.Number({ default: 10 }),
- search: t.String({ default: "" }),
- })
- ),
- }
- )
- .post(
- "/upl-img",
- ({ body }) => {
- console.log(body.title);
- return uplImg({ files: body.files, UPLOAD_DIR_IMAGE });
- },
- {
- body: t.Object({
- title: t.String(),
- files: t.Files({ multiple: true }),
- }),
- }
- )
- .post(
- "/upl-img-single",
- ({ body }) => {
- return uplImgSingle({
- fileName: body.name,
- file: body.file,
- UPLOAD_DIR_IMAGE,
- });
- },
- {
- body: t.Object({
- name: t.String(),
- file: t.File(),
- }),
- }
- )
- .post(
- "/upl-csv-single",
- ({ body }) => {
- return uplCsvSingle({ fileName: body.name, file: body.file });
- },
- {
- body: t.Object({
- name: t.String(),
- file: t.File(),
- }),
- }
- )
- .post(
- "/upl-csv",
- ({ body }) => {
- return uplCsv({ files: body.files });
- },
- {
- body: t.Object({
- files: t.Files(),
- }),
- }
- )
- );
+ .get("/layanan", layanan)
+ .get("/potensi", getPotensi)
+ .get(
+ "/img/:name",
+ ({ params, query }) => {
+ return img({
+ name: params.name,
+ UPLOAD_DIR_IMAGE,
+ ROOT,
+ size: query.size,
+ });
+ },
+ {
+ params: t.Object({
+ name: t.String(),
+ }),
+ query: t.Optional(
+ t.Object({
+ size: t.Optional(t.Number()),
+ })
+ ),
+ }
+ )
+ .delete(
+ "/img/:name",
+ ({ params }) => {
+ return imgDel({
+ name: params.name,
+ UPLOAD_DIR_IMAGE,
+ });
+ },
+ {
+ params: t.Object({
+ name: t.String(),
+ }),
+ }
+ )
+ .get(
+ "/imgs",
+ ({ query }) => {
+ return imgs({
+ search: query.search,
+ page: query.page,
+ count: query.count,
+ UPLOAD_DIR_IMAGE,
+ });
+ },
+ {
+ query: t.Optional(
+ t.Object({
+ page: t.Number({ default: 1 }),
+ count: t.Number({ default: 10 }),
+ search: t.String({ default: "" }),
+ })
+ ),
+ }
+ )
+ .post(
+ "/upl-img",
+ ({ body }) => {
+ console.log(body.title);
+ return uplImg({ files: body.files, UPLOAD_DIR_IMAGE });
+ },
+ {
+ body: t.Object({
+ title: t.String(),
+ files: t.Files({ multiple: true }),
+ }),
+ }
+ )
+ .post(
+ "/upl-img-single",
+ ({ body }) => {
+ return uplImgSingle({
+ fileName: body.name,
+ file: body.file,
+ UPLOAD_DIR_IMAGE,
+ });
+ },
+ {
+ body: t.Object({
+ name: t.String(),
+ file: t.File(),
+ }),
+ }
+ )
+ .post(
+ "/upl-csv-single",
+ ({ body }) => {
+ return uplCsvSingle({ fileName: body.name, file: body.file });
+ },
+ {
+ body: t.Object({
+ name: t.String(),
+ file: t.File(),
+ }),
+ }
+ )
+ .post(
+ "/upl-csv",
+ ({ body }) => {
+ return uplCsv({ files: body.files });
+ },
+ {
+ body: t.Object({
+ files: t.Files(),
+ }),
+ }
+ )
+);
export const GET = ApiServer.handle;
export const POST = ApiServer.handle;
diff --git a/src/app/darmasaba/(pages)/ekonomi/pasar-desa/page.tsx b/src/app/darmasaba/(pages)/ekonomi/pasar-desa/page.tsx
index 501b0b4f..3ceabef0 100644
--- a/src/app/darmasaba/(pages)/ekonomi/pasar-desa/page.tsx
+++ b/src/app/darmasaba/(pages)/ekonomi/pasar-desa/page.tsx
@@ -1,11 +1,11 @@
'use client'
import colors from '@/con/colors';
-import { Box, Button, Combobox, Flex, Group, Image, InputBase, InputPlaceholder, Paper, SimpleGrid, Stack, Text, TextInput, useCombobox } from '@mantine/core';
-import { IconArrowDown, IconMapPinFilled, IconSearch, IconShoppingCartFilled, IconStarFilled } from '@tabler/icons-react';
+import { Box, Combobox, Flex, Image, InputBase, InputPlaceholder, Paper, SimpleGrid, Stack, Text, TextInput, useCombobox } from '@mantine/core';
+import { IconMapPinFilled, IconSearch, IconShoppingCartFilled, IconStarFilled } from '@tabler/icons-react';
+import { motion } from 'motion/react';
+import { useRouter } from 'next/navigation';
import { useState } from 'react';
import BackButton from '../../desa/layanan/_com/BackButto';
-import { useRouter } from 'next/navigation';
-import { motion } from 'motion/react';
const groceries = [
'Makanan',
@@ -170,9 +170,6 @@ function Page() {
)
})}
-
- } fz={'md'}>Lihat Produk Lainnya
-
diff --git a/src/app/darmasaba/(pages)/ppid/daftar-informasi-publik-desa-darmasaba/page.tsx b/src/app/darmasaba/(pages)/ppid/daftar-informasi-publik-desa-darmasaba/page.tsx
index 82768a10..ba894c94 100644
--- a/src/app/darmasaba/(pages)/ppid/daftar-informasi-publik-desa-darmasaba/page.tsx
+++ b/src/app/darmasaba/(pages)/ppid/daftar-informasi-publik-desa-darmasaba/page.tsx
@@ -1,50 +1,27 @@
+'use client'
+import stateDaftarInformasiPublik from '@/app/admin/(dashboard)/_state/ppid/daftar_informasi_publik/daftarInformasiPublik';
import colors from '@/con/colors';
-import { Stack, Box, Text, Center, Image, TextInput, TableTd, TableTr, TableTbody, TableTh, TableThead, Table, ActionIcon } from '@mantine/core';
-import React from 'react';
+import { Box, Center, Image, Skeleton, Stack, Table, TableTbody, TableTd, TableTh, TableThead, TableTr, Text, TextInput } from '@mantine/core';
+import { useShallowEffect } from '@mantine/hooks';
+import { IconSearch } from '@tabler/icons-react';
+import { useProxy } from 'valtio/utils';
import BackButton from '../../desa/layanan/_com/BackButto';
-import { IconDownload, IconSearch } from '@tabler/icons-react';
-const dataTable = [
- {
- id: 1,
- nomer: '1',
- jenis: "Peraturan Desa",
- deskripsi: "Dokumen yang berisi kebijakan dan regulasi desa",
- tanggal: "15 Januari 2024",
- unduh:
- },
- {
- id: 2,
- nomer: '2',
- jenis: "Laporan Keuangan",
- deskripsi: "Laporan Kegunaan anggaran desa secara transparan",
- tanggal: "20 Januari 2024",
- unduh:
- },
- {
- id: 3,
- nomer: '3',
- jenis: "Program & Kegiatan",
- deskripsi: "Informasi mengenai program pembangunan & kegiatan desa",
- tanggal: "30 Januari 2024",
- unduh:
- },
-
-]
function Page() {
- const rows = dataTable.map((element) => (
-
- {element.nomer}
- {element.jenis}
- {element.deskripsi}
- {element.tanggal}
-
-
- {element.unduh}
-
-
-
- ))
+ const listData = useProxy(stateDaftarInformasiPublik.daftarInformasi)
+ useShallowEffect(() => {
+ listData.findMany.load()
+ }, [])
+ if (!listData.findMany.data) return
+
+
+
+
+
+
+
+
+
return (
@@ -71,10 +48,18 @@ function Page() {
Jenis Informasi
Deskripsi
Tanggal Publikasi
- Unduh
- {rows}
+
+ {listData.findMany.data?.map((item) => (
+
+ {item.nomor}
+ {item.jenisInformasi}
+
+ {item.tanggal}
+
+ ))}
+
Kontak PPID
diff --git a/src/app/darmasaba/(pages)/ppid/ikm-desa-darmasaba/grafik_berdasarkan_jenis_kelamin/page.tsx b/src/app/darmasaba/(pages)/ppid/ikm-desa-darmasaba/grafik_berdasarkan_jenis_kelamin/page.tsx
new file mode 100644
index 00000000..977ec842
--- /dev/null
+++ b/src/app/darmasaba/(pages)/ppid/ikm-desa-darmasaba/grafik_berdasarkan_jenis_kelamin/page.tsx
@@ -0,0 +1,87 @@
+/* eslint-disable @typescript-eslint/no-explicit-any */
+'use client'
+import React, { useEffect, useState } from 'react';
+import { Box, Center, Flex, Skeleton, Stack, Text, Title } from '@mantine/core';
+import { Cell, Pie, PieChart } from 'recharts';
+import colors from '@/con/colors';
+import { useShallowEffect } from '@mantine/hooks';
+import { useProxy } from 'valtio/utils';
+import stateGrafikBerdasarkanJenisKelamin from '@/app/admin/(dashboard)/_state/ppid/indeks_kepuasan_masyarakat/grafikBerdasarkanJenisKelamin';
+
+function GrafikBerdasarkanJenisKelamin() {
+ const grafikBerdasarkanJenisKelamin = useProxy(stateGrafikBerdasarkanJenisKelamin.grafikBerdasarkanJenisKelamin)
+ const [mounted, setMounted] = useState(false);
+ const [donutData, setDonutData] = useState([]);
+
+ useEffect(() => {
+ setMounted(true);
+ }, [])
+
+ const updateChartData = (data: any) => {
+ if (data && data.length > 0) {
+ const totalLaki = data.reduce((acc: number, cur: any) => acc + Number(cur.laki || 0), 0);
+ const totalPerempuan = data.reduce((acc: number, cur: any) => acc + Number(cur.perempuan || 0), 0);
+
+ setDonutData([
+ { name: 'Laki-laki', value: totalLaki, color: colors['blue-button'], key: 'laki-laki' },
+ { name: 'Perempuan', value: totalPerempuan, color: '#FF6384', key: 'perempuan' }
+ ]);
+ }
+ };
+
+ useShallowEffect(() => {
+ fetchData();
+ }, []);
+
+ const fetchData = async () => {
+ await grafikBerdasarkanJenisKelamin.findMany.load();
+ if (grafikBerdasarkanJenisKelamin.findMany.data) {
+ updateChartData(grafikBerdasarkanJenisKelamin.findMany.data);
+ }
+ };
+
+ if(!grafikBerdasarkanJenisKelamin.findMany.data) return
+ Grafik Berdasarkan Jenis Kelamin Responden
+
+
+
+ return (
+
+ Grafik Berdasarkan Jenis Kelamin Responden
+ {mounted && donutData.length > 0 && (
+
+
+
+
+
+ {donutData.map((entry, index) => (
+ |
+ ))}
+
+
+
+
+
+ Perempuan: {donutData.find((entry) => entry.name === 'Perempuan')?.value}
+
+
+
+ Laki-laki: {donutData.find((entry) => entry.name === 'Laki-laki')?.value}
+
+
+ )}
+
+ );
+}
+
+export default GrafikBerdasarkanJenisKelamin;
diff --git a/src/app/darmasaba/(pages)/ppid/ikm-desa-darmasaba/grafik_berdasarkan_pilihan_responden/page.tsx b/src/app/darmasaba/(pages)/ppid/ikm-desa-darmasaba/grafik_berdasarkan_pilihan_responden/page.tsx
new file mode 100644
index 00000000..57a14c08
--- /dev/null
+++ b/src/app/darmasaba/(pages)/ppid/ikm-desa-darmasaba/grafik_berdasarkan_pilihan_responden/page.tsx
@@ -0,0 +1,96 @@
+/* eslint-disable @typescript-eslint/no-explicit-any */
+'use client'
+import stateGrafikResponden from '@/app/admin/(dashboard)/_state/ppid/indeks_kepuasan_masyarakat/grafikBerdasarkanResponden';
+import colors from '@/con/colors';
+import { Stack, Title, Box, Center, Flex, Text, Skeleton } from '@mantine/core';
+import { useShallowEffect } from '@mantine/hooks';
+import React, { useEffect, useState } from 'react';
+import { PieChart, Pie, Cell } from 'recharts';
+import { useProxy } from 'valtio/utils';
+
+function GrafikBerdasarkanResponden() {
+ const grafikBerdasarkanResponden = useProxy(stateGrafikResponden.grafikBerdasarkanResponden)
+ const [donutData, setDonutData] = useState([]);
+ const [mounted, setMounted] = useState(false);
+
+ useEffect(() => {
+ setMounted(true);
+ }, [])
+
+ const updateChartData = (data: any) => {
+ if (data && data.length > 0) {
+ const totalSangatBaik = data.reduce((acc: number, cur: any) => acc + Number(cur.sangatbaik || 0), 0);
+ const totalBaik = data.reduce((acc: number, cur: any) => acc + Number(cur.baik || 0), 0);
+ const totalKurangBaik = data.reduce((acc: number, cur: any) => acc + Number(cur.kurangbaik || 0), 0);
+ const totalTidakBaik = data.reduce((acc: number, cur: any) => acc + Number(cur.tidakbaik || 0), 0);
+ setDonutData([
+ { name: 'sangatbaik', value: totalSangatBaik, color: colors['blue-button'], key: 'sangatbaik' },
+ { name: 'baik', value: totalBaik, color: '#10A85AFF', key: 'baik' },
+ { name: 'kurangbaik', value: totalKurangBaik, color: '#B3AA12FF', key: 'kurangbaik' },
+ { name: 'tidakbaik', value: totalTidakBaik, color: '#B21313FF', key: 'tidakbaik' }
+ ]);
+ }
+ };
+
+ useShallowEffect(() => {
+ fetchData();
+ }, []);
+
+ const fetchData = async () => {
+ await grafikBerdasarkanResponden.findMany.load();
+ if (grafikBerdasarkanResponden.findMany.data) {
+ updateChartData(grafikBerdasarkanResponden.findMany.data);
+ }
+ };
+
+ if (!grafikBerdasarkanResponden.findMany.data) return
+ Grafik Berdasarkan Responden
+
+
+ return (
+
+ Grafik Berdasarkan Responden
+ {mounted && donutData.length > 0 && (
+
+
+
+
+ {donutData.map((entry, index) => (
+ |
+ ))}
+
+
+
+
+
+ Sangat Baik: {donutData.find((entry) => entry.name === 'sangatbaik')?.value}
+
+
+
+ Baik: {donutData.find((entry) => entry.name === 'baik')?.value}
+
+
+
+ Kurang Baik: {donutData.find((entry) => entry.name === 'kurangbaik')?.value}
+
+
+
+ Tidak Baik: {donutData.find((entry) => entry.name === 'tidakbaik')?.value}
+
+
+ )}
+
+ );
+}
+
+export default GrafikBerdasarkanResponden;
diff --git a/src/app/darmasaba/(pages)/ppid/ikm-desa-darmasaba/grafik_berdasarkan_umur_responden/page.tsx b/src/app/darmasaba/(pages)/ppid/ikm-desa-darmasaba/grafik_berdasarkan_umur_responden/page.tsx
new file mode 100644
index 00000000..e1786eaa
--- /dev/null
+++ b/src/app/darmasaba/(pages)/ppid/ikm-desa-darmasaba/grafik_berdasarkan_umur_responden/page.tsx
@@ -0,0 +1,97 @@
+/* eslint-disable @typescript-eslint/no-explicit-any */
+'use client'
+import stateGrafikBerdasarkanUmur from '@/app/admin/(dashboard)/_state/ppid/indeks_kepuasan_masyarakat/grafikBerdasarkanUmur';
+import colors from '@/con/colors';
+import { Stack, Title, Box, Center, Flex, Text, Skeleton } from '@mantine/core';
+import { useShallowEffect } from '@mantine/hooks';
+import React, { useEffect, useState } from 'react';
+import { PieChart, Pie, Cell } from 'recharts';
+import { useProxy } from 'valtio/utils';
+
+function GrafikBerdasarakanUmur() {
+ const grafikBerdasarkanUmur = useProxy(stateGrafikBerdasarkanUmur.grafikBerdasarkanUmur)
+ const [donutData, setDonutData] = useState([]);
+ const [mounted, setMounted] = useState(false);
+
+ useEffect(() => {
+ setMounted(true);
+ }, []);
+
+ const updateChartData = (data: any) => {
+ if (data && data.length > 0) {
+ const totalRemaja = data.reduce((acc: number, cur: any) => acc + Number(cur.remaja || 0), 0);
+ const totalDewasa = data.reduce((acc: number, cur: any) => acc + Number(cur.dewasa || 0), 0);
+ const totalOrangtua = data.reduce((acc: number, cur: any) => acc + Number(cur.orangtua || 0), 0);
+ const totalLansia = data.reduce((acc: number, cur: any) => acc + Number(cur.lansia || 0), 0);
+
+ setDonutData([
+ { name: 'Remaja', value: totalRemaja, color: colors['blue-button'], key: 'remaja' },
+ { name: 'Dewasa', value: totalDewasa, color: '#D32711FF', key: 'dewasa' },
+ { name: 'Orangtua', value: totalOrangtua, color: '#B46B04FF', key: 'orangtua' },
+ { name: 'Lansia', value: totalLansia, color: '#038617FF', key: 'lansia' }
+ ]);
+ }
+ };
+
+ useShallowEffect(() => {
+ fetchData();
+ }, []);
+
+ const fetchData = async () => {
+ await grafikBerdasarkanUmur.findMany.load();
+ if (grafikBerdasarkanUmur.findMany.data) {
+ updateChartData(grafikBerdasarkanUmur.findMany.data);
+ }
+ }
+
+ if(!grafikBerdasarkanUmur.findMany.data) return
+ Grafik Berdasarkan Umur Responden
+
+
+ return (
+
+ Grafik Berdasarkan Umur Responden
+ {mounted && donutData.length > 0 && (
+
+
+
+
+ {donutData.map((entry, index) => (
+ |
+ ))}
+
+
+
+
+
+ 17 - 25 tahun: {donutData.find((entry) => entry.name === 'remaja')?.value}
+
+
+
+ 26 - 45 tahun: {donutData.find((entry) => entry.name === 'dewasa')?.value}
+
+
+
+ 46 - 60 tahun: {donutData.find((entry) => entry.name === 'orangtua')?.value}
+
+
+
+ di atas 60 tahun: {donutData.find((entry) => entry.name === 'lansia')?.value}
+
+
+ )}
+
+ );
+}
+
+export default GrafikBerdasarakanUmur;
diff --git a/src/app/darmasaba/(pages)/ppid/ikm-desa-darmasaba/grafik_hasil_kepuasan_masyarakat/page.tsx b/src/app/darmasaba/(pages)/ppid/ikm-desa-darmasaba/grafik_hasil_kepuasan_masyarakat/page.tsx
new file mode 100644
index 00000000..d504cbb1
--- /dev/null
+++ b/src/app/darmasaba/(pages)/ppid/ikm-desa-darmasaba/grafik_hasil_kepuasan_masyarakat/page.tsx
@@ -0,0 +1,57 @@
+/* eslint-disable @typescript-eslint/no-explicit-any */
+'use client'
+import stateGrafikHasilKepuasanMasyarakat from '@/app/admin/(dashboard)/_state/ppid/indeks_kepuasan_masyarakat/grafikHasilKepuasan';
+import colors from '@/con/colors';
+import { Box, Skeleton, Stack, Text, Title } from '@mantine/core';
+import { useMediaQuery, useShallowEffect } from '@mantine/hooks';
+import React, { useEffect, useState } from 'react';
+import { BarChart, Tooltip, XAxis, YAxis, Legend, Bar } from 'recharts';
+import { useProxy } from 'valtio/utils';
+
+function GrafikHasilKepuasan() {
+ const grafikHasilKepuasan = useProxy(stateGrafikHasilKepuasanMasyarakat.grafikHasilKepuasanMasyarakat)
+ const [chartData, setChartData] = useState([]);
+ const [mounted, setMounted] = useState(false);
+ const isTablet = useMediaQuery('(max-width: 1024px)')
+ const isMobile = useMediaQuery('(max-width: 768px)')
+
+ useEffect(() => {
+ setMounted(true);
+ }, [])
+
+ useShallowEffect(() => {
+ const fetchData = async () => {
+ await grafikHasilKepuasan.findMany.load();
+ if (grafikHasilKepuasan.findMany.data && grafikHasilKepuasan.findMany.data.length > 0) {
+ setChartData(grafikHasilKepuasan.findMany.data);
+ }
+ };
+ fetchData();
+ }, []);
+
+ if(!grafikHasilKepuasan.findMany.data) return
+ Grafik Hasil Kepuasan Masyarakat Terhadap Pelayanan Publik
+
+
+
+ return (
+
+
+ Grafik Hasil Kepuasan Masyarakat Terhadap Pelayanan Publik
+
+
+ {mounted && chartData.length > 0 && (
+
+
+
+
+
+
+
+ )}
+
+
+ );
+}
+
+export default GrafikHasilKepuasan;
diff --git a/src/app/darmasaba/(pages)/ppid/ikm-desa-darmasaba/page.tsx b/src/app/darmasaba/(pages)/ppid/ikm-desa-darmasaba/page.tsx
index 5f20eafc..13ffbee0 100644
--- a/src/app/darmasaba/(pages)/ppid/ikm-desa-darmasaba/page.tsx
+++ b/src/app/darmasaba/(pages)/ppid/ikm-desa-darmasaba/page.tsx
@@ -1,38 +1,11 @@
import colors from '@/con/colors';
-import { Stack, Box, Paper, Text, Center, Flex, ColorSwatch, } from '@mantine/core';
-import React from 'react';
+import { Box, Paper, Stack, Text } from '@mantine/core';
import BackButton from '../../desa/layanan/_com/BackButto';
-import { BarChart, DonutChart } from '@mantine/charts';
+import GrafikBerdasarkanJenisKelamin from './grafik_berdasarkan_jenis_kelamin/page';
+import GrafikBerdasarkanResponden from './grafik_berdasarkan_pilihan_responden/page';
+import GrafikBerdasarakanUmur from './grafik_berdasarkan_umur_responden/page';
+import GrafikHasilKepuasan from './grafik_hasil_kepuasan_masyarakat/page';
-const dataBar = [
- { pelayanan: 'Persyaratan', kepuasan: 90 },
- { pelayanan: 'Prosedur', kepuasan: 98 },
- { pelayanan: 'Kecepatan', kepuasan: 92 },
- { pelayanan: 'Biaya / Tarif', kepuasan: 85 },
- { pelayanan: 'Produk Layanan', kepuasan: 89 },
- { pelayanan: 'Kompetensi Pelaksana', kepuasan: 91 },
- { pelayanan: 'Perilaku Pelaksana', kepuasan: 90 },
- { pelayanan: 'Penanganan Pengaduan', kepuasan: 93 },
- { pelayanan: 'Sarana dan Prasarana', kepuasan: 91 },
-]
-const dataJenisKelamin = [
- { name: 'Perempuan', value: 90, color: '#3291CB' },
- { name: 'Laki - Laki', value: 10, color: colors['blue-button'] },
-]
-const dataResponden = [
- { name: 'Sangat Baik', value: 60, color: 'green' },
- { name: 'Baik', value: 20, color: 'blue' },
- { name: 'Kurang Baik', value: 10, color: 'orange' },
- { name: 'Tidak Baik', value: 10, color: 'red' },
-
-]
-const dataUmur = [
- { name: '17 - 25 tahun', value: 60, color: 'green' },
- { name: '26 - 45 tahun', value: 20, color: 'blue' },
- { name: '46 - 60 tahun', value: 10, color: 'orange' },
- { name: 'di atas 60 tahun', value: 10, color: 'red' },
-
-]
function Page() {
return (
@@ -48,116 +21,23 @@ function Page() {
-
-
- Grafik Hasil Kepuasan Masyarakat Terhadap Pelayanan Publik
-
-
+
+
-
- Grafik Berdasarkan Jenis Kelamin Responden
-
-
-
-
-
-
-
- Perempuan
-
-
-
-
-
- Laki - Laki
-
-
-
-
+
-
- Grafik Berdasarkan Pilihan Responden
-
-
-
-
-
-
-
- Sangat Baik
-
-
-
-
-
- Baik
-
-
-
-
-
- Kurang Baik
-
-
-
-
-
- Tidak Baik
-
-
-
-
+
-
- Grafik Berdasarkan Umur Responden
-
-
-
-
-
-
-
- 17 – 25 tahun
-
-
-
-
-
- 26 – 45 tahun
-
-
-
-
-
- 46 – 60 tahun
-
-
-
-
-
- di atas 60 tahun
-
-
-
-
+
diff --git a/src/app/darmasaba/(pages)/ppid/permohonan-informasi-publik/jenis_infromasi/jenisInformasiSelector.tsx b/src/app/darmasaba/(pages)/ppid/permohonan-informasi-publik/jenis_infromasi/jenisInformasiSelector.tsx
new file mode 100644
index 00000000..3b81266f
--- /dev/null
+++ b/src/app/darmasaba/(pages)/ppid/permohonan-informasi-publik/jenis_infromasi/jenisInformasiSelector.tsx
@@ -0,0 +1,48 @@
+// components/jenisInformasiSelector.tsx
+'use client';
+import { Skeleton, Group, Select } from '@mantine/core';
+import { useShallowEffect } from '@mantine/hooks';
+import { Prisma } from '@prisma/client';
+import React from 'react';
+import { useProxy } from 'valtio/utils';
+import statePermohonanInformasi from '@/app/admin/(dashboard)/_state/ppid/permohonan_informasi_publik/permohonanInformasiPublik';
+
+export default function JenisInformasiSelector({ onChange }: {
+ onChange: (value: Prisma.JenisInformasiDimintaGetPayload<{
+ select: {
+ id: true;
+ name: true
+ }
+ }>) => void;
+}) {
+ const jenisInformasiState = useProxy(statePermohonanInformasi);
+
+ useShallowEffect(() => {
+ jenisInformasiState.jenisInformasiDiminta.findMany.load();
+ }, []);
+
+ if (!jenisInformasiState.jenisInformasiDiminta.findMany.data) {
+ return ;
+ }
+
+ // Add a check for data before mapping
+ const data = jenisInformasiState.jenisInformasiDiminta.findMany.data;
+ if (!data) return ;
+
+ return (
+
+ ({
+ value: item.id,
+ label: item.name,
+ }))}
+ onChange={(v) => {
+ const selectedData = data.find((item) => item.id === v);
+ if (selectedData) onChange(selectedData);
+ }}
+ />
+
+ );
+}
diff --git a/src/app/darmasaba/(pages)/ppid/permohonan-informasi-publik/memperoleh_informasi/memperolehInfromasi.tsx b/src/app/darmasaba/(pages)/ppid/permohonan-informasi-publik/memperoleh_informasi/memperolehInfromasi.tsx
new file mode 100644
index 00000000..e521caf0
--- /dev/null
+++ b/src/app/darmasaba/(pages)/ppid/permohonan-informasi-publik/memperoleh_informasi/memperolehInfromasi.tsx
@@ -0,0 +1,46 @@
+import statePermohonanInformasi from '@/app/admin/(dashboard)/_state/ppid/permohonan_informasi_publik/permohonanInformasiPublik';
+import { Group, Select, Skeleton } from '@mantine/core';
+import { useShallowEffect } from '@mantine/hooks';
+import { Prisma } from '@prisma/client';
+import React from 'react';
+import { useProxy } from 'valtio/utils';
+
+function MemperolehInformasi({ onChange }: {
+ onChange: (value: Prisma.CaraMemperolehInformasiGetPayload<{
+ select: {
+ id: true,
+ name: true
+ }
+ }>) => void
+}) {
+ const memperolehInformasiState = useProxy(statePermohonanInformasi)
+
+ useShallowEffect(() => {
+ memperolehInformasiState.caraMemperolehInformasi.findMany.load()
+ }, [])
+
+ if (!memperolehInformasiState.caraMemperolehInformasi.findMany.data)
+ return
+
+ const data = memperolehInformasiState.caraMemperolehInformasi.findMany.data;
+ if (!data) return
+
+ return (
+
+ ({
+ value: item.id,
+ label: item.name,
+ }))}
+ onChange={(v) => {
+ const selectedData = data.find((item) => item.id === v);
+ if (selectedData) onChange(selectedData);
+ }}
+ />
+
+ );
+}
+
+export default MemperolehInformasi;
diff --git a/src/app/darmasaba/(pages)/ppid/permohonan-informasi-publik/page.tsx b/src/app/darmasaba/(pages)/ppid/permohonan-informasi-publik/page.tsx
index 229acb31..894e9110 100644
--- a/src/app/darmasaba/(pages)/ppid/permohonan-informasi-publik/page.tsx
+++ b/src/app/darmasaba/(pages)/ppid/permohonan-informasi-publik/page.tsx
@@ -1,123 +1,39 @@
'use client'
+import statePermohonanInformasi from '@/app/admin/(dashboard)/_state/ppid/permohonan_informasi_publik/permohonanInformasiPublik';
import colors from '@/con/colors';
-import { ActionIcon, Box, Button, Center, Checkbox, Combobox, ComboboxOption, Group, Input, InputBase, Paper, SimpleGrid, Stack, Text, Textarea, TextInput, useCombobox } from '@mantine/core';
+import { ActionIcon, Box, Button, Center, Checkbox, Group, Paper, SimpleGrid, Stack, Text, TextInput } from '@mantine/core';
import { IconDownload } from '@tabler/icons-react';
-import BackButton from '../../desa/layanan/_com/BackButto';
import { useRouter } from 'next/navigation';
-import { useState } from 'react';
+import { useProxy } from 'valtio/utils';
+import BackButton from '../../desa/layanan/_com/BackButto';
+import JenisInformasiSelector from './jenis_infromasi/jenisInformasiSelector';
+import MemperolehInformasi from './memperoleh_informasi/memperolehInfromasi';
+import MemperolehSalinan from './salinan_informasi/salinanInformasi';
const data = [
- {
- id: 1,
- number: '1',
- title: "Langkah 1",
- desc: "Pemohon informasi publik mengajukan permohonan informasi kepada badan publik baik langsung maupun melalui surat elektronik",
- },
- {
- id: 2,
- number: '2',
- title: "Langkah 2",
- desc: "Isi formulir permohonan informasi dengan data diri (nama, alamat, telepon), jenis, format, dan cara penyampaian informasi, serta lampiran fotokopi kartu identitas.",
- },
- {
- id: 3,
- number: '3',
- title: "Langkah 3",
- desc: "PPID akan memproses permohonan sesuai dengan ketentuan",
- },
- {
- id: 4,
- number: '4',
- title: "Langkah 4",
- desc: "Petugas PPID menyampaikan informasi sesuai permohonan kepada pemohon informasi.",
- },
-]
+ { id: 1, number: '1', title: "Langkah 1", desc: "Pemohon informasi publik mengajukan permohonan informasi kepada badan publik baik langsung maupun melalui surat elektronik" },
+ { id: 2, number: '2', title: "Langkah 2", desc: "Isi formulir permohonan informasi dengan data diri (nama, alamat, telepon), jenis, format, dan cara penyampaian informasi, serta lampiran fotokopi kartu identitas." },
+ { id: 3, number: '3', title: "Langkah 3", desc: "PPID akan memproses permohonan sesuai dengan ketentuan" },
+ { id: 4, number: '4', title: "Langkah 4", desc: "Petugas PPID menyampaikan informasi sesuai permohonan kepada pemohon informasi." },
+];
-const jenisInformasi = [
- {
- id: 1,
- jenis: 'Keuangan Desa'
- },
- {
- id: 2,
- jenis: 'Pembangunan Desa'
- },
- {
- id: 3,
- jenis: 'Data Demografi'
- },
- {
- id: 4,
- jenis: 'Lainnya'
- },
-]
-
-const memperolehInformasi = [
- {
- id: 1,
- jenis: 'Melihat/Membaca/Mendengarkan/Mencatat'
- },
- {
- id: 2,
- jenis: 'Mendapatkan Salinan Informasi (Hardcopy)'
- },
- {
- id: 3,
- jenis: 'Mendapatkan Salinan Informasi (Softcopy)'
- }
-]
-
-const mendapatkanInformasi = [
- {
- id: 1,
- jenis: 'Mengambil Langsung'
- },
- {
- id: 2,
- jenis: 'Dikirim via Post'
- },
- {
- id: 3,
- jenis: 'Dikirim via Email'
- }
-]
function Page() {
- const combobox = useCombobox({
- onDropdownClose: () => combobox.resetSelectedOption(),
- });
+ const permohonanInformasiPublikState = useProxy(statePermohonanInformasi);
+ const router = useRouter();
- const combobox2 = useCombobox({
- onDropdownClose: () => combobox2.resetSelectedOption(),
- });
+ const submitForms = () => {
+ const { create } = permohonanInformasiPublikState.statepermohonanInformasiPublik;
- const combobox3 = useCombobox({
- onDropdownClose: () => combobox3.resetSelectedOption(),
- });
+ if (create.form.name && create.form.nik && create.form.notelp && create.form.alamat && create.form.email &&
+ create.form.jenisInformasiDimintaId && create.form.caraMemperolehInformasiId && create.form.caraMemperolehSalinanInformasiId) {
+ create.create();
+ router.push('/darmasaba/permohonan/berhasil');
+ } else {
+ console.log("Validasi gagal, form tidak lengkap");
+ // Display error message to user
+ }
+ };
- const [value, setValue] = useState(null);
- const [value2, setValue2] = useState(null);
- const [value3, setValue3] = useState(null);
-
-
-
- const options = jenisInformasi.map((item) => (
-
- {item.jenis}
-
- ))
-
- const options2 = memperolehInformasi.map((item) => (
-
- {item.jenis}
-
- ))
-
- const options3 = mendapatkanInformasi.map((item) => (
-
- {item.jenis}
-
- ))
- const router = useRouter()
return (
@@ -130,33 +46,20 @@ function Page() {
Tata Cara Permohonan
-
- {data.map((v, k) => {
- return (
-
-
-
-
- {v.number}
-
-
-
- {v.title}
-
-
- {v.desc}
-
-
-
- )
- })}
+
+ {data.map((v, k) => (
+
+
+
+
+ {v.number}
+
+
+ {v.title}
+ {v.desc}
+
+
+ ))}
}>
@@ -165,132 +68,45 @@ function Page() {
- Formulir Permohonan Informasi
-
-
-
-
-
-
- {/* ComboBox */}
-
- Jenis Informasi yang diminta
- {
- setValue(val);
- combobox.closeDropdown();
+
+ Formulir Permohonan Informasi
+ {
+ permohonanInformasiPublikState.statepermohonanInformasiPublik.create.form.name = val.target.value;
+ }} />
+ {
+ permohonanInformasiPublikState.statepermohonanInformasiPublik.create.form.nik = val.target.value;
+ }} />
+ {
+ permohonanInformasiPublikState.statepermohonanInformasiPublik.create.form.notelp = val.target.value;
+ }} />
+ {
+ permohonanInformasiPublikState.statepermohonanInformasiPublik.create.form.alamat = val.target.value;
+ }} />
+ {
+ permohonanInformasiPublikState.statepermohonanInformasiPublik.create.form.email = val.target.value;
+ }} />
+ {
+ permohonanInformasiPublikState.statepermohonanInformasiPublik.create.form.jenisInformasiDimintaId = val.id;
}}
- >
-
- }
- onClick={() => combobox.toggleDropdown()}
- rightSectionPointerEvents="none"
- >
- {value || --Pilih Jenis Informasi-- }
-
-
-
-
- {options}
-
-
-
-
- {/* ComboBox2 */}
-
- Cara Memperoleh Informasi
- {
- setValue2(val);
- combobox2.closeDropdown();
- }}
- >
-
- }
- onClick={() => combobox2.toggleDropdown()}
- rightSectionPointerEvents="none"
- >
- {value2 || --Pilih Cara Memperoleh-- }
-
-
-
-
- {options2}
-
-
-
- {/* ComboBox3 */}
-
- Cara Mendapatkan Salinan Informasi
- {
- setValue3(val);
- combobox3.closeDropdown();
- }}
- >
-
- }
- onClick={() => combobox3.toggleDropdown()}
- rightSectionPointerEvents="none"
- >
- {value3 || --Pilih Cara Mendapatkan-- }
-
-
-
-
- {options3}
-
-
-
-
-
-
- router.push('/darmasaba/permohonan/berhasil')} bg={"green"} fullWidth>
- Kirim Permohonan
-
+ {
+ permohonanInformasiPublikState.statepermohonanInformasiPublik.create.form.caraMemperolehInformasiId = val.id;
+ }}
+ />
+ {
+ permohonanInformasiPublikState.statepermohonanInformasiPublik.create.form.caraMemperolehSalinanInformasiId = val.id;
+ }}
+ />
+
+
+
+
+ Kirim Permohonan
+
+
@@ -300,4 +116,4 @@ function Page() {
);
}
-export default Page;
+export default Page;
\ No newline at end of file
diff --git a/src/app/darmasaba/(pages)/ppid/permohonan-informasi-publik/salinan_informasi/salinanInformasi.tsx b/src/app/darmasaba/(pages)/ppid/permohonan-informasi-publik/salinan_informasi/salinanInformasi.tsx
new file mode 100644
index 00000000..c88dda51
--- /dev/null
+++ b/src/app/darmasaba/(pages)/ppid/permohonan-informasi-publik/salinan_informasi/salinanInformasi.tsx
@@ -0,0 +1,43 @@
+import statePermohonanInformasi from '@/app/admin/(dashboard)/_state/ppid/permohonan_informasi_publik/permohonanInformasiPublik';
+import { Skeleton, Group, Select } from '@mantine/core';
+import { useShallowEffect } from '@mantine/hooks';
+import { Prisma } from '@prisma/client';
+import React from 'react';
+import { useProxy } from 'valtio/utils';
+
+function MemperolehSalinan({ onChange }: {
+ onChange: (value: Prisma.CaraMemperolehSalinanInformasiGetPayload<{
+ select: {
+ id: true,
+ name: true
+ }
+ }>) => void
+}) {
+ const memperolehSalinanInformasiState = useProxy(statePermohonanInformasi)
+ useShallowEffect(() => {
+ memperolehSalinanInformasiState.caraMemperolehSalinanInformasi.findMany.load()
+ }, [])
+
+ if (!memperolehSalinanInformasiState.caraMemperolehSalinanInformasi.findMany.data) return
+
+ const data = memperolehSalinanInformasiState.caraMemperolehSalinanInformasi.findMany.data
+ if (!data) return
+
+ return (
+
+ ({
+ value: item.id,
+ label: item.name,
+ }))}
+ onChange={(v) => {
+ const selectedData = data.find((item) => item.id === v);
+ if (selectedData) onChange(selectedData);
+ }}
+ />
+
+ );
+}
+export default MemperolehSalinan;
diff --git a/src/app/darmasaba/(pages)/ppid/permohonan-keberatan-informasi-publik/page.tsx b/src/app/darmasaba/(pages)/ppid/permohonan-keberatan-informasi-publik/page.tsx
index 691ebcd7..43a56543 100644
--- a/src/app/darmasaba/(pages)/ppid/permohonan-keberatan-informasi-publik/page.tsx
+++ b/src/app/darmasaba/(pages)/ppid/permohonan-keberatan-informasi-publik/page.tsx
@@ -1,9 +1,12 @@
'use client'
+import permohonanKeberatanInformasi from '@/app/admin/(dashboard)/_state/ppid/permohonan_keberatan_informasi_publik/permohonanKeberatanInformasi';
+import { PPIDTextEditor } from '@/app/admin/(dashboard)/ppid/_com/PPIDTextEditor';
import colors from '@/con/colors';
-import { Box, Button, Center, Group, Paper, SimpleGrid, Stack, Text, Textarea, TextInput } from '@mantine/core';
+import { Box, Button, Center, Group, Paper, SimpleGrid, Stack, Text, TextInput } from '@mantine/core';
import { IconFileCheck, IconForms, IconHourglassOff, IconPhoneRinging } from '@tabler/icons-react';
-import BackButton from '../../desa/layanan/_com/BackButto';
import { useRouter } from 'next/navigation';
+import { useProxy } from 'valtio/utils';
+import BackButton from '../../desa/layanan/_com/BackButto';
const data = [
{
@@ -32,6 +35,15 @@ const data = [
},
]
function Page() {
+ const stateKeberatan = useProxy(permohonanKeberatanInformasi)
+ const submit = () => {
+ if (stateKeberatan.create.form.name && stateKeberatan.create.form.email && stateKeberatan.create.form.notelp && stateKeberatan.create.form.alasan) {
+ stateKeberatan.create.create()
+ router.push('/darmasaba/permohonan/berhasil')
+ } else {
+ console.log("Validasi gagal, form tidak lengkap")
+ }
+ }
const router = useRouter();
return (
@@ -76,33 +88,41 @@ function Page() {
- Formulir Permohonan Keberatan
-
-
-
-
- router.push('/darmasaba/permohonan/berhasil')} bg={"green"} fullWidth>
- Kirim Permohonan
-
+
+ Formulir Permohonan Keberatan
+ {
+ stateKeberatan.create.form.name = val.target.value
+ }}
+ />
+ {
+ stateKeberatan.create.form.email = val.target.value
+ }}
+ />
+ {
+ stateKeberatan.create.form.notelp = val.target.value
+ }}
+ />
+ Alasan Permohonan Keberatan
+ {
+ stateKeberatan.create.form.alasan = val
+ }}
+
+ />
+
+ Kirim Permohonan
+
+
Kontak PPID
diff --git a/src/app/darmasaba/(pages)/ppid/profile-ppid/page.tsx b/src/app/darmasaba/(pages)/ppid/profile-ppid/page.tsx
index 73c06f04..136c7ce7 100644
--- a/src/app/darmasaba/(pages)/ppid/profile-ppid/page.tsx
+++ b/src/app/darmasaba/(pages)/ppid/profile-ppid/page.tsx
@@ -1,9 +1,37 @@
+'use client'
+import stateProfilePPID from '@/app/admin/(dashboard)/_state/ppid/profile_ppid/profile_PPID';
import colors from '@/con/colors';
-import { Stack, Box, Text, Paper, Flex, Image, Divider, Center, SimpleGrid, List, ListItem } from '@mantine/core';
-import React from 'react';
+import { Box, Center, Divider, Flex, Image, List, Paper, SimpleGrid, Skeleton, Stack, Text } from '@mantine/core';
+import { useShallowEffect } from '@mantine/hooks';
+import { useProxy } from 'valtio/utils';
import BackButton from '../../desa/layanan/_com/BackButto';
function Page() {
+ const allList = useProxy(stateProfilePPID)
+ useShallowEffect(() => {
+ allList.findById.load("1") // Assuming "1" is your default ID, adjust as needed
+ }, [])
+
+ if (!allList.findById.data) return
+
+
+
+
+
+
+
+
+ {Array.from({ length: 10 }).map((v, k) =>
+
+ )}
+
+
+
+
+ const dataArray = Array.isArray(allList.findById.data)
+ ? allList.findById.data
+ : [allList.findById.data];
+
return (
@@ -14,101 +42,78 @@ function Page() {
Profil Singkat PPID Desa Darmasaba
-
-
-
-
-
- PROFIL PIMPINAN BADAN PUBLIK DESA DARMASABA
-
-
-
- {/* biodata perbekel */}
-
-
-
-
-
-
-
-
- (
+
+
+
+
+
+ PROFIL PIMPINAN BADAN PUBLIK DESA DARMASABA
+
+
+
+ {/* biodata perbekel */}
+
+
+
+
+
+
+
+
+
-
- I.B. Surya Prabhawa Manuaba,
-
-
- S.H.,M.H.,NL.P.
-
-
-
-
-
-
-
- Biodata
- I.B Surya Prabhawa Manuaba, S.H., M.H., adalah Perbekel Darmasaba periode 2021-2027, seorang advokat, pendiri Mantra Legal Consultants & Advocates, serta aktif di bidang musik dan akademis.
- Dia menempuh pendidikan hukum di Universitas Udayana dan Universitas Mahasaraswati Denpasar, serta memiliki pengalaman luas di berbagai organisasi dan kepemimpinan.
+ >
+
+ {item.name}
+
+
+
+
- Riwayat Karir
- 2021 - 2027: Perbekel Desa Darmasaba
- 2015 - Sekarang: Founder & Managing Director Mantra Legal Consultants & Advocates
- 2020 - Sekarang: Founder Ugawa Record Music Studio
- 2010 - 2016: Dosen Fakultas Hukum Universitas Mahasaraswati Denpasar
+
+ Biodata
+
+
+
+ Riwayat Karir
+
+
-
-
-
-
- Pengalaman Organisasi
-
-
- 1996 - 1997: Ketua OSIS SMP Negeri 1 Abiansemal
- 1999 - 2000: Ketua OSIS SMA Negeri 1 Mengwi
- 2008 - 2009: Ketua BEM Universitas Mahasaraswati Denpasar
- 2008 - 2010: Ketua Sekaa Taruna Sila Dharma, Banjar Tengah, Desa Adat Tegal, Darmasaba
- 2020 - Sekarang: Pengurus Young Lawyer Committee Peradi Denpasar
- 2021 - Sekarang: Dewan Kehormatan Himpunan Pengusaha Muda Indonesia (HIPMI) Badung
- 2023 - 2028: Komite Tetap Advokasi - Bidang Hukum dan Regulasi Kamar Dagang dan Industri Badung
-
-
-
-
- Program Kerja Unggulan
- Pemberdayaan Ekonomi dan UMKM
-
-
- Pelatihan dan pendampingan UMKM lokal
- Program bantuan modal usaha bagi pelaku usaha kecil
- Digitalisasi UMKM untuk meningkatkan pemasaran produk lokal
-
-
-
-
- Peningkatan Infrastruktur Desa
-
-
- Pembangunan dan perbaikan jalan desa
- Penyediaan fasilitas umum dan ruang terbuka hijau
- Optimalisasi layanan publik berbasis digital
-
-
-
-
-
+
+
+
+ Pengalaman Organisasi
+
+
+
+
+
+
+
+ Program Kerja Unggulan
+
+
+
+
+
+
+
+
+
+ ))}
);
}
diff --git a/src/app/darmasaba/(pages)/ppid/visi-misi-ppid/page.tsx b/src/app/darmasaba/(pages)/ppid/visi-misi-ppid/page.tsx
index 1030b15a..31b90a81 100644
--- a/src/app/darmasaba/(pages)/ppid/visi-misi-ppid/page.tsx
+++ b/src/app/darmasaba/(pages)/ppid/visi-misi-ppid/page.tsx
@@ -1,54 +1,60 @@
+'use client'
+import stateVisiMisiPPID from '@/app/admin/(dashboard)/_state/ppid/visi_misi_ppid/visimisiPPID';
import colors from '@/con/colors';
-import { Stack, Box, Paper, Text, Image, Center, ListItem, List } from '@mantine/core';
-import React from 'react';
+import { Box, Center, Image, Paper, Skeleton, Stack, Text } from '@mantine/core';
+import { useShallowEffect } from '@mantine/hooks';
+import { useProxy } from 'valtio/utils';
import BackButton from '../../desa/layanan/_com/BackButto';
function Page() {
+ const allList = useProxy(stateVisiMisiPPID)
+ useShallowEffect(() => {
+ allList.findById.load("1") // Assuming "1" is your default ID, adjust as needed
+ }, [])
+
+ if (!allList.findById.data) return
+ {Array.from({ length: 10 }).map((v, k) => )}
+
+
+ const dataArray = Array.isArray(allList.findById.data)
+ ? allList.findById.data
+ : [allList.findById.data];
return (
-
-
-
-
-
-
-
-
- MOTO PPID DESA DARMASABA
-
-
- MEMBERIKAN INFORMASI YANG CEPAT, MUDAH, TEPAT DAN TRANSPARAN
-
-
-
-
- VISI PPID
-
-
- Memberikan pelayanan informasi yanng transparan dan akuntabel untuk memenuhi hak pemohon informasi
- sesuai dengan ketentuan peraturan perundang-undangan yang berlaku.
-
-
-
-
- MISI PPID
-
-
-
- Meningkatkan pengelolaan dan pelayanan informasi yang berkualitas, benar dan bertanggung jawab
- Membangun dan mengembangkan sistem penyediaan dan layanan informasi.
- Meningkatkan dan mengembangkan kompetensi dan kualitas SDM dalam bidang pelayanan informasi.
- Mewujudkan keterbukaan informasi Pemerintah Desa Punggul dengan proses yang cepat, tepat, mudah
- dan sederhana.
-
+ {dataArray.map((item) => (
+
+
+
+
+
+
+
+
+ MOTO PPID DESA DARMASABA
+
+
+ MEMBERIKAN INFORMASI YANG CEPAT, MUDAH, TEPAT DAN TRANSPARAN
+
-
-
-
-
+
+
+ VISI PPID
+
+
+
+
+
+ MISI PPID
+
+
+
+
+
+
+ ))}
);
}
diff --git a/src/app/darmasaba/_com/main-page/prestasi/index.tsx b/src/app/darmasaba/_com/main-page/prestasi/index.tsx
index 4d2c6518..8ac7b9ef 100644
--- a/src/app/darmasaba/_com/main-page/prestasi/index.tsx
+++ b/src/app/darmasaba/_com/main-page/prestasi/index.tsx
@@ -8,7 +8,7 @@ const data = [
title: "Olahraga dan Kepemudaan",
deskripsi: "Tim Bola Voli Putri Dharma Temaja meraih juara 3 dalam Turnamen Bola Voli Mangupura Cup 2024 kategori Putri Se-Bali ",
image: "/api/img/prestasi-voli.jpeg",
- link: "/darmasaba/prestasi/tim-bola-voli-putri-dharma-temaja-meraih-juara-3-dalam-turnamen-bola-voli-mangupura-cup-2024-kategori-putri-se-bali"
+ link: "/darmasaba/prestasi-desa/tim-bola-voli-putri-dharma-temaja-meraih-juara-3-dalam-turnamen-bola-voli-mangupura-cup-2024-kategori-putri-se-bali"
},
{
id: 2,
diff --git a/src/app/percobaan/page.tsx b/src/app/percobaan/page.tsx
new file mode 100644
index 00000000..f482f320
--- /dev/null
+++ b/src/app/percobaan/page.tsx
@@ -0,0 +1,67 @@
+'use client'
+import ApiFetch from '@/lib/api-fetch';
+import { Button, Card, Container, FileInput, Flex, Image, SimpleGrid, Stack, Text } from '@mantine/core';
+import { useShallowEffect } from '@mantine/hooks';
+import { useState } from 'react';
+import { toast } from 'react-toastify';
+
+function Page() {
+
+ const [gambar, setGambar] = useState(null);
+ const [listFile, setListFile] = useState([])
+ const [fileNya, setFileNya] = useState(null)
+
+
+ const loadListFile = async () => {
+ const { data } = await ApiFetch.api.fileStorage.findMany.get()
+ setListFile(data?.map((item) => item.link) || [])
+ }
+ useShallowEffect(() => {
+ loadListFile()
+ }, [])
+
+ const submit = async () => {
+ console.log("kirim gamabar")
+ const file = fileNya
+ if (!file) return toast.warn("file dibutuhkan");
+
+ const { data } = await ApiFetch.api.fileStorage.create.post({
+ file: file,
+ name: file.name
+ })
+
+ console.log(data?.data)
+ setGambar(data?.data?.link || null)
+ toast.success("berhasil upload")
+ loadListFile()
+ setGambar(null)
+
+ }
+ return (
+
+
+ Uoload gambar
+
+
+ {
+ console.log(e?.name)
+ setGambar(e ? "data:image/png;base64," + Buffer.from(await e.arrayBuffer()).toString("base64") : null)
+ setFileNya(e)
+ }} />
+ submit
+
+ {gambar && }
+
+
+
+
+ {listFile.map((v) => (
+
+ ))}
+
+
+
+ );
+}
+
+export default Page;
\ No newline at end of file
diff --git a/src/lib/api-fetch.ts b/src/lib/api-fetch.ts
index 5183771c..efae7f30 100644
--- a/src/lib/api-fetch.ts
+++ b/src/lib/api-fetch.ts
@@ -1,5 +1,7 @@
import { AppServer } from '@/app/api/[[...slugs]]/route'
import { treaty } from '@elysiajs/eden'
-const ApiFetch = treaty(process.env.NEXT_PUBLIC_WIBU_URL || 'localhost:3000')
+
+const BASE_URL = process.env.NEXT_PUBLIC_BASE_URL || 'localhost:3000'
+const ApiFetch = treaty(BASE_URL)
export default ApiFetch
\ No newline at end of file
diff --git a/test.txt b/test.txt
new file mode 100644
index 00000000..e69de29b
diff --git a/types/env.d.ts b/types/env.d.ts
new file mode 100644
index 00000000..d4dbd193
--- /dev/null
+++ b/types/env.d.ts
@@ -0,0 +1,8 @@
+declare namespace NodeJS {
+ interface ProcessEnv {
+ DATABASE_URL?: string;
+ WIBU_UPLOAD_DIR?: string;
+ NEXT_PUBLIC_BASE_URL?: string;
+ }
+}
+