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 2b973f6e..c9a52ec1 100644
--- a/package.json
+++ b/package.json
@@ -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/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
index 04d71d97..3727382c 100644
--- a/prisma/data/ppid/profile-ppid/profilePPid.json
+++ b/prisma/data/ppid/profile-ppid/profilePPid.json
@@ -1,7 +1,11 @@
[
- {"name": "I.B Surya Prabhawa Manuaba, S.H., M.H.
"},
- {"biodata" : "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" : "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 "},
- {"pengalaman" : "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 "},
- {"unggulan" : "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 "}
-]
\ No newline at end of file
+ {
+ "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 34be5b4e..31430ab9 100644
--- a/prisma/schema.prisma
+++ b/prisma/schema.prisma
@@ -47,20 +47,40 @@ model AppMenuChild {
appMenuId String?
}
+// ========================================= FILE STORAGE ========================================= //
+
+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[]
+ PotensiDesa PotensiDesa[]
+}
+
//========================================= MENU PPID ========================================= //
// ========================================= VISI MISI PPID ========================================= //
-model VisiPPID {
+model VisiMisiPPID {
id String @id @default(cuid())
- content String
+ visi String @db.Text
+ misi String @db.Text
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
deletedAt DateTime @default(now())
isActive Boolean @default(true)
}
-model MisiPPID {
+// ========================================= DASAR HUKUM PPID ========================================= //
+model DasarHukumPPID {
id String @id @default(cuid())
- content String
+ judul String @db.Text
+ content String @db.Text
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
deletedAt DateTime @default(now())
@@ -70,11 +90,12 @@ model MisiPPID {
// ========================================= PROFILE PPID ========================================= //
model ProfilePPID {
id String @id @default(cuid())
- name String @unique
- biodata String
- riwayat String
- pengalaman String
- unggulan String
+ 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())
@@ -204,22 +225,52 @@ model GrafikBerdasarkanUmur {
}
// ========================================= 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[]
@@ -229,6 +280,21 @@ model KatagoryBerita {
isActive Boolean @default(true)
}
+// ========================================= POTENSI DESA ========================================= //
+model PotensiDesa {
+ id String @id @default(cuid())
+ name String
+ deskripsi String
+ kategori 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)
+}
+
// ========================================= PENGUMUMAN ========================================= //
model Pengumuman {
id String @id @default(cuid())
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 b334bc9e..6cd35bf2 100644
--- a/prisma/seed.ts
+++ b/prisma/seed.ts
@@ -1,133 +1,277 @@
-import prisma from '@/lib/prisma'
-import categoryPengumuman from './data/category-pengumuman.json'
-import katagoryBerita from './data/katagory-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 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 ...")
-
- 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 ...")
-
-
-
-})().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/perbekel.png b/public/perbekel.png
new file mode 100644
index 00000000..ed1cbd10
Binary files /dev/null and b/public/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/66f8e9e5-838e-4aaf-bbf2-9a31a6fc060e_perbekel.png b/public/uploads/seeded-images/profile-ppid/66f8e9e5-838e-4aaf-bbf2-9a31a6fc060e_perbekel.png
new file mode 100644
index 00000000..ed1cbd10
Binary files /dev/null and b/public/uploads/seeded-images/profile-ppid/66f8e9e5-838e-4aaf-bbf2-9a31a6fc060e_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/src/app/admin/(dashboard)/_com/createEditor.tsx b/src/app/admin/(dashboard)/_com/createEditor.tsx
new file mode 100644
index 00000000..7878e59a
--- /dev/null
+++ b/src/app/admin/(dashboard)/_com/createEditor.tsx
@@ -0,0 +1,85 @@
+// TestEditor.tsx
+import { RichTextEditor, Link } from '@mantine/tiptap';
+import { useEditor } from '@tiptap/react';
+import Highlight from '@tiptap/extension-highlight';
+import StarterKit from '@tiptap/starter-kit';
+import Underline from '@tiptap/extension-underline';
+import TextAlign from '@tiptap/extension-text-align';
+import Superscript from '@tiptap/extension-superscript';
+import SubScript from '@tiptap/extension-subscript';
+
+type CreateEditorProps = {
+ value: string;
+ onChange: (content: string) => void;
+};
+
+export default function CreateEditor({ value, onChange }: CreateEditorProps) {
+ const editor = useEditor({
+ extensions: [
+ StarterKit,
+ Underline,
+ Link,
+ Superscript,
+ SubScript,
+ Highlight,
+ TextAlign.configure({ types: ['heading', 'paragraph'] }),
+ ],
+ content: value,
+ onUpdate: () => {
+ if (editor) {
+ onChange(editor.getHTML());
+ }
+ },
+ });
+
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
\ No newline at end of file
diff --git a/src/app/admin/(dashboard)/_com/editEditor.tsx b/src/app/admin/(dashboard)/_com/editEditor.tsx
new file mode 100644
index 00000000..66317cc2
--- /dev/null
+++ b/src/app/admin/(dashboard)/_com/editEditor.tsx
@@ -0,0 +1,102 @@
+'use client'
+import { RichTextEditor, Link } from '@mantine/tiptap';
+import { useEditor } from '@tiptap/react';
+import Highlight from '@tiptap/extension-highlight';
+import StarterKit from '@tiptap/starter-kit';
+import Underline from '@tiptap/extension-underline';
+import TextAlign from '@tiptap/extension-text-align';
+import Superscript from '@tiptap/extension-superscript';
+import SubScript from '@tiptap/extension-subscript';
+import { useEffect } from 'react';
+
+type EditEditorProps = {
+ value: string;
+ onChange: (content: string) => void;
+};
+
+export default function EditEditor({ value, onChange }: EditEditorProps) {
+ const editor = useEditor({
+ extensions: [
+ StarterKit,
+ Underline,
+ Link,
+ Superscript,
+ SubScript,
+ Highlight,
+ TextAlign.configure({ types: ['heading', 'paragraph'] }),
+ ],
+ content: value,
+ // Hapus `immediatelyRender` dan `onMount`
+ });
+
+ // Sinkronisasi konten saat `value` berubah
+ useEffect(() => {
+ if (editor && value !== editor.getHTML()) {
+ editor.commands.setContent(value);
+ }
+ }, [value, editor]);
+
+ // Sinkronisasi konten ke parent saat diubah
+ useEffect(() => {
+ if (!editor) return;
+
+ const updateHandler = () => onChange(editor.getHTML());
+ editor.on('update', updateHandler);
+
+ return () => {
+ editor.off('update', updateHandler);
+ };
+ }, [editor, onChange]);
+
+ return (
+
+
+ {/* Toolbar seperti sebelumnya */}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
\ No newline at end of file
diff --git a/src/app/admin/(dashboard)/_com/header.tsx b/src/app/admin/(dashboard)/_com/header.tsx
new file mode 100644
index 00000000..1a867c81
--- /dev/null
+++ b/src/app/admin/(dashboard)/_com/header.tsx
@@ -0,0 +1,27 @@
+import React from 'react';
+import { Grid, GridCol, Paper, TextInput, Title } from '@mantine/core';
+import { IconSearch } from '@tabler/icons-react'; // Sesuaikan jika kamu pakai icon lain
+import colors from '@/con/colors';
+
+
+const HeaderSearch = ({ title = "", placeholder = "pencarian", searchIcon = }: { title: string, placeholder?: string, searchIcon?: React.ReactNode }) => {
+ return (
+
+
+ {title}
+
+
+
+
+
+
+
+ );
+};
+
+export default HeaderSearch;
\ No newline at end of file
diff --git a/src/app/admin/(dashboard)/_com/judulList.tsx b/src/app/admin/(dashboard)/_com/judulList.tsx
new file mode 100644
index 00000000..4eaa5731
--- /dev/null
+++ b/src/app/admin/(dashboard)/_com/judulList.tsx
@@ -0,0 +1,30 @@
+
+'use client'
+import colors from '@/con/colors';
+import { Grid, GridCol, Button, Text } from '@mantine/core';
+import { IconCircleDashedPlus } from '@tabler/icons-react';
+import { useRouter } from 'next/navigation';
+import React from 'react';
+
+const JudulList = ({ title = "", href = "#" }) => {
+ const router = useRouter();
+
+ const handleNavigate = () => {
+ router.push(href);
+ };
+
+ return (
+
+
+ {title}
+
+
+
+
+
+
+
+ );
+};
+
+export default JudulList;
diff --git a/src/app/admin/(dashboard)/_com/modalKonfirmasiHapus.tsx b/src/app/admin/(dashboard)/_com/modalKonfirmasiHapus.tsx
new file mode 100644
index 00000000..ccedf0f0
--- /dev/null
+++ b/src/app/admin/(dashboard)/_com/modalKonfirmasiHapus.tsx
@@ -0,0 +1,36 @@
+// components/modal/ModalKonfirmasiHapus.tsx
+import colors from "@/con/colors"
+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 ea5bdfbf..56b4fb01 100644
--- a/src/app/admin/(dashboard)/_state/desa/berita.ts
+++ b/src/app/admin/(dashboard)/_state/desa/berita.ts
@@ -1,23 +1,31 @@
-/* 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 } }>[],
+ data: [] as Prisma.KategoriBeritaGetPayload<{ omit: { isActive: true } }>[],
async load() {
const res = await ApiFetch.api.desa.berita.category["find-many"].get();
if (res.status === 200) {
@@ -27,23 +35,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 +48,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,33 +56,200 @@ const berita = proxy({
);
if (res.status === 200) {
berita.findMany.load();
- return toast.success("succes create");
+ return toast.success("Berita berhasil disimpan!");
}
- return toast.error("failed create");
+ return toast.error("Gagal menyimpan berita");
} catch (error) {
console.log((error as Error).message);
} finally {
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 ) ?? [];
}
},
},
+ findUnique: {
+ data: null as
+ | Prisma.BeritaGetPayload<{
+ include: {
+ image: true;
+ kategoriBerita: true;
+ };
+ }> | null,
+ async load(id: string) {
+ try {
+ const res = await fetch(`/api/desa/berita/${id}`);
+ if (res.ok) {
+ const data = await res.json();
+ berita.findUnique.data = data.data ?? null;
+ } else {
+ console.error('Failed to fetch berita:', res.statusText);
+ berita.findUnique.data = null;
+ }
+ } catch (error) {
+ console.error('Error fetching berita:', error);
+ berita.findUnique.data = null;
+ }
+ },
+ },
+ 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;
+ }
+ },
+ },
+ edit: {
+ id: "",
+ form: { ...defaultForm },
+ loading: false,
+
+ async load(id: string) {
+ if (!id) {
+ toast.warn("ID tidak valid");
+ return null;
+ }
+
+ try {
+ const response = await fetch(`/api/desa/berita/${id}`, {
+ method: 'GET',
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ });
+
+ if (!response.ok) {
+ throw new Error(`HTTP error! status: ${response.status}`);
+ }
+
+ const result = await response.json();
+
+ if (result?.success) {
+ const data = result.data;
+ this.id = data.id;
+ this.form = {
+ judul: data.judul,
+ deskripsi: data.deskripsi,
+ content: data.content,
+ kategoriBeritaId: data.kategoriBeritaId || "",
+ imageId: data.imageId || "",
+ };
+ return data; // Return the loaded data
+ } else {
+ throw new Error(result?.message || "Gagal memuat data");
+ }
+ } catch (error) {
+ console.error("Error loading berita:", error);
+ toast.error(error instanceof Error ? error.message : "Gagal memuat data");
+ return null;
+ }
+ },
+
+ async update() {
+ const cek = templateForm.safeParse(berita.edit.form);
+ if (!cek.success) {
+ const err = `[${cek.error.issues
+ .map((v) => `${v.path.join(".")}`)
+ .join("\n")}] required`;
+ toast.error(err);
+ return false;
+ }
+
+ try {
+ berita.edit.loading = true;
+
+ const response = await fetch(`/api/desa/berita/${this.id}`, {
+ method: 'PUT',
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ body: JSON.stringify({
+ judul: this.form.judul,
+ deskripsi: this.form.deskripsi,
+ content: this.form.content,
+ kategoriBeritaId: this.form.kategoriBeritaId || null,
+ imageId: this.form.imageId,
+ }),
+ });
+
+ if (!response.ok) {
+ const errorData = await response.json().catch(() => ({}));
+ throw new Error(errorData.message || `HTTP error! status: ${response.status}`);
+ }
+
+ const result = await response.json();
+
+ if (result.success) {
+ toast.success("Berhasil update berita");
+ await berita.findMany.load(); // refresh list
+ return true;
+ } else {
+ throw new Error(result.message || "Gagal update berita");
+ }
+ } catch (error) {
+ console.error("Error updating berita:", error);
+ toast.error(error instanceof Error ? error.message : "Terjadi kesalahan saat update berita");
+ return false;
+ } finally {
+ berita.edit.loading = false;
+ }
+ },
+
+ reset() {
+ berita.edit.id = "";
+ berita.edit.form = { ...defaultForm };
+ },
+ },
+
});
+// 5. State global
const stateDashboardBerita = proxy({
category,
berita,
});
-export default stateDashboardBerita;
\ No newline at end of file
+export default stateDashboardBerita;
diff --git a/src/app/admin/(dashboard)/_state/desa/potensi.ts b/src/app/admin/(dashboard)/_state/desa/potensi.ts
new file mode 100644
index 00000000..c61ec4f1
--- /dev/null
+++ b/src/app/admin/(dashboard)/_state/desa/potensi.ts
@@ -0,0 +1,223 @@
+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(1).max(50),
+ deskripsi: z.string().min(1).max(50),
+ kategori: z.string().min(1).max(50),
+ imageId: z.string().min(1).max(50),
+ content: z.string().min(1).max(5000),
+})
+
+const defaultForm = {
+ name: "",
+ deskripsi: "",
+ kategori: "",
+ imageId: "",
+ content: "",
+}
+
+const potensiDesaState = proxy({
+ create: {
+ form: { ...defaultForm },
+ loading: false,
+ async create() {
+ const cek = templateForm.safeParse(potensiDesaState.create.form);
+ if (!cek.success) {
+ const err = `[${cek.error.issues
+ .map((v) => `${v.path.join(".")}`)
+ .join("\n")}] required`;
+ return toast.error(err);
+ }
+ try {
+ potensiDesaState.create.loading = true;
+ const res = await ApiFetch.api.desa.potensi["create"].post(potensiDesaState.create.form);
+ if (res.status === 200) {
+ potensiDesaState.findMany.load();
+ return toast.success("Potensi berhasil disimpan!");
+ }
+ return toast.error("Gagal menyimpan potensi");
+ } catch (error) {
+ console.log((error as Error).message);
+ } finally {
+ potensiDesaState.create.loading = false;
+ }
+ }
+ },
+ findMany: {
+ data: null as
+ | Prisma.PotensiDesaGetPayload<{
+ include: {
+ image: true;
+ }
+ }>[]
+ | null,
+ async load() {
+ const res = await ApiFetch.api.desa.potensi["find-many"].get();
+ if (res.status === 200) {
+ potensiDesaState.findMany.data = res.data?.data ?? [];
+ }
+ }
+ },
+ findUnique: {
+ data: null as
+ | Prisma.PotensiDesaGetPayload<{
+ include: {
+ image: true;
+ }
+ }> | null,
+ async load(id: string) {
+ try {
+ const res = await fetch(`/api/desa/potensi/${id}`);
+ if (res.ok) {
+ const data = await res.json();
+ potensiDesaState.findUnique.data = data.data ?? null;
+ } else {
+ console.error('Failed to fetch potensi:', res.statusText);
+ potensiDesaState.findUnique.data = null;
+ }
+ } catch (error) {
+ console.error('Error fetching potensi:', error);
+ potensiDesaState.findUnique.data = null;
+ }
+ },
+ },
+ delete: {
+ loading: false,
+ async byId(id: string) {
+ if (!id) return toast.warn("ID tidak valid");
+
+ try {
+ potensiDesaState.delete.loading = true;
+
+ const response = await fetch(`/api/desa/potensi/del/${id}`, {
+ method: 'DELETE',
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ });
+
+ const result = await response.json();
+
+ if (response.ok && result?.success) {
+ toast.success(result.message || "Potensi berhasil dihapus");
+ await potensiDesaState.findMany.load(); // refresh list
+ } else {
+ toast.error(result?.message || "Gagal menghapus potensi");
+ }
+ } catch (error) {
+ console.error("Gagal delete:", error);
+ toast.error("Terjadi kesalahan saat menghapus potensi");
+ } finally {
+ potensiDesaState.delete.loading = false;
+ }
+ },
+ },
+ edit: {
+ id: "",
+ form: { ...defaultForm },
+ loading: false,
+
+ async load(id: string) {
+ if (!id) {
+ toast.warn("ID tidak valid");
+ return null;
+ }
+
+ try {
+ const response = await fetch(`/api/desa/potensi/${id}`, {
+ method: 'GET',
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ });
+
+ if (!response.ok) {
+ throw new Error(`HTTP error! status: ${response.status}`);
+ }
+
+ const result = await response.json();
+
+ if (result?.success) {
+ const data = result.data;
+ this.id = data.id;
+ this.form = {
+ name: data.name,
+ deskripsi: data.deskripsi,
+ kategori: data.kategori,
+ imageId: data.imageId || "",
+ content: data.content,
+ };
+ return data; // Return the loaded data
+ } else {
+ throw new Error(result?.message || "Gagal memuat data");
+ }
+ } catch (error) {
+ console.error("Error loading potensi:", error);
+ toast.error(error instanceof Error ? error.message : "Gagal memuat data");
+ return null;
+ }
+ },
+
+ async update() {
+ const cek = templateForm.safeParse(potensiDesaState.edit.form);
+ if (!cek.success) {
+ const err = `[${cek.error.issues
+ .map((v) => `${v.path.join(".")}`)
+ .join("\n")}] required`;
+ toast.error(err);
+ return false;
+ }
+
+ try {
+ potensiDesaState.edit.loading = true;
+
+ const response = await fetch(`/api/desa/potensi/${this.id}`, {
+ method: 'PUT',
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ body: JSON.stringify({
+ name: this.form.name,
+ deskripsi: this.form.deskripsi,
+ kategori: this.form.kategori,
+ imageId: this.form.imageId,
+ content: this.form.content,
+ }),
+ });
+
+ if (!response.ok) {
+ const errorData = await response.json().catch(() => ({}));
+ throw new Error(errorData.message || `HTTP error! status: ${response.status}`);
+ }
+
+ const result = await response.json();
+
+ if (result.success) {
+ toast.success("Berhasil update potensi");
+ await potensiDesaState.findMany.load(); // refresh list
+ return true;
+ } else {
+ throw new Error(result.message || "Gagal update potensi");
+ }
+ } catch (error) {
+ console.error("Error updating potensi:", error);
+ toast.error(error instanceof Error ? error.message : "Terjadi kesalahan saat update potensi");
+ return false;
+ } finally {
+ potensiDesaState.edit.loading = false;
+ }
+ },
+ reset() {
+ potensiDesaState.edit.id = "";
+ potensiDesaState.edit.form = { ...defaultForm };
+ }
+ }
+})
+
+export default potensiDesaState
+
+
\ No newline at end of file
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/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/permohonan_informasi_publik/permohonanInformasiPublik.ts b/src/app/admin/(dashboard)/_state/ppid/permohonan_informasi_publik/permohonanInformasiPublik.ts
index 4487056f..363998cf 100644
--- a/src/app/admin/(dashboard)/_state/ppid/permohonan_informasi_publik/permohonanInformasiPublik.ts
+++ b/src/app/admin/(dashboard)/_state/ppid/permohonan_informasi_publik/permohonanInformasiPublik.ts
@@ -56,6 +56,7 @@ const caraMemperolehSalinanInformasi = proxy({
}
}
})
+console.log(caraMemperolehSalinanInformasi)
type PermohonanInformasiPublikForm = Prisma.PermohonanInformasiPublikGetPayload<{
select: {
@@ -70,12 +71,12 @@ type PermohonanInformasiPublikForm = Prisma.PermohonanInformasiPublikGetPayload<
};
}>;
-const permohonanInformasiPublikForm = proxy({
+const statepermohonanInformasiPublik = proxy({
create: {
form: {} as PermohonanInformasiPublikForm,
loading: false,
async create(){
- const cek = templateForm.safeParse(permohonanInformasiPublikForm.create.form);
+ const cek = templateForm.safeParse(statepermohonanInformasiPublik.create.form);
if(!cek.success) {
const err = `[${cek.error.issues
.map((v) => `${v.path.join(".")}`)
@@ -83,38 +84,42 @@ const permohonanInformasiPublikForm = proxy({
return toast.error(err);
}
try {
- permohonanInformasiPublikForm.create.loading = true;
- const res = await ApiFetch.api.ppid.permohonaninformasipublik["create"].post(permohonanInformasiPublikForm.create.form);
+ statepermohonanInformasiPublik.create.loading = true;
+ const res = await ApiFetch.api.ppid.permohonaninformasipublik["create"].post(statepermohonanInformasiPublik.create.form);
if (res.status === 200) {
- permohonanInformasiPublikForm.findMany.load();
+ statepermohonanInformasiPublik.findMany.load();
return toast.success("success create");
}
return toast.error("failed create");
} catch (error) {
console.log((error as Error).message);
} finally {
- permohonanInformasiPublikForm.create.loading = false;
+ statepermohonanInformasiPublik.create.loading = false;
}
}
},
findMany: {
data: null as
- | Prisma.PermohonanInformasiPublikGetPayload<{ omit: { isActive: true } }>[]
+ | 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) {
- permohonanInformasiPublikForm.findMany.data = res.data?.data ?? [];
+ statepermohonanInformasiPublik.findMany.data = res.data?.data ?? [];
}
}
}
})
-const statePermohonanInformasi = proxy({
- permohonanInformasiPublikForm,
+const statepermohonanInformasiPublikForm = proxy({
+ statepermohonanInformasiPublik,
jenisInformasiDiminta,
caraMemperolehInformasi,
- caraMemperolehSalinanInformasi
+ caraMemperolehSalinanInformasi,
})
-export default statePermohonanInformasi;
+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
index 3e8f4f41..0decf48a 100644
--- 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
@@ -20,12 +20,12 @@ type PermohonanKeberatanInformasiForm = Prisma.FormulirPermohonanKeberatanGetPay
};
}>;
-const permohonanKeberatanInformasiForm = proxy({
+const permohonanKeberatanInformasi = proxy({
create: {
form: {} as PermohonanKeberatanInformasiForm,
loading: false,
async create(){
- const cek = templateForm.safeParse(permohonanKeberatanInformasiForm.create.form);
+ const cek = templateForm.safeParse(permohonanKeberatanInformasi.create.form);
if(!cek.success) {
const err = `[${cek.error.issues
.map((v) => `${v.path.join(".")}`)
@@ -33,17 +33,17 @@ const permohonanKeberatanInformasiForm = proxy({
return toast.error(err);
}
try {
- permohonanKeberatanInformasiForm.create.loading = true;
- const res = await ApiFetch.api.ppid.permohonankeberataninformasipublik["create"].post(permohonanKeberatanInformasiForm.create.form);
+ permohonanKeberatanInformasi.create.loading = true;
+ const res = await ApiFetch.api.ppid.permohonankeberataninformasipublik["create"].post(permohonanKeberatanInformasi.create.form);
if (res.status === 200) {
- permohonanKeberatanInformasiForm.findMany.load();
+ permohonanKeberatanInformasi.findMany.load();
return toast.success("success create");
}
return toast.error("failed create");
} catch (error) {
console.log((error as Error).message);
} finally {
- permohonanKeberatanInformasiForm.create.loading = false;
+ permohonanKeberatanInformasi.create.loading = false;
}
},
},
@@ -54,15 +54,11 @@ const permohonanKeberatanInformasiForm = proxy({
async load() {
const res = await ApiFetch.api.ppid.permohonankeberataninformasipublik["find-many"].get();
if (res.status === 200) {
- permohonanKeberatanInformasiForm.findMany.data = res.data?.data ?? [];
+ permohonanKeberatanInformasi.findMany.data = res.data?.data ?? [];
}
}
}
});
-const statePermohonanKeberatan = proxy({
- permohonanKeberatanInformasiForm,
-})
-
-export default statePermohonanKeberatan;
+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
index e35f6062..167d8edd 100644
--- a/src/app/admin/(dashboard)/_state/ppid/profile_ppid/profile_PPID.ts
+++ b/src/app/admin/(dashboard)/_state/ppid/profile_ppid/profile_PPID.ts
@@ -4,66 +4,169 @@ 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"),
-})
+ 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: {
- name: true;
- biodata: true;
- riwayat: true;
- pengalaman: true;
- unggulan: true;
- }
-}>
-
-const profilePPID = proxy({
- create: {
- form: {} as ProfilePPIDForm,
- loading: false,
- async create() {
- const cek = templateForm.safeParse(profilePPID.create.form);
- if (!cek.success) {
- const err = `[${cek.error.issues
- .map((v) => `${v.path.join(".")}`)
- .join("\n")}] required`;
- return toast.error(err);
- }
- try {
- profilePPID.create.loading = true;
- const res = await ApiFetch.api.ppid.profileppid["create"].post(profilePPID.create.form);
- if (res.status === 200) {
- profilePPID.findMany.load();
- return toast.success("success create");
- }
- return toast.error("failed create");
- } catch (error) {
- console.log((error as Error).message);
- } finally {
- profilePPID.create.loading = false;
- }
- }
- },
- findMany: {
- data: null as
- | Prisma.ProfilePPIDGetPayload<{omit: {isActive: true}}>[]
- | null,
- async load() {
- const res = await ApiFetch.api.ppid.profileppid["find-many"].get();
- if (res.status === 200) {
- profilePPID.findMany.data = res.data?.data ?? [];
- }
- }
- }
-})
+ 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({
- profilePPID
-})
+ /**
+ * Bagian untuk ambil data berdasarkan ID
+ */
+ findById: {
+ data: null as ProfilePPIDForm | null,
+ loading: false,
-export default stateProfilePPID;
\ No newline at end of file
+ /**
+ * 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/[id]/edit/page.tsx b/src/app/admin/(dashboard)/desa/berita/[id]/edit/page.tsx
new file mode 100644
index 00000000..a753aede
--- /dev/null
+++ b/src/app/admin/(dashboard)/desa/berita/[id]/edit/page.tsx
@@ -0,0 +1,241 @@
+"use client";
+
+import {
+ Box,
+ Button,
+ Center,
+ Image,
+ Paper,
+ Select,
+ Skeleton,
+ Stack,
+ Text,
+ TextInput,
+ Title,
+} from "@mantine/core";
+import { IconArrowBack, IconImageInPicture } from "@tabler/icons-react";
+import { useParams, useRouter } from "next/navigation";
+import { useEffect, useState } from "react";
+import { toast } from "react-toastify";
+import { useProxy } from "valtio/utils";
+
+
+import EditEditor from "@/app/admin/(dashboard)/_com/editEditor";
+import colors from "@/con/colors";
+import ApiFetch from "@/lib/api-fetch";
+import { FileInput } from "@mantine/core";
+import { useShallowEffect } from "@mantine/hooks";
+import { Prisma } from "@prisma/client";
+import stateDashboardBerita from "../../../../_state/desa/berita";
+
+function EditBerita() {
+ const beritaState = useProxy(stateDashboardBerita);
+ const router = useRouter();
+ const params = useParams();
+
+ const [previewImage, setPreviewImage] = useState(null);
+ const [file, setFile] = useState(null);
+ const [formData, setFormData] = useState({
+ judul: beritaState.berita.edit.form.judul || '',
+ deskripsi: beritaState.berita.edit.form.deskripsi || '',
+ kategoriBeritaId: beritaState.berita.edit.form.kategoriBeritaId || '',
+ content: beritaState.berita.edit.form.content || '',
+ imageId: beritaState.berita.edit.form.imageId || ''
+ });
+
+ // Load berita by id saat pertama kali
+ useEffect(() => {
+ const loadBerita = async () => {
+ const id = params?.id as string;
+ if (!id) return;
+
+ try {
+ const data = await stateDashboardBerita.berita.edit.load(id); // akses langsung, bukan dari proxy
+ if (data) {
+ setFormData({
+ judul: data.judul || '',
+ deskripsi: data.deskripsi || '',
+ kategoriBeritaId: data.kategoriBeritaId || '',
+ content: data.content || '',
+ imageId: data.imageId || '',
+ });
+
+ if (data?.image?.link) {
+ setPreviewImage(data.image.link);
+ }
+ }
+ } catch (error) {
+ console.error("Error loading berita:", error);
+ toast.error("Gagal memuat data berita");
+ }
+ };
+
+ loadBerita();
+ }, [params?.id]); // ✅ hapus beritaState dari dependency
+
+ const handleSubmit = async () => {
+
+ try {
+ // Update global state with form data
+ beritaState.berita.edit.form = {
+ ...beritaState.berita.edit.form,
+ judul: formData.judul,
+ deskripsi: formData.deskripsi,
+ content: formData.content,
+ kategoriBeritaId: formData.kategoriBeritaId || '',
+ imageId: formData.imageId // Keep existing imageId if not changed
+ };
+
+ // Jika ada file baru, upload
+ if (file) {
+ 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");
+ }
+
+ // Update imageId in global state
+ beritaState.berita.edit.form.imageId = uploaded.id;
+ }
+
+ await beritaState.berita.edit.update();
+ toast.success("Berita berhasil diperbarui!");
+ router.push("/admin/desa/berita");
+ } catch (error) {
+ console.error("Error updating berita:", error);
+ toast.error("Terjadi kesalahan saat memperbarui berita");
+ }
+ };
+
+ return (
+
+
+ router.back()}>
+
+
+
+
+
+ Edit Berita
+ setFormData({ ...formData, judul: e.target.value })}
+ label={Judul }
+ placeholder="masukkan judul"
+ />
+
+ {
+ setFormData({
+ ...formData,
+ kategoriBeritaId: val?.id || ''
+ });
+ }}
+ />
+
+ setFormData({ ...formData, deskripsi: e.target.value })}
+ label={Deskripsi }
+ placeholder="masukkan deskripsi"
+ />
+
+ Upload Gambar Baru (Opsional)}
+ 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
+ {
+ setFormData((prev) => ({ ...prev, content: htmlContent }));
+ beritaState.berita.edit.form.content = htmlContent;
+ }}
+ />
+
+
+ Edit Berita
+
+
+
+ );
+}
+
+interface SelectCategoryProps {
+ onChange: (value: Prisma.KategoriBeritaGetPayload<{
+ select: {
+ name: true;
+ id: true;
+ };
+ }> | null) => void;
+ value?: string | null;
+ defaultValue?: string | null;
+}
+
+function SelectCategory({
+ onChange,
+ value,
+ defaultValue,
+}: SelectCategoryProps) {
+ const categoryState = useProxy(stateDashboardBerita.category);
+
+ useShallowEffect(() => {
+ categoryState.findMany.load().then(() => {
+ console.log("Kategori berhasil dimuat:", categoryState.findMany.data);
+ });
+ }, []);
+
+ if (!categoryState.findMany.data) {
+ return ;
+ }
+
+
+ const selectedValue = value || defaultValue;
+
+ return (
+ Kategori}
+ placeholder="Pilih kategori"
+ data={categoryState.findMany.data.map((item) => ({
+ label: item.name,
+ value: item.id,
+ }))}
+ value={selectedValue || null}
+ onChange={(val: string | null) => {
+ if (val) {
+ const selected = categoryState.findMany.data?.find((item) => item.id === val);
+ if (selected) {
+ onChange(selected);
+ }
+ } else {
+ onChange(null);
+ }
+ }}
+ searchable
+ clearable
+ nothingFoundMessage="Tidak ditemukan"
+ />
+ );
+}
+
+export default EditBerita;
diff --git a/src/app/admin/(dashboard)/desa/berita/[id]/page.tsx b/src/app/admin/(dashboard)/desa/berita/[id]/page.tsx
new file mode 100644
index 00000000..a991e6ba
--- /dev/null
+++ b/src/app/admin/(dashboard)/desa/berita/[id]/page.tsx
@@ -0,0 +1,120 @@
+'use client'
+import { useProxy } from 'valtio/utils';
+
+import { Box, Button, Flex, Image, Paper, Skeleton, Stack, Text } from '@mantine/core';
+import { useShallowEffect } from '@mantine/hooks';
+import { IconArrowBack, IconEdit, IconX } from '@tabler/icons-react';
+import { useParams, useRouter } from 'next/navigation';
+import { useState } from 'react';
+
+import colors from '@/con/colors';
+import { ModalKonfirmasiHapus } from '../../../_com/modalKonfirmasiHapus';
+import stateDashboardBerita from '../../../_state/desa/berita';
+
+function DetailBerita() {
+ const beritaState = useProxy(stateDashboardBerita)
+ const [modalHapus, setModalHapus] = useState(false)
+ const [selectedId, setSelectedId] = useState(null)
+ const params = useParams()
+ const router = useRouter()
+
+ useShallowEffect(() => {
+ beritaState.berita.findUnique.load(params?.id as string)
+ }, [])
+
+
+ const handleHapus = () => {
+ if (selectedId) {
+ beritaState.berita.delete.byId(selectedId)
+ setModalHapus(false)
+ setSelectedId(null)
+ router.push("/admin/desa/berita")
+ }
+ }
+
+ if (!beritaState.berita.findUnique.data) {
+ return (
+
+ {Array.from({ length: 10 }).map((_, k) => (
+
+ ))}
+
+ )
+ }
+
+ return (
+
+
+ router.back()}>
+
+
+
+
+
+ Detail Berita
+ {beritaState.berita.findUnique.data ? (
+
+
+
+ Kategori
+ {beritaState.berita.findUnique.data?.kategoriBerita?.name}
+
+
+ Judul
+ {beritaState.berita.findUnique.data?.judul}
+
+
+ Deskripsi
+ {beritaState.berita.findUnique.data?.deskripsi}
+
+
+ Gambar
+
+
+
+ Konten
+
+
+
+ {
+ if (beritaState.berita.findUnique.data) {
+ setSelectedId(beritaState.berita.findUnique.data.id);
+ setModalHapus(true);
+ }
+ }}
+ disabled={beritaState.berita.delete.loading || !beritaState.berita.findUnique.data}
+ color={"red"}
+ >
+
+
+ {
+ if (beritaState.berita.findUnique.data) {
+ router.push(`/admin/desa/berita/${beritaState.berita.findUnique.data.id}/edit`);
+ }
+ }}
+ disabled={!beritaState.berita.findUnique.data}
+ color={"green"}
+ >
+
+
+
+
+
+ ) : null}
+
+
+
+ {/* Modal Konfirmasi Hapus */}
+ setModalHapus(false)}
+ onConfirm={handleHapus}
+ text='Apakah anda yakin ingin menghapus berita ini?'
+ />
+
+ );
+}
+
+export default DetailBerita;
\ No newline at end of file
diff --git a/src/app/admin/(dashboard)/desa/berita/_com/BeritaEditor.tsx b/src/app/admin/(dashboard)/desa/berita/_com/BeritaEditor.tsx
index 0cceafa4..3361c2bc 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,28 +9,77 @@ 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, useState } 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({ onSubmit }: { onSubmit: (val: string) => void }) {
- const editor = useEditor({
- extensions: [
- StarterKit,
- Underline,
- Link,
- Superscript,
- SubScript,
- Highlight,
- TextAlign.configure({ types: ['heading', 'paragraph'] }),
- ],
- content,
- immediatelyRender: false
- });
-
- if (!editor) {
- return null;
- }
+ export function BeritaEditor({
+ onEditorReady,
+ showSubmit = true,
+ onSubmit,
+ initialContent = '',
+ onUpdate,
+ }: {
+ onEditorReady?: (editor: any | null) => void;
+ onSubmit?: (val: string) => void;
+ showSubmit?: boolean;
+ initialContent?: string;
+ onUpdate?: (content: string) => void;
+ }) {
+ const [mounted, setMounted] = useState(false);
+ const [isReady, setIsReady] = useState(false);
+
+ const editor = useEditor({
+ extensions: [
+ StarterKit,
+ Underline,
+ Link,
+ Superscript,
+ SubScript,
+ Highlight,
+ TextAlign.configure({ types: ['heading', 'paragraph'] }),
+ ],
+ content: initialContent || '
',
+ onUpdate: ({ editor }) => {
+ if (onUpdate) {
+ onUpdate(editor.getHTML());
+ }
+ },
+ editorProps: {
+ attributes: {
+ class: 'prose max-w-none',
+ },
+ },
+ onSelectionUpdate: () => {
+ if (!isReady && editor) {
+ setIsReady(true);
+ onEditorReady?.(editor);
+ }
+ },
+ immediatelyRender: false
+ });
+
+ useEffect(() => {
+ if (editor) {
+ // Set initial content when component mounts
+ editor.commands.setContent(initialContent || '
');
+
+ // Mark as mounted and notify parent
+ if (!mounted) {
+ setMounted(true);
+ onEditorReady?.(editor);
+ }
+ }
+
+ return () => {
+ if (editor) {
+ editor.destroy();
+ }
+ };
+ }, [editor, initialContent, mounted, onEditorReady]);
+
+ if (!editor) return Loading editor...
;
return (
@@ -82,10 +132,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/create/page.tsx b/src/app/admin/(dashboard)/desa/berita/create/page.tsx
new file mode 100644
index 00000000..f27cc51f
--- /dev/null
+++ b/src/app/admin/(dashboard)/desa/berita/create/page.tsx
@@ -0,0 +1,168 @@
+'use client'
+import colors from '@/con/colors';
+import ApiFetch from '@/lib/api-fetch';
+import { Box, Button, Center, FileInput, Image, Paper, Select, Skeleton, Stack, Text, TextInput, Title } from '@mantine/core';
+import { useShallowEffect } from '@mantine/hooks';
+import { Prisma } from '@prisma/client';
+import { IconArrowBack, IconImageInPicture } from '@tabler/icons-react';
+import { useRouter } from 'next/navigation';
+import { useState } from 'react';
+import { toast } from 'react-toastify';
+import { useProxy } from 'valtio/utils';
+import CreateEditor from '../../../_com/createEditor';
+import stateDashboardBerita from '../../../_state/desa/berita';
+
+export default function CreateBerita() {
+ const beritaState = useProxy(stateDashboardBerita);
+ const [previewImage, setPreviewImage] = useState(null);
+ const [file, setFile] = useState(null);
+ const router = useRouter()
+
+ const resetForm = () => {
+ // Reset state di valtio
+ beritaState.berita.create.form = {
+ judul: "",
+ deskripsi: "",
+ kategoriBeritaId: "",
+ imageId: "",
+ content: "",
+ };
+
+ // Reset state lokal
+ setPreviewImage(null);
+ setFile(null);
+ };
+
+ const handleSubmit = async () => {
+ if (!file) {
+ return toast.warn("Pilih file gambar terlebih dahulu");
+ }
+
+ // 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();
+
+ // Reset form setelah submit
+ resetForm();
+ router.push("/admin/desa/berita")
+ };
+
+ return (
+
+
+ router.back()}>
+
+
+
+
+
+ Create Berita
+ {
+ 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
+ {
+ beritaState.berita.create.form.content = htmlContent;
+ }}
+ />
+
+ Simpan Berita
+
+
+
+ );
+
+ 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"
+ />
+ );
+ }
+}
diff --git a/src/app/admin/(dashboard)/desa/berita/page.tsx b/src/app/admin/(dashboard)/desa/berita/page.tsx
index fd79b4d3..01a96511 100644
--- a/src/app/admin/(dashboard)/desa/berita/page.tsx
+++ b/src/app/admin/(dashboard)/desa/berita/page.tsx
@@ -1,88 +1,189 @@
'use client'
-import { Center, Group, Select, SimpleGrid, Skeleton, Stack, Text, TextInput } from '@mantine/core';
+import colors from '@/con/colors';
+import { Box, Button, Grid, GridCol, Image, Paper, Skeleton, Stack, Table, TableTbody, TableTd, TableTh, TableThead, TableTr, Text, TextInput, Title } from '@mantine/core';
import { useShallowEffect } from '@mantine/hooks';
-import { Prisma } from '@prisma/client';
-import { IconImageInPicture } from '@tabler/icons-react';
+import { IconCircleDashedPlus, IconDeviceImacCog, IconSearch } from '@tabler/icons-react';
+import { useRouter } from 'next/navigation';
+import { useState } from 'react';
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 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 (
+
+
+
+ )
+ }
+
+ return (
+
+
+
+
+
+ List Berita
+
+
+ router.push("/admin/desa/berita/create")} bg={colors['blue-button']}>
+
+
+
+
+
+
+
+
+ Judul
+ Kategori
+ Image
+ Detail
+
+
+
+
+ {beritaState.berita.findMany.data?.map((item) => (
+
+
+
+ {item.judul}
+
+
+ {item.kategoriBerita?.name}
+
+
+
+
+ router.push(`/admin/desa/berita/${item.id}`)}>
+
+
+
+
+
+ ))}
+
+
+
+
+
+ {/* Modal Konfirmasi Hapus */}
+ setModalHapus(false)}
+ onConfirm={handleHapus}
+ text='Apakah anda yakin ingin menghapus berita ini?'
+ />
+
+ )
}
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/create/page.tsx b/src/app/admin/(dashboard)/desa/potensi/create/page.tsx
new file mode 100644
index 00000000..4dc249d4
--- /dev/null
+++ b/src/app/admin/(dashboard)/desa/potensi/create/page.tsx
@@ -0,0 +1,128 @@
+'use client';
+
+import colors from '@/con/colors';
+import ApiFetch from '@/lib/api-fetch';
+import { Box, Button, Center, FileInput, Image, Paper, Stack, Text, TextInput, Title } from '@mantine/core';
+import { IconArrowBack, IconImageInPicture } from '@tabler/icons-react';
+import { useState } from 'react';
+import { toast } from 'react-toastify';
+import { useProxy } from 'valtio/utils';
+import potensiDesaState from '../../../_state/desa/potensi';
+import { useRouter } from 'next/navigation';
+import CreateEditor from '../../../_com/createEditor';
+
+
+function CreatePotensi() {
+ const potensiState = useProxy(potensiDesaState);
+ const [previewImage, setPreviewImage] = useState(null);
+ const [file, setFile] = useState(null);
+ const router = useRouter();
+
+ const handleSubmit = async () => {
+ if (!file) return toast.warn('Pilih file gambar terlebih dahulu');
+
+ 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');
+ }
+
+ potensiState.create.form.imageId = uploaded.id;
+
+ await potensiState.create.create();
+
+ resetForm();
+ router.push('/admin/desa/potensi');
+ };
+
+ const resetForm = () => {
+ potensiState.create.form = {
+ name: '',
+ deskripsi: '',
+ kategori: '',
+ imageId: '',
+ content: '',
+ };
+
+ setPreviewImage(null);
+ setFile(null);
+ };
+
+ return (
+
+
+ router.back()}>
+
+
+
+
+
+
+ Create Potensi
+
+ (potensiState.create.form.name = val.target.value)}
+ label={Judul }
+ placeholder="masukkan judul"
+ />
+
+ (potensiState.create.form.deskripsi = val.target.value)}
+ label={Deskripsi }
+ placeholder="masukkan deskripsi"
+ />
+
+ (potensiState.create.form.kategori = val.target.value)}
+ label={Kategori }
+ placeholder="masukkan kategori"
+ />
+
+ 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
+ {
+ potensiState.create.form.content = htmlContent;
+ }}
+ />
+
+
+
+ Simpan Potensi
+
+
+
+
+ );
+}
+
+export default CreatePotensi;
diff --git a/src/app/admin/(dashboard)/desa/potensi/detail/[id]/page.tsx b/src/app/admin/(dashboard)/desa/potensi/detail/[id]/page.tsx
new file mode 100644
index 00000000..814a31d4
--- /dev/null
+++ b/src/app/admin/(dashboard)/desa/potensi/detail/[id]/page.tsx
@@ -0,0 +1,121 @@
+'use client'
+import colors from '@/con/colors';
+import { Box, Button, Flex, Image, Paper, Skeleton, Stack, Text } from '@mantine/core';
+import { IconArrowBack, IconEdit, IconX } from '@tabler/icons-react';
+import { useRouter } from 'next/navigation';
+import React from 'react';
+import { useProxy } from 'valtio/utils';
+import potensiDesaState from '../../../../_state/desa/potensi';
+import { useShallowEffect } from '@mantine/hooks';
+import { useParams } from 'next/navigation';
+import { useState } from 'react';
+import { ModalKonfirmasiHapus } from '@/app/admin/(dashboard)/_com/modalKonfirmasiHapus';
+
+export default function DetailPotensi() {
+ const router = useRouter()
+ const params = useParams()
+ const [modalHapus, setModalHapus] = useState(false)
+ const [selectedId, setSelectedId] = useState(null)
+ const potensiState = useProxy(potensiDesaState)
+
+ useShallowEffect(() => {
+ potensiState.findUnique.load(params?.id as string)
+ }, [])
+
+ const handleHapus = () => {
+ if (selectedId) {
+ potensiState.delete.byId(selectedId)
+ setModalHapus(false)
+ setSelectedId(null)
+ router.push("/admin/desa/potensi")
+ }
+ }
+
+ if (!potensiState.findUnique.data) {
+ return (
+
+ {Array.from({ length: 10 }).map((_, k) => (
+
+ ))}
+
+ )
+ }
+
+ return (
+
+
+ router.back()}>
+
+
+
+
+
+ Detail Potensi
+ {potensiState.findUnique.data ? (
+
+
+
+ Judul
+ {potensiState.findUnique.data.name}
+
+
+ Kategori
+ {potensiState.findUnique.data.kategori}
+
+
+ Deskripsi
+ {potensiState.findUnique.data.deskripsi}
+
+
+ Gambar
+
+
+
+ Konten
+
+
+
+
+ {
+ if (potensiState.findUnique.data) {
+ setSelectedId(potensiState.findUnique.data.id)
+ setModalHapus(true)
+ }
+ }}
+ disabled={potensiState.delete.loading || !potensiState.findUnique.data}
+ color="red"
+ >
+
+
+ {
+ if (potensiState.findUnique.data) {
+ router.push(`/admin/desa/potensi/edit/${potensiState.findUnique.data.id}`)
+ }
+ }}
+ disabled={!potensiState.findUnique.data}
+ color="green"
+ >
+
+
+
+
+
+
+ ) : null}
+
+
+
+ {/* Modal Hapus */}
+ setModalHapus(false)}
+ onConfirm={handleHapus}
+ text="Apakah anda yakin ingin menghapus potensi ini?"
+ />
+
+ );
+}
+
+
diff --git a/src/app/admin/(dashboard)/desa/potensi/edit/[id]/page.tsx b/src/app/admin/(dashboard)/desa/potensi/edit/[id]/page.tsx
new file mode 100644
index 00000000..4dff08b3
--- /dev/null
+++ b/src/app/admin/(dashboard)/desa/potensi/edit/[id]/page.tsx
@@ -0,0 +1,169 @@
+'use client'
+
+import EditEditor from "@/app/admin/(dashboard)/_com/editEditor";
+import potensiDesaState from "@/app/admin/(dashboard)/_state/desa/potensi";
+import colors from "@/con/colors";
+import ApiFetch from "@/lib/api-fetch";
+import { Box, Button, Paper, Stack, Title, TextInput, FileInput, Center, Text, Image } from "@mantine/core";
+import { IconArrowBack, IconImageInPicture } from "@tabler/icons-react";
+import { useParams } from "next/navigation";
+import { useRouter } from "next/navigation";
+import { useState, useEffect } from "react";
+import { toast } from "react-toastify";
+import { useProxy } from "valtio/utils";
+
+
+
+function EditPotensi() {
+ const potensiState = useProxy(potensiDesaState)
+ const router = useRouter()
+ const params = useParams()
+
+ const [previewImage, setPreviewImage] = useState(null);
+ const [file, setFile] = useState(null);
+ const [formData, setFormData] = useState({
+ name: '',
+ deskripsi: '',
+ kategori: '',
+ content: '',
+ imageId: ''
+ });
+
+ useEffect(() => {
+ const loadPotensi = async () => {
+ const id = params?.id as string;
+ if (!id) return;
+
+ try {
+ const data = await potensiDesaState.edit.load(id); // ambil data dari API
+ if (data) {
+ setFormData({
+ name: data.name || '',
+ deskripsi: data.deskripsi || '',
+ kategori: data.kategori || '',
+ content: data.content || '',
+ imageId: data.imageId || '',
+ });
+
+ if (data?.image?.link) {
+ setPreviewImage(data.image.link);
+ }
+ }
+ } catch (error) {
+ console.error("Error loading potensi:", error);
+ toast.error("Gagal memuat data potensi");
+ }
+ };
+
+ loadPotensi();
+ }, [params?.id]);
+
+ const handleSubmit = async () => {
+ try {
+ // Sinkronkan semua data dari formData ke state global
+ potensiState.edit.form = {
+ ...potensiState.edit.form,
+ name: formData.name,
+ deskripsi: formData.deskripsi,
+ kategori: formData.kategori,
+ content: formData.content,
+ };
+
+ if (file) {
+ 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");
+ }
+
+ potensiState.edit.form.imageId = uploaded.id;
+ }
+
+ await potensiState.edit.update();
+ toast.success("Potensi berhasil diperbarui!");
+ router.push("/admin/desa/potensi");
+ } catch (error) {
+ console.error("Error updating potensi:", error);
+ toast.error("Terjadi kesalahan saat memperbarui potensi");
+ }
+ };
+
+ return (
+
+
+ router.back()}>
+
+
+
+
+
+ Edit Potensi
+ {
+ const val = e.target.value;
+ setFormData((prev) => ({ ...prev, name: val }));
+ potensiState.edit.form.name = val;
+ }}
+ label={Judul }
+ placeholder="masukkan judul"
+ />
+ {
+ const val = e.target.value;
+ setFormData((prev) => ({ ...prev, deskripsi: val }));
+ potensiState.edit.form.deskripsi = val;
+ }}
+ label={Deskripsi }
+ placeholder="masukkan deskripsi"
+ />
+ {
+ const val = e.target.value;
+ setFormData((prev) => ({ ...prev, kategori: val }));
+ potensiState.edit.form.kategori = val;
+ }}
+ label={Kategori }
+ placeholder="masukkan kategori"
+ />
+
+ 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
+ {
+ setFormData((prev) => ({ ...prev, content: htmlContent }));
+ potensiState.edit.form.content = htmlContent;
+ }}
+ />
+
+ Edit Potensi
+
+
+
+ );
+}
+
+export default EditPotensi;
\ No newline at end of file
diff --git a/src/app/admin/(dashboard)/desa/potensi/page.tsx b/src/app/admin/(dashboard)/desa/potensi/page.tsx
index 8a2285b8..d9be0fac 100644
--- a/src/app/admin/(dashboard)/desa/potensi/page.tsx
+++ b/src/app/admin/(dashboard)/desa/potensi/page.tsx
@@ -1,11 +1,89 @@
-import React from 'react';
-function Page() {
+'use client'
+import colors from '@/con/colors';
+import { Box, Button, Image, Paper, Skeleton, Stack, Table, TableTbody, TableTd, TableTh, TableThead, TableTr, Text } from '@mantine/core';
+import { useShallowEffect } from '@mantine/hooks';
+import { IconDeviceImacCog, IconSearch } from '@tabler/icons-react';
+import { useRouter } from 'next/navigation';
+import { useProxy } from 'valtio/utils';
+import HeaderSearch from '../../_com/header';
+import JudulList from '../../_com/judulList';
+import potensiDesaState from '../../_state/desa/potensi';
+
+
+function Potensi() {
return (
-
- Potensi
-
+
+ }
+ />
+
+
);
}
-export default Page;
+function ListPotensi() {
+ const potensiState = useProxy(potensiDesaState)
+ useShallowEffect(() => {
+ potensiState.findMany.load()
+ }, [])
+
+ const router = useRouter()
+
+
+ if (!potensiState.findMany.data) {
+ return (
+
+
+
+ )
+ }
+
+ return (
+
+
+
+
+
+
+
+
+ Judul
+ Kategori
+ Image
+ Detail
+
+
+
+ {potensiState.findMany.data?.map((item) => (
+
+
+
+ {item.name}
+
+ {item.kategori}
+
+
+
+
+ router.push(`/admin/desa/potensi/detail/${item.id}`)}>
+
+
+
+
+ ))}
+
+
+
+
+
+
+ )
+}
+
+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/ajukan-ide-inovatif/page.tsx b/src/app/admin/(dashboard)/inovasi/ajukan-ide-inovatif/page.tsx
index 8a193283..6ff04673 100644
--- a/src/app/admin/(dashboard)/inovasi/ajukan-ide-inovatif/page.tsx
+++ b/src/app/admin/(dashboard)/inovasi/ajukan-ide-inovatif/page.tsx
@@ -1,10 +1,43 @@
+import colors from '@/con/colors';
+import { Box, Paper, Stack, Table, TableTbody, TableTd, TableTh, TableThead, TableTr, Title } from '@mantine/core';
import React from 'react';
function Page() {
return (
-
- ajukan-ide-inovatif
-
+
+
+
+ Ajukan Ide Inovatif
+
+
+
+
+ No
+ Nama
+ Alamat
+ Nama Ide Inovatif
+ Deskripsi
+ Masalah yang ingin diatasi
+ Benefit
+
+
+
+
+
+ 1
+ nama
+ alamat
+ ide inovatif
+ deskripsi
+ masalah
+ benefit
+
+
+
+
+
+
+
);
}
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)/inovasi/info-teknologi-tepat-guna/create/page.tsx b/src/app/admin/(dashboard)/inovasi/info-teknologi-tepat-guna/create/page.tsx
new file mode 100644
index 00000000..101f56e2
--- /dev/null
+++ b/src/app/admin/(dashboard)/inovasi/info-teknologi-tepat-guna/create/page.tsx
@@ -0,0 +1,35 @@
+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 CreateInfoTeknologiTepatGuna() {
+ return (
+
+
+
+
+ Create Info Teknologi Tepat Guna
+
+ Masukkan Image
+
+
+ Nama Info Teknologi Tepat Guna}
+ placeholder="Masukkan nama info teknologi tepat guna"
+ />
+ Deskripsi Info Teknologi Tepat Guna}
+ placeholder="Masukkan deskripsi info teknologi tepat guna"
+ />
+
+ Submit
+
+
+
+
+
+ );
+}
+
+export default CreateInfoTeknologiTepatGuna;
diff --git a/src/app/admin/(dashboard)/inovasi/info-teknologi-tepat-guna/listData/page.tsx b/src/app/admin/(dashboard)/inovasi/info-teknologi-tepat-guna/listData/page.tsx
new file mode 100644
index 00000000..45f080e9
--- /dev/null
+++ b/src/app/admin/(dashboard)/inovasi/info-teknologi-tepat-guna/listData/page.tsx
@@ -0,0 +1,31 @@
+import colors from '@/con/colors';
+import { Box, Paper, SimpleGrid, Stack, Title } from '@mantine/core';
+import React from 'react';
+
+function ListDataInfoTeknologiTepatGuna() {
+ return (
+
+
+
+ List Data Info Teknologi Tepat Guna
+
+
+ Data 1
+
+
+ Data 2
+
+
+ Data 3
+
+
+ Data 4
+
+
+
+
+
+ );
+}
+
+export default ListDataInfoTeknologiTepatGuna;
diff --git a/src/app/admin/(dashboard)/inovasi/info-teknologi-tepat-guna/page.tsx b/src/app/admin/(dashboard)/inovasi/info-teknologi-tepat-guna/page.tsx
index 26933cb1..68273de5 100644
--- a/src/app/admin/(dashboard)/inovasi/info-teknologi-tepat-guna/page.tsx
+++ b/src/app/admin/(dashboard)/inovasi/info-teknologi-tepat-guna/page.tsx
@@ -1,10 +1,17 @@
+import { Box, Stack, Title } from '@mantine/core';
import React from 'react';
+import CreateInfoTeknologiTepatGuna from './create/page';
+import ListDataInfoTeknologiTepatGuna from './listData/page';
function Page() {
return (
-
- info-teknologi-tepat-guna
-
+
+
+ Info Teknologi Tepat Guna
+
+
+
+
);
}
diff --git a/src/app/admin/(dashboard)/inovasi/kolaborasi-inovasi/page.tsx b/src/app/admin/(dashboard)/inovasi/kolaborasi-inovasi/page.tsx
index 7af45fbc..9ffe9a5d 100644
--- a/src/app/admin/(dashboard)/inovasi/kolaborasi-inovasi/page.tsx
+++ b/src/app/admin/(dashboard)/inovasi/kolaborasi-inovasi/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 KolaborasiInovasi from './ui/kolaborasiInovasi/page';
+import MitraKolaborasi from './ui/mitraKolaborasi/page';
function Page() {
return (
-
- kolaborasi-inovasi
-
+
+
+ Kolaborasi Inovasi
+
+
+
+ Kolaborasi Inovasi
+
+
+ Mitra Kolaborasi
+
+
+
+
+
+
+
+
+
+
+
+
+
);
}
diff --git a/src/app/admin/(dashboard)/inovasi/kolaborasi-inovasi/ui/kolaborasiInovasi/page.tsx b/src/app/admin/(dashboard)/inovasi/kolaborasi-inovasi/ui/kolaborasiInovasi/page.tsx
new file mode 100644
index 00000000..06233369
--- /dev/null
+++ b/src/app/admin/(dashboard)/inovasi/kolaborasi-inovasi/ui/kolaborasiInovasi/page.tsx
@@ -0,0 +1,53 @@
+import colors from '@/con/colors';
+import { Box, Paper, SimpleGrid, Stack, Text, TextInput, Title } from '@mantine/core';
+import React from 'react';
+
+function KolaborasiInovasi() {
+ return (
+
+
+
+
+
+ Create Kolaborasi Inovasi
+ Tahun}
+ placeholder="Masukkan tahun"
+ />
+ Nama Kolaborasi Inovasi}
+ placeholder="Masukkan nama kolaborasi inovasi"
+ />
+ Deskripsi Kolaborasi Inovasi}
+ placeholder="Masukkan deskripsi kolaborasi inovasi"
+ />
+
+
+
+
+
+
+ List Data Kolaborasi Inovasi
+
+
+ Data 1
+
+
+ Data 2
+
+
+ Data 3
+
+
+ Data 4
+
+
+
+
+
+
+ );
+}
+
+export default KolaborasiInovasi;
diff --git a/src/app/admin/(dashboard)/inovasi/kolaborasi-inovasi/ui/mitraKolaborasi/page.tsx b/src/app/admin/(dashboard)/inovasi/kolaborasi-inovasi/ui/mitraKolaborasi/page.tsx
new file mode 100644
index 00000000..bb82016e
--- /dev/null
+++ b/src/app/admin/(dashboard)/inovasi/kolaborasi-inovasi/ui/mitraKolaborasi/page.tsx
@@ -0,0 +1,52 @@
+import React from 'react';
+import { Box, Button, Group, Paper, SimpleGrid, Stack, Text, TextInput, Title } from '@mantine/core';
+import colors from '@/con/colors';
+import { IconImageInPicture } from '@tabler/icons-react';
+
+function MitraKolaborasi() {
+ return (
+
+
+
+
+
+ Create Mitra Kolaborasi
+ Nama Mitra Kolaborasi}
+ placeholder="Masukkan nama mitra kolaborasi"
+ />
+
+ Masukkan Image
+
+
+
+ Submit
+
+
+
+
+
+
+ List Data Kolaborasi Inovasi
+
+
+ Foto 1
+
+
+ Foto 2
+
+
+ Foto 3
+
+
+ Foto 4
+
+
+
+
+
+
+ );
+}
+
+export default MitraKolaborasi;
diff --git a/src/app/admin/(dashboard)/inovasi/layanan-online-desa/page.tsx b/src/app/admin/(dashboard)/inovasi/layanan-online-desa/page.tsx
index 45fefebb..6274543f 100644
--- a/src/app/admin/(dashboard)/inovasi/layanan-online-desa/page.tsx
+++ b/src/app/admin/(dashboard)/inovasi/layanan-online-desa/page.tsx
@@ -1,10 +1,40 @@
+import colors from '@/con/colors';
+import { Box, Paper, Stack, Text, TextInput, Title } from '@mantine/core';
+import { IconImageInPicture } from '@tabler/icons-react';
import React from 'react';
function Page() {
return (
-
- layanan-online-desa
-
+
+
+
+
+
+ Layanan Online Desa
+ Nama Layanan}
+ placeholder="Masukkan nama layanan"
+ />
+ Deskripsi Layanan}
+ placeholder="Masukkan deskripsi layanan"
+ />
+
+ Upload Gambar Layanan
+
+
+
+
+
+
+
+
+ List Data Layanan Online Desa
+
+
+
+
+
);
}
diff --git a/src/app/admin/(dashboard)/inovasi/program-kreatif-desa/create/page.tsx b/src/app/admin/(dashboard)/inovasi/program-kreatif-desa/create/page.tsx
new file mode 100644
index 00000000..73761550
--- /dev/null
+++ b/src/app/admin/(dashboard)/inovasi/program-kreatif-desa/create/page.tsx
@@ -0,0 +1,37 @@
+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 ProgramKreatifCreate() {
+ return (
+
+
+
+
+ Create Program Kreatif Desa
+
+ Gambar
+
+
+ Nama Program}
+ placeholder="Masukkan nama program"
+ />
+ Deskripsi}
+ placeholder="Masukkan deskripsi"
+ />
+
+ Simpan
+
+
+
+
+
+ );
+}
+
+export default ProgramKreatifCreate;
diff --git a/src/app/admin/(dashboard)/inovasi/program-kreatif-desa/listData/page.tsx b/src/app/admin/(dashboard)/inovasi/program-kreatif-desa/listData/page.tsx
new file mode 100644
index 00000000..4089bed5
--- /dev/null
+++ b/src/app/admin/(dashboard)/inovasi/program-kreatif-desa/listData/page.tsx
@@ -0,0 +1,29 @@
+import colors from '@/con/colors';
+import { Box, Paper, SimpleGrid, Stack, Title } from '@mantine/core';
+import React from 'react';
+
+function ListDataProgramKreatifDesa() {
+ return (
+
+
+ List Data Program Kreatif Desa
+
+
+ Data 1
+
+
+ Data 2
+
+
+ Data 3
+
+
+ Data 4
+
+
+
+
+ );
+}
+
+export default ListDataProgramKreatifDesa;
diff --git a/src/app/admin/(dashboard)/inovasi/program-kreatif-desa/page.tsx b/src/app/admin/(dashboard)/inovasi/program-kreatif-desa/page.tsx
index e338e985..c529c95d 100644
--- a/src/app/admin/(dashboard)/inovasi/program-kreatif-desa/page.tsx
+++ b/src/app/admin/(dashboard)/inovasi/program-kreatif-desa/page.tsx
@@ -1,10 +1,17 @@
+import { Box, Stack, Title } from '@mantine/core';
import React from 'react';
+import ProgramKreatifCreate from './create/page';
+import ListDataProgramKreatifDesa from './listData/page';
function Page() {
return (
-
- program-kreatif-desa
-
+
+
+ Program Kreatif Desa
+
+
+
+
);
}
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
index 0f9e3b6c..7975625c 100644
--- 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
@@ -1,21 +1,24 @@
'use client'
-import { Box, Text } from '@mantine/core';
+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
- }}
- />
+
+ Kapan Harus ke Dokter
+ {
+ doctorSign.create.form.content = val
+ }}
+ />
+
);
}
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
index 9807b9aa..61021b8c 100644
--- 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
@@ -1,27 +1,32 @@
'use client'
-import { Box, Text, TextInput } from '@mantine/core';
+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 (
- Title Pertolongan Pertama}
- placeholder="Masukkan title"
- onChange={(val) => {
- firstAidState.create.form.title = val.target.value
- }}
- />
- {
- firstAidState.create.form.content = val
- }}
- />
+
+
+ Judul Pertolongan Pertama}
+ placeholder="Masukkan judul"
+ onChange={(val) => {
+ firstAidState.create.form.title = val.target.value
+ }}
+ />
+ {
+ firstAidState.create.form.content = val
+ }}
+ />
+
+
);
}
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
index 1795e482..7dce6b06 100644
--- 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
@@ -1,21 +1,26 @@
'use client'
-import { Box, Text } from '@mantine/core';
+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;
- }}
- />
+
+
+
+ Pendahuluan
+ {
+ introduction.create.form.content = val;
+ }}
+ />
+
+
);
}
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
index ea3eba9c..6a22d179 100644
--- 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
@@ -1,33 +1,38 @@
'use client'
import stateArtikelKesehatan from '@/app/admin/(dashboard)/_state/kesehatan/data_kesehatan_warga/artikelKesehatan';
-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 MythFactUI() {
const mythFact = useProxy(stateArtikelKesehatan.mythFact)
return (
-
- Title Pertolongan Pertama Penyakit}
- placeholder="Masukkan title"
- 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
- }}
- />
+
+
+
+ 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
+ }}
+ />
+
+
);
}
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 dcd27d6d..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,5 +1,5 @@
'use client'
-import { Box, Button, Center, SimpleGrid, Skeleton, Stack, Table, TableTbody, TableTd, TableTh, TableThead, TableTr, Text, Title } from '@mantine/core';
+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';
@@ -39,19 +39,25 @@ function ArtikelKesehatan() {
base: 1, md: 2
}}>
- Artikel Kesehatan
-
-
-
-
-
-
- Submit
+
+ Artikel Kesehatan
+
+
+
+
+
+
+
+ Submit
+
+
- List Artikel Kesehatan
-
+
+ Data Artikel Kesehatan
+
+
@@ -78,71 +84,88 @@ function AllList() {
) return
{Array.from({ length: 10 }).map((v, k) => )}
- return
- Intoduction
- {listState.introduction.findMany.data?.map((item) => (
-
-
-
- ))}
+ return
+ {/* Introduction */}
+
+ Pendahuluan
+ {listState.introduction.findMany.data?.map((item) => (
+
+
+
+ ))}
+
{/* Symptom */}
- {listState.symptom.findMany.data?.map((item) => (
-
- {item.title}
-
-
- ))}
+
+ Gejala Penyakit
+ {listState.symptom.findMany.data?.map((item) => (
+
+ {item.title}
+
+
+ ))}
+
{/* Prevention */}
- {listState.prevention.findMany.data?.map((item) => (
-
- {item.title}
-
-
- ))}
+
+ Pencegahan Penyakit
+ {listState.prevention.findMany.data?.map((item) => (
+
+ {item.title}
+
+
+ ))}
+
{/* First Aid */}
- {listState.firstAid.findMany.data?.map((item) => (
-
- {item.title}
-
-
- ))}
+
+ Pertolongan Pertama
+ {listState.firstAid.findMany.data?.map((item) => (
+
+ {item.title}
+
+
+ ))}
+
{/* Myth Fact */}
- {listState.mythFact.findMany.data?.map((item) => (
-
- {item.title}
-
-
-
-
- Mitos
-
-
- Fakta
-
-
-
-
-
- {item.mitos}
- {item.fakta}
-
-
-
-
- ))}
+
+ 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) => (
-
-
-
- ))}
+
+ Kapan Harus Ke Dokter?
+ {listState.doctorSign.findMany.data?.map((item) => (
+
+
+
+ ))}
+
}
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
index 95952f7b..4752cb9b 100644
--- 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
@@ -1,28 +1,33 @@
'use client'
import stateArtikelKesehatan from '@/app/admin/(dashboard)/_state/kesehatan/data_kesehatan_warga/artikelKesehatan';
-import { Box, Text, TextInput } from '@mantine/core';
+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 (
-
- Title Pencegahan Penyakit}
- placeholder="Masukkan title"
- onChange={(val) => {
- preventionState.create.form.title = val.target.value
- }}
- />
- {
- preventionState.create.form.content = val
- }}
- />
+
+
+
+ Judul Pencegahan Penyakit}
+ placeholder="Masukkan judul"
+ onChange={(val) => {
+ preventionState.create.form.title = val.target.value
+ }}
+ />
+ {
+ preventionState.create.form.content = val
+ }}
+ />
+
+
);
}
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
index 1dd6bd75..195775f8 100644
--- 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
@@ -1,27 +1,32 @@
'use client'
import stateArtikelKesehatan from '@/app/admin/(dashboard)/_state/kesehatan/data_kesehatan_warga/artikelKesehatan';
-import { Box, Text, TextInput } from '@mantine/core';
+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 (
-
- Title Gejala Penyakit}
- placeholder='masukkan title'
- onChange={(val) => {
- symptomState.create.form.title = val.target.value
- }}
- />
- {
- symptomState.create.form.content = val
- }}
- />
+
+
+
+ Judul Gejala Penyakit}
+ placeholder='masukkan judul'
+ onChange={(val) => {
+ symptomState.create.form.title = val.target.value
+ }}
+ />
+ {
+ symptomState.create.form.content = val
+ }}
+ />
+
+
);
}
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 fd107859..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
@@ -2,7 +2,7 @@
'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 { 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';
@@ -35,54 +35,65 @@ function GrafikHasilKepuasan() {
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 66639f6b..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,7 +1,8 @@
'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 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, Tooltip, XAxis, YAxis } from 'recharts';
@@ -32,76 +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)/lingkungan/data-lingkungan-desa/create/page.tsx b/src/app/admin/(dashboard)/lingkungan/data-lingkungan-desa/create/page.tsx
new file mode 100644
index 00000000..88e6e01a
--- /dev/null
+++ b/src/app/admin/(dashboard)/lingkungan/data-lingkungan-desa/create/page.tsx
@@ -0,0 +1,73 @@
+'use client'
+import colors from '@/con/colors';
+import { Box, Button, Paper, Stack, Text, TextInput, Title } from '@mantine/core';
+import { IconArrowBack, IconImageInPicture } from '@tabler/icons-react';
+import { useRouter } from 'next/navigation';
+import React from 'react';
+
+function CreateDataLingkunganDesa() {
+ const router = useRouter()
+ return (
+
+
+ router.back()}>
+
+
+
+
+
+
+ Create Data Lingkungan Desa
+ Judul}
+ placeholder="masukkan judul"
+ />
+
+ Deskripsi}
+ placeholder="masukkan deskripsi"
+ />
+
+ Gambar
+
+
+ {/* 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
+ {/* {
+ potensiState.create.form.content = htmlContent;
+ }}
+ /> */}
+
+
+ Simpan Data
+
+
+
+
+ );
+}
+
+export default CreateDataLingkunganDesa;
diff --git a/src/app/admin/(dashboard)/lingkungan/data-lingkungan-desa/page.tsx b/src/app/admin/(dashboard)/lingkungan/data-lingkungan-desa/page.tsx
index 1732a9f4..d9ba4dfc 100644
--- a/src/app/admin/(dashboard)/lingkungan/data-lingkungan-desa/page.tsx
+++ b/src/app/admin/(dashboard)/lingkungan/data-lingkungan-desa/page.tsx
@@ -1,11 +1,66 @@
+import { Box, Button, Image, Paper, Stack, Table, TableTbody, TableTd, TableTh, TableThead, TableTr, Text } from '@mantine/core';
import React from 'react';
+import HeaderSearch from '../../_com/header';
+import { IconDeviceImacCog, IconSearch } from '@tabler/icons-react';
+import colors from '@/con/colors';
+import JudulList from '../../_com/judulList';
-function Page() {
+function DataLingkunganDesa() {
return (
-
- data-lingkungan-desa
-
+
+ }
+ />
+
+
);
}
-export default Page;
+function ListDataLingkunganDesa() {
+ return (
+
+
+
+
+
+
+
+
+ Judul
+ Gambar
+ Deskripsi
+ Detail
+
+
+
+
+
+
+ Judul
+
+
+
+
+
+ Deskripsi
+
+
+
+
+
+
+
+
+
+
+
+
+ )
+}
+
+export default DataLingkunganDesa;
diff --git a/src/app/admin/(dashboard)/lingkungan/edukasi-lingkungan/create/page.tsx b/src/app/admin/(dashboard)/lingkungan/edukasi-lingkungan/create/page.tsx
new file mode 100644
index 00000000..df1978c0
--- /dev/null
+++ b/src/app/admin/(dashboard)/lingkungan/edukasi-lingkungan/create/page.tsx
@@ -0,0 +1,61 @@
+'use client'
+import React from 'react';
+import colors from '@/con/colors';
+import { Box, Button, Paper, Stack, Text, TextInput, Title } from '@mantine/core';
+import { IconArrowBack, IconImageInPicture } from '@tabler/icons-react';
+import { useRouter } from 'next/navigation';
+
+function Page() {
+ const router = useRouter()
+ return (
+
+
+ router.back()}>
+
+
+
+
+
+
+ Create Edukasi Lingkungan
+ Judul}
+ placeholder="masukkan judul"
+ />
+ 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 ? (
+
+ ) : (
+
+
+
+ )} */}
+
+ Gambar
+
+
+
+ Simpan
+
+
+
+
+ );
+}
+
+export default Page;
diff --git a/src/app/admin/(dashboard)/lingkungan/edukasi-lingkungan/page.tsx b/src/app/admin/(dashboard)/lingkungan/edukasi-lingkungan/page.tsx
index 3252f581..eaf32a93 100644
--- a/src/app/admin/(dashboard)/lingkungan/edukasi-lingkungan/page.tsx
+++ b/src/app/admin/(dashboard)/lingkungan/edukasi-lingkungan/page.tsx
@@ -1,11 +1,66 @@
+import { Box, Button, Image, Paper, Stack, Table, TableTbody, TableTd, TableTh, TableThead, TableTr, Text } from '@mantine/core';
import React from 'react';
+import HeaderSearch from '../../_com/header';
+import { IconDeviceImacCog, IconSearch } from '@tabler/icons-react';
+import colors from '@/con/colors';
+import JudulList from '../../_com/judulList';
-function Page() {
+function Page() {
return (
-
- edukasi-lingkungan
-
+
+ }
+ />
+
+
);
}
+function ListEdukasiLingkungan() {
+ return (
+
+
+
+
+
+
+
+
+ Judul
+ Gambar
+ Deskripsi
+ Detail
+
+
+
+
+
+
+ Judul
+
+
+
+
+
+ Deskripsi
+
+
+
+
+
+
+
+
+
+
+
+
+ )
+}
+
export default Page;
diff --git a/src/app/admin/(dashboard)/lingkungan/gotong-royong/create/page.tsx b/src/app/admin/(dashboard)/lingkungan/gotong-royong/create/page.tsx
new file mode 100644
index 00000000..07cfb090
--- /dev/null
+++ b/src/app/admin/(dashboard)/lingkungan/gotong-royong/create/page.tsx
@@ -0,0 +1,65 @@
+'use client'
+import colors from '@/con/colors';
+import { Box, Button, Paper, Stack, Text, TextInput, Title } from '@mantine/core';
+import { IconArrowBack, IconImageInPicture } from '@tabler/icons-react';
+import { useRouter } from 'next/navigation';
+import React from 'react';
+
+function Page() {
+ const router = useRouter()
+ return (
+
+
+ router.back()}>
+
+
+
+
+
+
+ Create Gotong Royong
+ Judul}
+ placeholder="masukkan judul"
+ />
+ Kategori}
+ placeholder="masukkan kategori"
+ />
+ 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 ? (
+
+ ) : (
+
+
+
+ )} */}
+
+ Gambar
+
+
+
+ Simpan
+
+
+
+
+ );
+}
+
+export default Page;
diff --git a/src/app/admin/(dashboard)/lingkungan/gotong-royong/page.tsx b/src/app/admin/(dashboard)/lingkungan/gotong-royong/page.tsx
index 95411df9..0f0e90aa 100644
--- a/src/app/admin/(dashboard)/lingkungan/gotong-royong/page.tsx
+++ b/src/app/admin/(dashboard)/lingkungan/gotong-royong/page.tsx
@@ -1,11 +1,68 @@
-import React from 'react';
+import { Box, Button, Image, Paper, Stack, Table, TableTbody, TableTd, TableTh, TableThead, TableTr, Text } from '@mantine/core';
+import { IconDeviceImacCog, IconSearch } from '@tabler/icons-react';
+import HeaderSearch from '../../_com/header';
+import colors from '@/con/colors';
+import JudulList from '../../_com/judulList';
-function Page() {
+function GotongRoyong() {
return (
-
- gotong-royong
-
+
+ }
+ />
+
+
);
}
-export default Page;
+function ListGotongRoyong() {
+ return (
+
+
+
+
+
+
+
+
+ Judul
+ Kategori
+ Image
+ Deskripsi
+ Detail
+
+
+
+
+
+
+ Judul
+
+
+ Kategori
+
+
+
+ Deskripsi
+
+
+
+
+
+
+
+
+
+
+
+
+
+ )
+}
+
+export default GotongRoyong;
diff --git a/src/app/admin/(dashboard)/lingkungan/konservasi-adat-bali/create/page.tsx b/src/app/admin/(dashboard)/lingkungan/konservasi-adat-bali/create/page.tsx
new file mode 100644
index 00000000..68bd0e1e
--- /dev/null
+++ b/src/app/admin/(dashboard)/lingkungan/konservasi-adat-bali/create/page.tsx
@@ -0,0 +1,62 @@
+'use client'
+import React from 'react';
+import colors from '@/con/colors';
+import { Box, Button, Paper, Stack, Text, TextInput, Title } from '@mantine/core';
+import { IconArrowBack, IconImageInPicture } from '@tabler/icons-react';
+import { useRouter } from 'next/navigation';
+
+function Page() {
+ const router = useRouter()
+ return (
+
+
+ router.back()}>
+
+
+
+
+
+
+ Create Konservasi Adat Bali
+ Judul}
+ placeholder="masukkan judul"
+ />
+ 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 ? (
+
+ ) : (
+
+
+
+ )} */}
+
+ Gambar
+
+
+
+ Simpan
+
+
+
+
+ );
+}
+
+export default Page;
diff --git a/src/app/admin/(dashboard)/lingkungan/konservasi-adat-bali/page.tsx b/src/app/admin/(dashboard)/lingkungan/konservasi-adat-bali/page.tsx
index c1f5bf13..6361c664 100644
--- a/src/app/admin/(dashboard)/lingkungan/konservasi-adat-bali/page.tsx
+++ b/src/app/admin/(dashboard)/lingkungan/konservasi-adat-bali/page.tsx
@@ -1,11 +1,66 @@
+import { Box, Button, Image, Paper, Stack, Table, TableTbody, TableTd, TableTh, TableThead, TableTr, Text } from '@mantine/core';
import React from 'react';
+import HeaderSearch from '../../_com/header';
+import { IconDeviceImacCog, IconSearch } from '@tabler/icons-react';
+import colors from '@/con/colors';
+import JudulList from '../../_com/judulList';
-function Page() {
+function KonservasiAdatBali() {
return (
-
- konservasi-adat-bali
-
+
+ }
+ />
+
+
);
}
-export default Page;
+function ListKonservasiAdatBali() {
+ return (
+
+
+
+
+
+
+
+
+ Judul
+ Gambar
+ Deskripsi
+ Detail
+
+
+
+
+
+
+ Judul
+
+
+
+
+
+ Deskripsi
+
+
+
+
+
+
+
+
+
+
+
+
+ )
+}
+
+export default KonservasiAdatBali;
diff --git a/src/app/admin/(dashboard)/lingkungan/pengelolaan-sampah-bank-sampah/create/page.tsx b/src/app/admin/(dashboard)/lingkungan/pengelolaan-sampah-bank-sampah/create/page.tsx
new file mode 100644
index 00000000..c8697ae0
--- /dev/null
+++ b/src/app/admin/(dashboard)/lingkungan/pengelolaan-sampah-bank-sampah/create/page.tsx
@@ -0,0 +1,71 @@
+'use client'
+import colors from "@/con/colors";
+import { Box, Button, Paper, Stack, Title, TextInput, Text } from "@mantine/core";
+import { IconArrowBack } from "@tabler/icons-react";
+import { useRouter } from "next/navigation";
+
+
+export default function CreatePengelolaanSampahBankSampah() {
+ const router = useRouter()
+ return (
+
+
+ router.back()}>
+
+
+
+
+
+
+ Create Mekanisme Bank Sampah
+
+ Judul}
+ placeholder="masukkan judul"
+ />
+
+ 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
+ {/* {
+ potensiState.create.form.content = htmlContent;
+ }}
+ /> */}
+
+
+
+ Simpan
+
+
+
+
+ )
+}
+
diff --git a/src/app/admin/(dashboard)/lingkungan/pengelolaan-sampah-bank-sampah/page.tsx b/src/app/admin/(dashboard)/lingkungan/pengelolaan-sampah-bank-sampah/page.tsx
index 05e93042..85239543 100644
--- a/src/app/admin/(dashboard)/lingkungan/pengelolaan-sampah-bank-sampah/page.tsx
+++ b/src/app/admin/(dashboard)/lingkungan/pengelolaan-sampah-bank-sampah/page.tsx
@@ -1,11 +1,33 @@
-import React from 'react';
+import { Box, Stack, Tabs, TabsList, TabsPanel, TabsTab, Title } from '@mantine/core';
+import ListPage from './ui/list_page/listPage';
+import colors from '@/con/colors';
-function Page() {
+function PengelolaanSampahBankSampah() {
return (
-
- pengelolaan-sampah-bank-sampah
-
- );
+
+
+ Pengelolaan Sampah Bank Sampah
+
+
+
+ List Pengelolaan Sampah Bank Sampah
+
+
+ Maps
+
+
+
+
+
+
+
+
+ Maps
+
+
+
+
+ )
}
-export default Page;
+export default PengelolaanSampahBankSampah;
diff --git a/src/app/admin/(dashboard)/lingkungan/pengelolaan-sampah-bank-sampah/ui/list_page/listPage.tsx b/src/app/admin/(dashboard)/lingkungan/pengelolaan-sampah-bank-sampah/ui/list_page/listPage.tsx
new file mode 100644
index 00000000..c6bef31a
--- /dev/null
+++ b/src/app/admin/(dashboard)/lingkungan/pengelolaan-sampah-bank-sampah/ui/list_page/listPage.tsx
@@ -0,0 +1,66 @@
+import { Box, Button, Image, Paper, Stack, Table, TableTbody, TableTd, TableTh, TableThead, TableTr, Text } from '@mantine/core';
+import React from 'react';
+import HeaderSearch from '@/app/admin/(dashboard)/_com/header';
+import { IconDeviceImacCog, IconSearch } from '@tabler/icons-react';
+import colors from '@/con/colors';
+import JudulList from '@/app/admin/(dashboard)/_com/judulList';
+
+function ListPage() {
+ return (
+
+ }
+ />
+
+
+ );
+}
+
+function ListPengelolaanSampahBankSampah() {
+ return (
+
+
+
+
+
+
+
+
+ Judul
+ Gambar
+ Deskripsi
+ Detail
+
+
+
+
+
+
+ Judul
+
+
+
+
+
+ Deskripsi
+
+
+
+
+
+
+
+
+
+
+
+
+ )
+}
+
+export default ListPage;
diff --git a/src/app/admin/(dashboard)/lingkungan/program-penghijauan/create/page.tsx b/src/app/admin/(dashboard)/lingkungan/program-penghijauan/create/page.tsx
new file mode 100644
index 00000000..4c1e91c2
--- /dev/null
+++ b/src/app/admin/(dashboard)/lingkungan/program-penghijauan/create/page.tsx
@@ -0,0 +1,73 @@
+'use client'
+import colors from '@/con/colors';
+import { Box, Button, Paper, Stack, Text, TextInput, Title } from '@mantine/core';
+import { IconArrowBack, IconImageInPicture } from '@tabler/icons-react';
+import { useRouter } from 'next/navigation';
+
+function Page() {
+ const router = useRouter()
+ return (
+
+
+ router.back()}>
+
+
+
+
+
+
+ Create Program Penghijauan
+
+ Judul}
+ placeholder="masukkan judul"
+ />
+
+ Deskripsi}
+ placeholder="masukkan deskripsi"
+ />
+
+ Gambar
+
+ {/* 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
+ {/* {
+ potensiState.create.form.content = htmlContent;
+ }}
+ /> */}
+
+
+
+ Simpan Potensi
+
+
+
+
+ );
+}
+
+export default Page;
diff --git a/src/app/admin/(dashboard)/lingkungan/program-penghijauan/page.tsx b/src/app/admin/(dashboard)/lingkungan/program-penghijauan/page.tsx
index eb7a466b..e818879d 100644
--- a/src/app/admin/(dashboard)/lingkungan/program-penghijauan/page.tsx
+++ b/src/app/admin/(dashboard)/lingkungan/program-penghijauan/page.tsx
@@ -1,11 +1,68 @@
-import React from 'react';
+import { Box, Button, Image, Paper, Stack, Table, TableTbody, TableTd, TableTh, TableThead, TableTr, Text } from '@mantine/core';
+import HeaderSearch from '../../_com/header';
+import { IconDeviceImacCog, IconSearch } from '@tabler/icons-react';
+import colors from '@/con/colors';
+import JudulList from '../../_com/judulList';
-function Page() {
+function ProgramPenghijauan() {
return (
-
- program-penghijauan
-
+
+ }
+ />
+
+
);
}
-export default Page;
+function ListManfaatPenghijauan() {
+ return (
+
+
+
+
+
+
+
+
+ Judul
+ Gambar
+ Jumlah
+ Deskripsi
+ Detail
+
+
+
+
+
+
+ Judul
+
+
+
+ Jumlah
+
+
+
+
+ Deskripsi
+
+
+
+
+
+
+
+
+
+
+
+
+ )
+}
+
+export default ProgramPenghijauan;
diff --git a/src/app/admin/(dashboard)/ppid/_com/PPIDTextEditor.tsx b/src/app/admin/(dashboard)/ppid/_com/PPIDTextEditor.tsx
index b540c2e2..2e6629aa 100644
--- a/src/app/admin/(dashboard)/ppid/_com/PPIDTextEditor.tsx
+++ b/src/app/admin/(dashboard)/ppid/_com/PPIDTextEditor.tsx
@@ -8,14 +8,14 @@ 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';
-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 PPIDTextEditor({ onSubmit, onChange, showSubmit = true }: {
+export function PPIDTextEditor({ onSubmit, onChange, showSubmit = true, initialContent = '', }: {
onSubmit?: (val: string) => void,
onChange: (val: string) => void,
- showSubmit?: boolean }) {
+ showSubmit?: boolean,
+ initialContent?: string }) {
const editor = useEditor({
extensions: [
StarterKit,
@@ -27,12 +27,18 @@ export function PPIDTextEditor({ onSubmit, onChange, showSubmit = true }: {
TextAlign.configure({ types: ['heading', 'paragraph'] }),
],
immediatelyRender: false,
- content,
+ content: initialContent,
onUpdate : ({editor}) => {
onChange(editor.getHTML())
}
});
+ useEffect(() => {
+ if (editor && initialContent !== editor.getHTML()) {
+ editor.commands.setContent(initialContent || '
');
+ }
+ }, [initialContent, editor]);
+
return (
diff --git a/src/app/admin/(dashboard)/ppid/_com/ppid_Editor.tsx b/src/app/admin/(dashboard)/ppid/_com/ppid_Editor.tsx
index 29954bc9..b261c75a 100644
--- a/src/app/admin/(dashboard)/ppid/_com/ppid_Editor.tsx
+++ b/src/app/admin/(dashboard)/ppid/_com/ppid_Editor.tsx
@@ -10,7 +10,7 @@ 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 ';
+ 'Dokumen yang berisi kebijakan dan regulasi desa
';
export function PPIDEditor({ onSubmit, onChange, showSubmit = true }: {
onSubmit?: (val: string) => void,
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 9ee3ca61..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,10 @@
'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 React from 'react';
+import { useShallowEffect } from '@mantine/hooks';
import { useProxy } from 'valtio/utils';
import stateDaftarInformasiPublik from '../../_state/ppid/daftar_informasi_publik/daftarInformasiPublik';
-import { PPIDEditor } from '../_com/ppid_Editor';
-import colors from '@/con/colors';
-import { useShallowEffect } from '@mantine/hooks';
+import { PPIDTextEditor } from '../_com/PPIDTextEditor';
function Page() {
const daftarInformasi = useProxy(stateDaftarInformasiPublik.daftarInformasi)
@@ -30,7 +29,7 @@ function Page() {
daftarInformasi.create.form.jenisInformasi = val.target.value
}}
/>
- {
daftarInformasi.create.form.deskripsi = val
@@ -68,46 +67,50 @@ function ListDaftarInformasi() {
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}
-
- ))}
-
-
-
-
+ 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_hasil_kepuasan_masyarakat/page.tsx b/src/app/admin/(dashboard)/ppid/ikm-desa-darmasaba/_ui/grafik_hasil_kepuasan_masyarakat/page.tsx
index 5ece0a34..b114d94e 100644
--- 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
@@ -36,7 +36,6 @@ function GrafikHasilKepuasan() {
Grafik Hasil Kepuasan Masyarakat Terhadap Pelayanan Publik
-
-
+
+ Indeks Kepuasan Masyarakat (IKM) Desa Darmasaba
+
+
Grafik Hasil Kepuasan Masyarakat Terhadap Pelayanan Publik
diff --git a/src/app/admin/(dashboard)/ppid/permohonan-informasi-publik/jenisInformasi.tsx b/src/app/admin/(dashboard)/ppid/permohonan-informasi-publik/jenisInformasi.tsx
deleted file mode 100644
index 90a1c6f7..00000000
--- a/src/app/admin/(dashboard)/ppid/permohonan-informasi-publik/jenisInformasi.tsx
+++ /dev/null
@@ -1,41 +0,0 @@
-import { Prisma } from '@prisma/client';
-import React from 'react';
-import { useProxy } from 'valtio/utils';
-import statePermohonanInformasi from '../../_state/ppid/permohonan_informasi_publik/permohonanInformasiPublik';
-import { useShallowEffect } from '@mantine/hooks';
-import { Group, Select, Skeleton } from '@mantine/core';
-
-function JenisInformasi({ onChange }: {
- onChange: (value: Prisma.JenisInformasiDimintaGetPayload<{
- select: {
- id: true,
- name: true
- }
- }>) => void
-}) {
- const jenisInformasiState = useProxy(statePermohonanInformasi.jenisInformasiDiminta)
- useShallowEffect(() => {
- jenisInformasiState.findMany.load()
- }, [])
-
- if (!jenisInformasiState.findMany.data) return
- return (
-
- ({
- value: item.id,
- label: item.name
- }))}
- onChange={(v) => {
- const data = jenisInformasiState.findMany.data?.find((item) => item.id === v)
- if (!data) return
- onChange(data)
- }}
- />
-
- );
-}
-
-export default JenisInformasi;
diff --git a/src/app/admin/(dashboard)/ppid/permohonan-informasi-publik/memperolehInformasi.tsx b/src/app/admin/(dashboard)/ppid/permohonan-informasi-publik/memperolehInformasi.tsx
deleted file mode 100644
index 1bc91900..00000000
--- a/src/app/admin/(dashboard)/ppid/permohonan-informasi-publik/memperolehInformasi.tsx
+++ /dev/null
@@ -1,38 +0,0 @@
-import { 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 '../../_state/ppid/permohonan_informasi_publik/permohonanInformasiPublik';
-
-function MemperolehInformasi({ onChange }: {
- onChange: (value: Prisma.CaraMemperolehInformasiGetPayload<{
- select: {
- id: true,
- name: true
- }
- }>) => void
-}) {
- const memperolehInformasiState = useProxy(statePermohonanInformasi.caraMemperolehInformasi)
-
- useShallowEffect(() => {
- memperolehInformasiState.findMany.load()
- }, [])
- return (
-
- ({
- value: item.id,
- label: item.name
- }))} onChange={(v) => {
- const data = memperolehInformasiState.findMany.data?.find((item) => item.id === v)
- if (!data) return
- onChange(data)
- }} />
-
- );
-}
-
-export default MemperolehInformasi;
diff --git a/src/app/admin/(dashboard)/ppid/permohonan-informasi-publik/memperolehSalinan.tsx b/src/app/admin/(dashboard)/ppid/permohonan-informasi-publik/memperolehSalinan.tsx
deleted file mode 100644
index b5dfc2b8..00000000
--- a/src/app/admin/(dashboard)/ppid/permohonan-informasi-publik/memperolehSalinan.tsx
+++ /dev/null
@@ -1,45 +0,0 @@
-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';
-import statePermohonanInformasi from '../../_state/ppid/permohonan_informasi_publik/permohonanInformasiPublik';
-
-function MemperolehSalinan({ onChange }: {
- onChange: (value: Prisma.CaraMemperolehSalinanInformasiGetPayload<{
- select: {
- id: true,
- name: true
- }
- }>) => void
-}) {
- const memperolehSalinanInformasiState = useProxy(statePermohonanInformasi.caraMemperolehSalinanInformasi)
- useShallowEffect(() => {
- memperolehSalinanInformasiState.findMany.load()
- }, [])
-
- if (!memperolehSalinanInformasiState.findMany.data) return
- return (
-
- ({
- value: item.id,
- label: item.name
- }))}
- onChange={(v) => {
- if (!v) return
- const selectedItem = memperolehSalinanInformasiState.findMany.data?.find(item => item.id === v)
- if (selectedItem) {
- onChange({
- id: selectedItem.id,
- name: selectedItem.name
- })
- }
- }}
- />
-
- );
-}
-export default MemperolehSalinan;
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 bab23af5..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,115 +1,57 @@
'use client'
-import { Box, Button, Group, Paper, SimpleGrid, Stack, TextInput, Title } from '@mantine/core';
-import { useProxy } from 'valtio/utils';
-import statePermohonanInformasi from '../../_state/ppid/permohonan_informasi_publik/permohonanInformasiPublik';
-import JenisInformasi from './jenisInformasi';
-import MemperolehInformasi from './memperolehInformasi';
-import MemperolehSalinan from './memperolehSalinan';
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
+
+
+
+
+ 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}
+
+ ))}
+
+
+
+
);
}
-function PermohonanInformasiPublikCreate() {
- const permohonanInformasiPublikState = useProxy(statePermohonanInformasi)
- const submitForms = () => {
- // Tambahkan log untuk debugging
- console.log("Form data sebelum submit:", {
- name: permohonanInformasiPublikState.permohonanInformasiPublikForm.create.form.name,
- nik: permohonanInformasiPublikState.permohonanInformasiPublikForm.create.form.nik,
- notelp: permohonanInformasiPublikState.permohonanInformasiPublikForm.create.form.notelp,
- alamat: permohonanInformasiPublikState.permohonanInformasiPublikForm.create.form.alamat,
- email: permohonanInformasiPublikState.permohonanInformasiPublikForm.create.form.email,
- jenisInformasiDimintaId: permohonanInformasiPublikState.jenisInformasiDiminta,
- caraMemperolehInformasiId: permohonanInformasiPublikState.caraMemperolehInformasi,
- caraMemperolehSalinanInformasiId: permohonanInformasiPublikState.caraMemperolehSalinanInformasi
- });
-
- if (permohonanInformasiPublikState.permohonanInformasiPublikForm.create.form.name &&
- permohonanInformasiPublikState.permohonanInformasiPublikForm.create.form.nik &&
- permohonanInformasiPublikState.permohonanInformasiPublikForm.create.form.notelp &&
- permohonanInformasiPublikState.permohonanInformasiPublikForm.create.form.alamat &&
- permohonanInformasiPublikState.permohonanInformasiPublikForm.create.form.email &&
- permohonanInformasiPublikState.jenisInformasiDiminta &&
- permohonanInformasiPublikState.caraMemperolehInformasi &&
- permohonanInformasiPublikState.caraMemperolehSalinanInformasi) {
- permohonanInformasiPublikState.permohonanInformasiPublikForm.create.create()
- } else {
- console.log("Validasi gagal, form tidak lengkap");
- // Tampilkan pesan error ke pengguna di sini
- }
- }
- return (
-
-
-
- Permohonan Informasi Publik
- {
- permohonanInformasiPublikState.permohonanInformasiPublikForm.create.form.name = val.target.value
- }}
- />
- {
- permohonanInformasiPublikState.permohonanInformasiPublikForm.create.form.nik = val.target.value
- }}
- />
- {
- permohonanInformasiPublikState.permohonanInformasiPublikForm.create.form.notelp = val.target.value
- }}
- />
- {
- permohonanInformasiPublikState.permohonanInformasiPublikForm.create.form.alamat = val.target.value
- }}
- />
- {
- permohonanInformasiPublikState.permohonanInformasiPublikForm.create.form.email = val.target.value
- }}
- />
- {
- permohonanInformasiPublikState.permohonanInformasiPublikForm.create.form.jenisInformasiDimintaId = val.id
- }}
- />
- {
- permohonanInformasiPublikState.permohonanInformasiPublikForm.create.form.caraMemperolehInformasiId = val.id
- }}
- />
- {
- permohonanInformasiPublikState.permohonanInformasiPublikForm.create.form.caraMemperolehSalinanInformasiId = val.id
- }}
- />
-
- Submit
-
-
-
-
- )
-}
-
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 e416f772..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,73 +1,12 @@
'use client'
import colors from '@/con/colors';
-import { Box, Button, Group, Paper, SimpleGrid, Skeleton, Stack, Text, TextInput, Title } from '@mantine/core';
-import React from 'react';
+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';
-import { useShallowEffect } from '@mantine/hooks';
function Page() {
- return (
-
-
-
-
-
-
- );
-}
-
-function PermohonanKeberatanInformasiCreate() {
- const state = useProxy(statePermohonanKeberatan.permohonanKeberatanInformasiForm)
- const submit = () => {
- if (state.create.form.name && state.create.form.email && state.create.form.notelp && state.create.form.alasan) {
- state.create.create()
- }
- }
- return (
-
-
-
- Permohonan Keberatan Informasi Publik
- {
- state.create.form.name = val.target.value
- }}
- />
- {
- state.create.form.email = val.target.value
- }}
- />
- {
- state.create.form.notelp = val.target.value
- }}
- />
- {
- state.create.form.alasan = val.target.value
- }}
- />
-
- Kirim Permohonan
-
-
-
-
- )
-}
-
-function PermohonanKeberatanInformasiList() {
- const listState = useProxy(statePermohonanKeberatan.permohonanKeberatanInformasiForm)
+ const listState = useProxy(statePermohonanKeberatan)
useShallowEffect(() => {
listState.findMany.load()
}, [])
@@ -75,24 +14,36 @@ function PermohonanKeberatanInformasiList() {
if (!listState.findMany.data) return
{Array.from({ length: 10 }).map((v, k) => )}
-
return (
Permohonan Keberatan Informasi Publik
- {listState.findMany.data?.map((item) => (
-
- Nama: {item.name}
- Email: {item.email}
- Telepon: {item.notelp}
- Alasan: {item.alasan}
-
- ))}
+
+
+
+ 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
index bbb1c86b..bde2d57d 100644
--- a/src/app/admin/(dashboard)/ppid/profile-ppid/biodata/page.tsx
+++ b/src/app/admin/(dashboard)/ppid/profile-ppid/biodata/page.tsx
@@ -1,24 +1,76 @@
'use client'
-import { Box, Text } from '@mantine/core';
-import React from 'react';
+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 { PPIDEditor } from '../../_com/ppid_Editor';
+import { PPIDTextEditor } from '../../_com/PPIDTextEditor';
function Biodata() {
- const biodataState = useProxy(stateProfilePPID.profilePPID)
+ const biodataState = useProxy(stateProfilePPID)
+ const [loading, setLoading] = useState(false);
+
return (
Biodata
- {
- biodataState.create.form.biodata = val
- }}
- />
-
+ {
+ 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;
+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 9036584d..de1a55a3 100644
--- a/src/app/admin/(dashboard)/ppid/profile-ppid/page.tsx
+++ b/src/app/admin/(dashboard)/ppid/profile-ppid/page.tsx
@@ -1,6 +1,6 @@
'use client'
import colors from '@/con/colors';
-import { Box, Button, Group, Paper, SimpleGrid, Skeleton, Stack, Text, TextInput, Title } from '@mantine/core';
+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';
@@ -8,6 +8,9 @@ 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() {
@@ -22,16 +25,33 @@ function 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.profilePPID.create.form.name &&
- allState.profilePPID.create.form.biodata &&
- allState.profilePPID.create.form.riwayat &&
- allState.profilePPID.create.form.pengalaman &&
- allState.profilePPID.create.form.unggulan) {
- allState.profilePPID.create.create()
- }
+ 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 (
@@ -41,8 +61,11 @@ function ProfileCreate() {
Nama Perbekel}
placeholder="masukkan nama perbekel"
+ value={allState.findById.data?.name || ''}
onChange={(val) => {
- allState.profilePPID.create.form.name = val.currentTarget.value
+ if (allState.findById.data) {
+ allState.findById.data.name = val.currentTarget.value
+ }
}}
/>
@@ -50,53 +73,17 @@ function ProfileCreate() {
- Submit
+
+ Submit
+
)
}
-function ProfileList() {
- const allList = useProxy(stateProfilePPID)
- useShallowEffect(() => {
- allList.profilePPID.findMany.load()
- }, [])
-
- if (!allList.profilePPID.findMany.data) return
- {Array.from({ length: 10 }).map((v, k) => )}
-
- return (
-
-
- List Profile PPID
- {allList.profilePPID.findMany.data?.map((item) => (
-
-
- Nama
-
-
-
- Biodata
-
-
-
- Riwayat
-
-
-
- Pengalaman
-
-
-
- Program Kerja Unggulan
-
-
-
- ))}
-
-
- )
-}
-
-export default Page;
+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
index 791a6e63..20be1859 100644
--- a/src/app/admin/(dashboard)/ppid/profile-ppid/pengalaman_organisasi/page.tsx
+++ b/src/app/admin/(dashboard)/ppid/profile-ppid/pengalaman_organisasi/page.tsx
@@ -3,17 +3,21 @@ 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 { PPIDEditor } from '../../_com/ppid_Editor';
+import { PPIDTextEditor } from '../../_com/PPIDTextEditor';
function PengalamanOrganisasi() {
- const pengalamanOrganisasiState = useProxy(stateProfilePPID.profilePPID)
+ const pengalamanOrganisasiState = useProxy(stateProfilePPID)
return (
Pengalaman Organisasi
- {
- pengalamanOrganisasiState.create.form.pengalaman = val
+ if (pengalamanOrganisasiState.findById.data) {
+ pengalamanOrganisasiState.findById.data.pengalaman = val;
+ }
}}
+ initialContent={pengalamanOrganisasiState.findById.data?.pengalaman ?? ''}
/>
);
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
index 8c222071..c643f51e 100644
--- 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
@@ -3,17 +3,21 @@ 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 { PPIDEditor } from '../../_com/ppid_Editor';
+import { PPIDTextEditor } from '../../_com/PPIDTextEditor';
function ProgramKerjaUnggulan() {
- const programKerjaUnggulanState = useProxy(stateProfilePPID.profilePPID)
+ const programKerjaUnggulanState = useProxy(stateProfilePPID)
return (
Program Kerja Unggulan
- {
- programKerjaUnggulanState.create.form.unggulan = val
+ if (programKerjaUnggulanState.findById.data) {
+ programKerjaUnggulanState.findById.data.unggulan = val;
+ }
}}
+ initialContent={programKerjaUnggulanState.findById.data?.unggulan ?? ''}
/>
);
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
index 9c280e35..f1ecd870 100644
--- a/src/app/admin/(dashboard)/ppid/profile-ppid/riwayat_karir/page.tsx
+++ b/src/app/admin/(dashboard)/ppid/profile-ppid/riwayat_karir/page.tsx
@@ -7,21 +7,24 @@ import dynamic from 'next/dynamic';
import stateProfilePPID from '../../../_state/ppid/profile_ppid/profile_PPID';
// ini penting
-const PPIDEditor = dynamic(() => import('../../_com/ppid_Editor').then(mod => mod.PPIDEditor), {
+const PPIDTextEditor = dynamic(() => import('../../_com/PPIDTextEditor').then(mod => mod.PPIDTextEditor), {
ssr: false, // disable server side rendering
});
-
function RiwayatKarir() {
- const biodataState = useProxy(stateProfilePPID.profilePPID);
+ const riwayatKarirState = useProxy(stateProfilePPID);
return (
Riwayat Karir
- {
- biodataState.create.form.riwayat = val;
+ if (riwayatKarirState.findById.data) {
+ riwayatKarirState.findById.data.riwayat = val;
+ }
}}
+ initialContent={riwayatKarirState.findById.data?.riwayat ?? ''}
/>
);
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..937d2a1d 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..e64f67ca 100644
--- a/src/app/api/[[...slugs]]/_lib/desa/berita/create.ts
+++ b/src/app/api/[[...slugs]]/_lib/desa/berita/create.ts
@@ -6,23 +6,21 @@ 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)
-
await prisma.berita.create({
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-by-id.ts b/src/app/api/[[...slugs]]/_lib/desa/berita/find-by-id.ts
new file mode 100644
index 00000000..54e6deac
--- /dev/null
+++ b/src/app/api/[[...slugs]]/_lib/desa/berita/find-by-id.ts
@@ -0,0 +1,59 @@
+import prisma from "@/lib/prisma";
+
+export default async function handler(
+ request: Request
+) {
+ // Extract the ID from the URL path
+ const url = new URL(request.url);
+ const pathSegments = url.pathname.split('/');
+ const id = pathSegments[pathSegments.length - 1];
+
+ if (!id) {
+ return Response.json({
+ success: false,
+ message: "ID tidak boleh kosong",
+ }, { status: 400 });
+ }
+
+ try {
+ // Validate that the ID is a valid UUID or whatever format you're using
+ if (typeof id !== 'string') {
+ return Response.json({
+ success: false,
+ message: "ID tidak valid",
+ }, { status: 400 });
+ }
+
+ const data = await prisma.berita.findUnique({
+ where: { id },
+ include: {
+ image: true,
+ kategoriBerita: true,
+ },
+ });
+
+ if (!data) {
+ return Response.json({
+ success: false,
+ message: "Berita tidak ditemukan",
+ }, { status: 404 });
+ }
+
+ // Ensure we're returning a proper Response object
+ return Response.json({
+ success: true,
+ message: "Success fetch berita by ID",
+ data,
+ }, {
+ status: 200,
+ });
+ } catch (e) {
+ console.error("Find by ID error:", e);
+ return Response.json({
+ success: false,
+ message: "Gagal mengambil berita: " + (e instanceof Error ? e.message : 'Unknown error'),
+ }, {
+ status: 500,
+ });
+ }
+}
\ No newline at end of file
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..3fdf3b63 100644
--- a/src/app/api/[[...slugs]]/_lib/desa/berita/index.ts
+++ b/src/app/api/[[...slugs]]/_lib/desa/berita/index.ts
@@ -1,19 +1,43 @@
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";
+import findBeritaById from "./find-by-id";
const Berita = new Elysia({ prefix: "/berita", tags: ["Desa/Berita"] })
- .get("/category/find-many", katagoryBeritaFindMany)
+ .get("/category/find-many", kategoriBeritaFindMany)
.get("/find-many", beritaFindMany)
+ .get("/:id", async (context) => {
+ const response = await findBeritaById(new Request(context.request));
+ return response;
+ })
.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(
+ "/:id",
+ async (context) => {
+ const response = await beritaUpdate(context);
+ return response;
+ },
+ {
+ body: t.Object({
+ judul: t.String(),
+ deskripsi: t.String(),
+ imageId: t.String(),
+ content: t.String(),
+ kategoriBeritaId: t.Union([t.String(), t.Null()]),
+ }),
+ }
+ );
export default Berita;
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..d9c03582
--- /dev/null
+++ b/src/app/api/[[...slugs]]/_lib/desa/berita/updt.ts
@@ -0,0 +1,98 @@
+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) {
+ try {
+ 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 new Response(
+ JSON.stringify({ success: false, message: "ID tidak boleh kosong" }),
+ { status: 400, headers: { 'Content-Type': 'application/json' } }
+ );
+ }
+
+ const existing = await prisma.berita.findUnique({
+ where: { id },
+ include: {
+ image: true,
+ kategoriBerita: true,
+ },
+ });
+
+ if (!existing) {
+ return new Response(
+ JSON.stringify({ success: false, message: "Berita tidak ditemukan" }),
+ { status: 404, headers: { 'Content-Type': 'application/json' } }
+ );
+ }
+
+ 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: kategoriBeritaId || null,
+ imageId,
+ },
+ });
+
+ return new Response(
+ JSON.stringify({
+ success: true,
+ message: "Berita berhasil diupdate",
+ data: updated,
+ }),
+ { status: 200, headers: { 'Content-Type': 'application/json' } }
+ );
+ } catch (error) {
+ console.error("Error updating berita:", error);
+ return new Response(
+ JSON.stringify({
+ success: false,
+ message: "Terjadi kesalahan saat mengupdate berita",
+ }),
+ { status: 500, headers: { 'Content-Type': 'application/json' } }
+ );
+ }
+}
+ 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..fc8b25db 100644
--- a/src/app/api/[[...slugs]]/_lib/desa/index.ts
+++ b/src/app/api/[[...slugs]]/_lib/desa/index.ts
@@ -1,9 +1,13 @@
import Elysia from "elysia";
import Berita from "./berita";
import Pengumuman from "./pengumuman";
+import ProfileDesa from "./profile/profile_desa";
+import PotensiDesa from "./potensi";
const Desa = new Elysia({ prefix: "/api/desa", tags: ["Desa"] })
.use(Berita)
.use(Pengumuman)
+ .use(ProfileDesa)
+ .use(PotensiDesa)
export default Desa;
diff --git a/src/app/api/[[...slugs]]/_lib/desa/potensi/create.ts b/src/app/api/[[...slugs]]/_lib/desa/potensi/create.ts
new file mode 100644
index 00000000..54754aa4
--- /dev/null
+++ b/src/app/api/[[...slugs]]/_lib/desa/potensi/create.ts
@@ -0,0 +1,33 @@
+import prisma from "@/lib/prisma";
+import { Prisma } from "@prisma/client";
+import { Context } from "elysia";
+
+type FormCreate = Prisma.PotensiDesaGetPayload<{
+ select: {
+ name: true;
+ deskripsi: true;
+ kategori: true;
+ imageId: true;
+ content: true;
+ }
+}>
+export default async function potensiDesaCreate(context: Context) {
+ const body = context.body as FormCreate;
+
+ await prisma.potensiDesa.create({
+ data: {
+ name: body.name,
+ deskripsi: body.deskripsi,
+ kategori: body.kategori,
+ imageId: body.imageId,
+ content: body.content,
+ },
+ });
+ return {
+ success: true,
+ message: "Success create potensi desa",
+ data: {
+ ...body,
+ },
+ };
+}
\ No newline at end of file
diff --git a/src/app/api/[[...slugs]]/_lib/desa/potensi/del.ts b/src/app/api/[[...slugs]]/_lib/desa/potensi/del.ts
new file mode 100644
index 00000000..8f8eb916
--- /dev/null
+++ b/src/app/api/[[...slugs]]/_lib/desa/potensi/del.ts
@@ -0,0 +1,54 @@
+import prisma from "@/lib/prisma";
+import path from "path";
+import { Context } from "vm";
+import fs from "fs/promises";
+
+const potensiDesaDelete = async (context: Context) => {
+ const id = context.params?.id as string;
+
+ if (!id) {
+ return {
+ status: 400,
+ body: "ID tidak diberikan",
+ };
+ }
+
+ const potensiDesa = await prisma.potensiDesa.findUnique({
+ where: { id },
+ include: {
+ image: true,
+ },
+ });
+
+ if (!potensiDesa) {
+ return {
+ status: 404,
+ body: "Potensi Desa tidak ditemukan",
+ };
+ }
+
+ // Hapus file gambar dari filesystem jika ada
+ if (potensiDesa.image) {
+ try {
+ const filePath = path.join(potensiDesa.image.path, potensiDesa.image.name);
+ await fs.unlink(filePath);
+ await prisma.fileStorage.delete({
+ where: { id: potensiDesa.image.id },
+ });
+ } catch (err) {
+ console.error("Gagal hapus file image:", err);
+ }
+ }
+
+ // Hapus potensi desa dari DB
+ await prisma.potensiDesa.delete({
+ where: { id },
+ });
+
+ return {
+ success: true,
+ message: "Potensi Desa dan file terkait berhasil dihapus",
+ };
+};
+
+export default potensiDesaDelete;
\ No newline at end of file
diff --git a/src/app/api/[[...slugs]]/_lib/desa/potensi/find-many.ts b/src/app/api/[[...slugs]]/_lib/desa/potensi/find-many.ts
new file mode 100644
index 00000000..bf78eacb
--- /dev/null
+++ b/src/app/api/[[...slugs]]/_lib/desa/potensi/find-many.ts
@@ -0,0 +1,26 @@
+import prisma from "@/lib/prisma";
+
+async function potensiDesaFindMany() {
+ try {
+ const data = await prisma.potensiDesa.findMany({
+ where: { isActive: true },
+ include: {
+ image: true,
+ },
+ });
+
+ return {
+ success: true,
+ message: "Success fetch potensi desa",
+ data,
+ };
+ } catch (e) {
+ console.error("Find many error:", e);
+ return {
+ success: false,
+ message: "Failed fetch potensi desa",
+ };
+ }
+}
+
+export default potensiDesaFindMany
\ No newline at end of file
diff --git a/src/app/api/[[...slugs]]/_lib/desa/potensi/find-unique.ts b/src/app/api/[[...slugs]]/_lib/desa/potensi/find-unique.ts
new file mode 100644
index 00000000..d5944f87
--- /dev/null
+++ b/src/app/api/[[...slugs]]/_lib/desa/potensi/find-unique.ts
@@ -0,0 +1,51 @@
+import prisma from "@/lib/prisma";
+
+export default async function findUnique(
+ request: Request) {
+ const url = new URL(request.url);
+ const pathSegments = url.pathname.split('/');
+ const id = pathSegments[pathSegments.length - 1];
+
+ if(!id) {
+ return Response.json({
+ success: false,
+ message: "ID tidak boleh kosong",
+ }, { status: 400 });
+ }
+
+ try {
+ if( typeof id !== 'string') {
+ return Response.json({
+ success: false,
+ message: "ID harus berupa string",
+ }, { status: 400 });
+ }
+
+ const data = await prisma.potensiDesa.findUnique({
+ where: { id },
+ include: {
+ image: true,
+ },
+ });
+
+ if(!data) {
+ return Response.json({
+ success: false,
+ message: "Potensi Desa tidak ditemukan",
+ }, { status: 404 });
+ }
+
+ return Response.json({
+ success: true,
+ message: "Success fetch potensi desa by ID",
+ data,
+ }, { status: 200 });
+ } catch (error) {
+ console.error("Find by ID error:", error);
+ return Response.json({
+ success: false,
+ message: "Gagal mengambil potensi desa: " + (error instanceof Error ? error.message : 'Unknown error'),
+ }, { status: 500 });
+ }
+
+}
\ No newline at end of file
diff --git a/src/app/api/[[...slugs]]/_lib/desa/potensi/index.ts b/src/app/api/[[...slugs]]/_lib/desa/potensi/index.ts
new file mode 100644
index 00000000..2cf0b658
--- /dev/null
+++ b/src/app/api/[[...slugs]]/_lib/desa/potensi/index.ts
@@ -0,0 +1,45 @@
+import Elysia from "elysia";
+import createPotensiDesa from "./create";
+import { t } from "elysia";
+import potensiDesaDelete from "./del";
+import potensiDesaFindMany from "./find-many";
+import potensiDesaUpdate from "./updt";
+import findUnique from "./find-unique";
+
+
+const PotensiDesa = new Elysia({
+ prefix: "/potensi", tags: ["Desa/Potensi"]
+})
+ .post("/create", createPotensiDesa, {
+ body: t.Object({
+ name: t.String(),
+ deskripsi: t.String(),
+ kategori: t.String(),
+ imageId: t.String(),
+ content: t.String(),
+ }),
+ })
+ .delete("/del/:id", potensiDesaDelete)
+ .get("/find-many", potensiDesaFindMany)
+ .get("/:id", async (context) => {
+ const response = await findUnique(new Request(context.request));
+ return response;
+ })
+ .put(
+ "/:id",
+ async (context) => {
+ const response = await potensiDesaUpdate(context);
+ return response;
+ },
+ {
+ body: t.Object({
+ name: t.String(),
+ deskripsi: t.String(),
+ kategori: t.String(),
+ imageId: t.String(),
+ content: t.String(),
+ }),
+ }
+ )
+
+export default PotensiDesa
\ No newline at end of file
diff --git a/src/app/api/[[...slugs]]/_lib/desa/potensi/updt.ts b/src/app/api/[[...slugs]]/_lib/desa/potensi/updt.ts
new file mode 100644
index 00000000..5edc9506
--- /dev/null
+++ b/src/app/api/[[...slugs]]/_lib/desa/potensi/updt.ts
@@ -0,0 +1,98 @@
+import prisma from "@/lib/prisma";
+import { Prisma } from "@prisma/client";
+import { Context } from "elysia";
+import path from "path";
+import fs from "fs/promises";
+
+type FormUpdate = Prisma.PotensiDesaGetPayload<{
+ select: {
+ id: true;
+ name: true;
+ deskripsi: true;
+ kategori: true;
+ imageId: true;
+ content: true;
+ };
+}>;
+
+export default async function potensiDesaUpdate(context: Context) {
+ try {
+ const id = context.params?.id as string;
+ const body = (await context.body) as Omit;
+
+ const {
+ name,
+ deskripsi,
+ kategori,
+ imageId,
+ content,
+ } = body;
+
+ if (!id) {
+ return new Response(
+ JSON.stringify({ success: false, message: "ID tidak ditemukan" }),
+ { status: 400, headers: { 'Content-Type': 'application/json' } }
+ )
+ }
+
+ const existing = await prisma.potensiDesa.findUnique({
+ where: { id },
+ include: {
+ image: true,
+ }
+ });
+
+ if (!existing) {
+ return new Response(
+ JSON.stringify({ success: false, message: "Potensi Desa tidak ditemukan"}),
+ { status: 404, headers: { 'Content-Type': 'application/json' } }
+ )
+ }
+
+ 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 (error) {
+ console.error("Gagal hapus gambar lama:", error);
+ }
+ }
+ }
+
+ const updated = await prisma.potensiDesa.update({
+ where: { id },
+ data: {
+ name,
+ deskripsi,
+ kategori,
+ imageId,
+ content,
+ },
+ });
+
+ return new Response(
+ JSON.stringify({
+ success: true,
+ message: "Potensi Desa berhasil diupdate",
+ data: updated,
+ }),
+ { status: 200, headers: { 'Content-Type': 'application/json' } }
+ );
+ } catch (error) {
+ console.error("Error updating potensi desa:", error);
+ return new Response(
+ JSON.stringify({
+ success: false,
+ message: "Terjadi kesalahan saat mengupdate potensi desa",
+ }),
+ { status: 500, headers: { 'Content-Type': 'application/json' } }
+ );
+ }
+
+}
+
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/ppid/daftar_informasi_publik/create.ts b/src/app/api/[[...slugs]]/_lib/ppid/daftar_informasi_publik/create.ts
index 79a95c98..252c10f0 100644
--- a/src/app/api/[[...slugs]]/_lib/ppid/daftar_informasi_publik/create.ts
+++ b/src/app/api/[[...slugs]]/_lib/ppid/daftar_informasi_publik/create.ts
@@ -11,9 +11,12 @@ type FormCreate = Prisma.DaftarInformasiPublikGetPayload<{
}>
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,
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/index.ts b/src/app/api/[[...slugs]]/_lib/ppid/index.ts
index 07df0252..d830064c 100644
--- a/src/app/api/[[...slugs]]/_lib/ppid/index.ts
+++ b/src/app/api/[[...slugs]]/_lib/ppid/index.ts
@@ -7,7 +7,9 @@ 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";
+import VisiMisiPPID from "./visi_misi_ppid/visi_misi_ppid";
+import DasarHukumPPID from "./dasar_hukum";
+
@@ -21,6 +23,7 @@ const PPID = new Elysia({ prefix: "/api/ppid", tags: ["PPID"] })
.use(PermohonanInformasiPublik)
.use(PermohonanKeberatanInformasiPublik)
.use(VisiMisiPPID)
+.use(DasarHukumPPID)
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
index 21932013..4cc99f88 100644
--- a/src/app/api/[[...slugs]]/_lib/ppid/permohonan_informasi_publik/create.ts
+++ b/src/app/api/[[...slugs]]/_lib/ppid/permohonan_informasi_publik/create.ts
@@ -26,6 +26,7 @@ export default async function permohonanInformasiPublikCreate(context: Context)
alamat: body.alamat,
jenisInformasiDimintaId: body.jenisInformasiDimintaId,
caraMemperolehInformasiId: body.caraMemperolehInformasiId,
+ caraMemperolehSalinanInformasiId: body.caraMemperolehSalinanInformasiId,
}
})
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
index dd3d6770..f8f32d41 100644
--- 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
@@ -1,7 +1,13 @@
import prisma from "@/lib/prisma";
export default async function permohonanInformasiPublikFindMany() {
- const res = await prisma.permohonanInformasiPublik.findMany();
+ 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/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/find-many.ts b/src/app/api/[[...slugs]]/_lib/ppid/profile_ppid/find-many.ts
deleted file mode 100644
index 1edb803f..00000000
--- a/src/app/api/[[...slugs]]/_lib/ppid/profile_ppid/find-many.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-import prisma from "@/lib/prisma";
-
-export default async function profilePPIDFindMany() {
- const res = await prisma.profilePPID.findMany();
- return{
- data: res
- }
-}
-
\ No newline at end of file
diff --git a/src/app/api/[[...slugs]]/_lib/ppid/profile_ppid/index.ts b/src/app/api/[[...slugs]]/_lib/ppid/profile_ppid/index.ts
index 88dbe815..fb274096 100644
--- a/src/app/api/[[...slugs]]/_lib/ppid/profile_ppid/index.ts
+++ b/src/app/api/[[...slugs]]/_lib/ppid/profile_ppid/index.ts
@@ -1,14 +1,16 @@
import Elysia, { t } from "elysia";
-import profilePPIDCreate from "./create";
-import profilePPIDFindMany from "./find-many";
+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-many", profilePPIDFindMany)
- .post("/create", profilePPIDCreate, {
+ .get("/find-by-id", profilePPIDFindById)
+ .post("/update", profilePPIDUpdate, {
body: t.Object({
+ id: t.String(),
name: t.String(),
biodata: t.String(),
riwayat: t.String(),
@@ -16,6 +18,7 @@ const ProfilePPID = new Elysia({
unggulan: t.String(),
})
})
+ .post("/edit-img", editImageProfilePPID)
export default ProfilePPID;
diff --git a/src/app/api/[[...slugs]]/_lib/ppid/profile_ppid/create.ts b/src/app/api/[[...slugs]]/_lib/ppid/profile_ppid/update.ts
similarity index 80%
rename from src/app/api/[[...slugs]]/_lib/ppid/profile_ppid/create.ts
rename to src/app/api/[[...slugs]]/_lib/ppid/profile_ppid/update.ts
index 19a733a4..621e98f4 100644
--- a/src/app/api/[[...slugs]]/_lib/ppid/profile_ppid/create.ts
+++ b/src/app/api/[[...slugs]]/_lib/ppid/profile_ppid/update.ts
@@ -4,6 +4,7 @@ import { Context } from "elysia";
type FormCreate = Prisma.ProfilePPIDGetPayload<{
select: {
+ id: true;
name: true;
biodata: true;
riwayat: true;
@@ -11,10 +12,13 @@ type FormCreate = Prisma.ProfilePPIDGetPayload<{
unggulan: true;
}
}>
-export default async function profilePPIDCreate(context: Context) {
+export default async function profilePPIDUpdate(context: Context) {
const body = context.body as FormCreate;
- await prisma.profilePPID.create({
+ await prisma.profilePPID.update({
+ where: {
+ id: body.id
+ },
data: {
name: body.name,
biodata: body.biodata,
diff --git a/src/app/api/[[...slugs]]/_lib/ppid/visi_misi_ppid/index.ts b/src/app/api/[[...slugs]]/_lib/ppid/visi_misi_ppid/index.ts
deleted file mode 100644
index e41bf86d..00000000
--- a/src/app/api/[[...slugs]]/_lib/ppid/visi_misi_ppid/index.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-import Elysia from "elysia";
-import MisiPPID from "./misi_ppid";
-
-const VisiMisiPPID = new Elysia({ prefix: "/visimisippid", tags: ["PPID/Visi Misi PPID"] })
-.use(MisiPPID)
-
-export default VisiMisiPPID
\ No newline at end of file
diff --git a/src/app/api/[[...slugs]]/_lib/ppid/visi_misi_ppid/misi_ppid/create.ts b/src/app/api/[[...slugs]]/_lib/ppid/visi_misi_ppid/misi_ppid/create.ts
deleted file mode 100644
index 2be2fb31..00000000
--- a/src/app/api/[[...slugs]]/_lib/ppid/visi_misi_ppid/misi_ppid/create.ts
+++ /dev/null
@@ -1,27 +0,0 @@
-import prisma from "@/lib/prisma";
-import { Prisma } from "@prisma/client";
-import { Context } from "elysia";
-
-type FormCreate = Prisma.MisiPPIDGetPayload<{
- select: {
- content: true;
- }
-}>
-
-export default async function misiPPIDCreate(context: Context) {
- const body = context.body as FormCreate;
-
- await prisma.misiPPID.create({
- data: {
- content: body.content,
- }
- })
-
- return {
- success: true,
- message: "Misi PPID Berhasil Dibuat",
- data: {
- ...body,
- }
- }
-}
\ No newline at end of file
diff --git a/src/app/api/[[...slugs]]/_lib/ppid/visi_misi_ppid/misi_ppid/delete.ts b/src/app/api/[[...slugs]]/_lib/ppid/visi_misi_ppid/misi_ppid/delete.ts
deleted file mode 100644
index c100c412..00000000
--- a/src/app/api/[[...slugs]]/_lib/ppid/visi_misi_ppid/misi_ppid/delete.ts
+++ /dev/null
@@ -1,17 +0,0 @@
-import prisma from "@/lib/prisma";
-import { Context } from "elysia";
-
-export async function misiPPIDDelete(context: Context) {
- const id = context.params.id
-
- await prisma.misiPPID.delete({
- where: {
- id: id
- }
- })
-
- return {
- success: true,
- message: "Misi PPID Berhasil Dihapus",
- }
-}
\ No newline at end of file
diff --git a/src/app/api/[[...slugs]]/_lib/ppid/visi_misi_ppid/misi_ppid/find-many.ts b/src/app/api/[[...slugs]]/_lib/ppid/visi_misi_ppid/misi_ppid/find-many.ts
deleted file mode 100644
index c41181e6..00000000
--- a/src/app/api/[[...slugs]]/_lib/ppid/visi_misi_ppid/misi_ppid/find-many.ts
+++ /dev/null
@@ -1,8 +0,0 @@
-import prisma from "@/lib/prisma";
-
-export async function misiPPIDFindMany() {
- const res = await prisma.misiPPID.findMany();
- return {
- data: res,
- };
-}
\ No newline at end of file
diff --git a/src/app/api/[[...slugs]]/_lib/ppid/visi_misi_ppid/misi_ppid/index.ts b/src/app/api/[[...slugs]]/_lib/ppid/visi_misi_ppid/misi_ppid/index.ts
deleted file mode 100644
index 8f8ad523..00000000
--- a/src/app/api/[[...slugs]]/_lib/ppid/visi_misi_ppid/misi_ppid/index.ts
+++ /dev/null
@@ -1,24 +0,0 @@
-import Elysia, { t } from "elysia";
-import { misiPPIDFindMany } from "./find-many";
-import misiPPIDCreate from "./create";
-import { misiPPIDDelete } from "./delete";
-import misiPPIDUpdate from "./update";
-
-const MisiPPID = new Elysia({
- prefix: "/misippid",
- tags: ["PPID/Visi Misi PPID/ Misi PPID"],
-})
-.get("/find-many", misiPPIDFindMany)
-.post("/create", misiPPIDCreate, {
- body: t.Object({
- content: t.String(),
- })
-})
-.put("/update/:id", misiPPIDUpdate, {
- body: t.Object({
- content: t.String(),
- })
-})
-.delete("/delete/:id", misiPPIDDelete)
-
-export default MisiPPID;
\ No newline at end of file
diff --git a/src/app/api/[[...slugs]]/_lib/ppid/visi_misi_ppid/misi_ppid/update.ts b/src/app/api/[[...slugs]]/_lib/ppid/visi_misi_ppid/misi_ppid/update.ts
deleted file mode 100644
index ccc1319b..00000000
--- a/src/app/api/[[...slugs]]/_lib/ppid/visi_misi_ppid/misi_ppid/update.ts
+++ /dev/null
@@ -1,29 +0,0 @@
-import prisma from "@/lib/prisma";
-import { Prisma } from "@prisma/client";
-import { Context } from "elysia";
-
-type FormUpdate = Prisma.MisiPPIDGetPayload<{
- select: {
- content: true;
- }
-}>
-
-export default async function misiPPIDUpdate(context: Context) {
- const id = context.params.id
- const body = context.body as FormUpdate;
-
- await prisma.misiPPID.update({
- where: { id: id },
- data: {
- content: body.content,
- }
- })
-
- return {
- success: true,
- message: "Misi PPID Berhasil Diupdate",
- 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 840f15ae..3f2fd804 100644
--- a/src/app/api/[[...slugs]]/route.ts
+++ b/src/app/api/[[...slugs]]/route.ts
@@ -1,20 +1,23 @@
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 PPID from "./_lib/ppid";
+import FileStorage from "./_lib/fileStorage";
+
const ROOT = process.cwd();
@@ -62,11 +65,18 @@ const Utils = new Elysia({
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 {
@@ -77,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/Footer.tsx b/src/app/darmasaba/_com/Footer.tsx
index 05909d12..d3755a94 100644
--- a/src/app/darmasaba/_com/Footer.tsx
+++ b/src/app/darmasaba/_com/Footer.tsx
@@ -10,7 +10,7 @@ function Footer() {
return (
<>
-
+
diff --git a/src/app/darmasaba/_com/main-page/desaantikorupsi/index.tsx b/src/app/darmasaba/_com/main-page/desaantikorupsi/index.tsx
index 72303ca2..b446f2da 100644
--- a/src/app/darmasaba/_com/main-page/desaantikorupsi/index.tsx
+++ b/src/app/darmasaba/_com/main-page/desaantikorupsi/index.tsx
@@ -44,9 +44,9 @@ function DesaAntiKorupsi() {
- Desa Anti Korupsi
+ Desa Anti Korupsi
- Desa antikorupsi mendorong pemerintahan jujur dan transparan. Keuangan desa dikelola terbuka dengan melibatkan warga mengawasi anggaran, sehingga digunakan tepat sasaran sesuai kebutuhan.
+ Desa antikorupsi mendorong pemerintahan jujur dan transparan. Keuangan desa dikelola terbuka dengan melibatkan warga mengawasi anggaran, sehingga digunakan tepat sasaran sesuai kebutuhan.
Selengkapnya
@@ -65,13 +65,13 @@ function DesaAntiKorupsi() {
- {v.judul}
+ {v.judul}
{v.icon}
- {v.deskripsi}
+ {v.deskripsi}
diff --git a/src/app/darmasaba/_com/main-page/kepuasan/index.tsx b/src/app/darmasaba/_com/main-page/kepuasan/index.tsx
index c173a10f..865784a9 100644
--- a/src/app/darmasaba/_com/main-page/kepuasan/index.tsx
+++ b/src/app/darmasaba/_com/main-page/kepuasan/index.tsx
@@ -1,7 +1,8 @@
"use client";
-import { Stack, Container, Center, Text, Paper, Flex, Box, SimpleGrid } from "@mantine/core";
-import { BarChart, PieChart } from '@mantine/charts';
import colors from "@/con/colors";
+import { BarChart, PieChart } from '@mantine/charts';
+import { Box, Center, Container, Flex, Paper, SimpleGrid, Stack, Text } from "@mantine/core";
+import { useMediaQuery } from "@mantine/hooks";
const dataBarChart = [
{
@@ -71,13 +72,14 @@ const dataPieChart3 = [
]
function Kepuasan() {
+ const isMobile = useMediaQuery('(max-width: 768px)');
return (
- Indeks Kepuasan Masyarakat
+ Indeks Kepuasan Masyarakat
- Ukur kebahagiaan warga, tingkatkan layanan desa! Dengan partisipasi aktif masyarakat, kami berkomitmen untuk terus memperbaiki layanan agar lebih transparan, efektif, dan sesuai dengan kebutuhan warga. Kepuasan Anda adalah prioritas utama kami dalam membangun desa yang lebih baik!
+ Ukur kebahagiaan warga, tingkatkan layanan desa! Dengan partisipasi aktif masyarakat, kami berkomitmen untuk terus memperbaiki layanan agar lebih transparan, efektif, dan sesuai dengan kebutuhan warga. Kepuasan Anda adalah prioritas utama kami dalam membangun desa yang lebih baik!
@@ -118,7 +120,7 @@ function Kepuasan() {
Jenis Kelamin
Pilihan
Umur
-
-
+
+
Jadwal Kerja
@@ -168,7 +164,14 @@ function LandingPage() {
-
+
+
+
+
Rabu, 10 Maret 2025
@@ -187,7 +190,8 @@ function LandingPage() {
-
+
+
diff --git a/src/app/darmasaba/_com/main-page/penghargaan/index.tsx b/src/app/darmasaba/_com/main-page/penghargaan/index.tsx
index 5900da5a..6927c548 100644
--- a/src/app/darmasaba/_com/main-page/penghargaan/index.tsx
+++ b/src/app/darmasaba/_com/main-page/penghargaan/index.tsx
@@ -51,7 +51,7 @@ function Penghargaan() {
Juara 2 Duta Investasi
-
+
Juara Favorit Lomba Video Pendek
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/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;
+ }
+}
+