Compare commits
6 Commits
nico/push-
...
nico/15-ma
| Author | SHA1 | Date | |
|---|---|---|---|
| f5d68d4982 | |||
| 2844132ea0 | |||
| e5889ca903 | |||
| 8a34a122d0 | |||
| 795c79dd5f | |||
| a8556aacb7 |
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "desa-darmasaba",
|
||||
"version": "0.1.1",
|
||||
"version": "0.1.2",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "next dev --turbopack",
|
||||
@@ -16,6 +16,7 @@
|
||||
"@cubejs-client/core": "^0.31.0",
|
||||
"@elysiajs/cors": "^1.2.0",
|
||||
"@elysiajs/eden": "^1.2.0",
|
||||
"@elysiajs/static": "^1.3.0",
|
||||
"@elysiajs/stream": "^1.1.0",
|
||||
"@elysiajs/swagger": "^1.2.0",
|
||||
"@mantine/carousel": "^7.16.2",
|
||||
@@ -47,14 +48,16 @@
|
||||
"elysia": "^1.2.12",
|
||||
"embla-carousel-autoplay": "^8.5.2",
|
||||
"embla-carousel-react": "^7.1.0",
|
||||
"form-data": "^4.0.2",
|
||||
"framer-motion": "^12.4.1",
|
||||
"get-port": "^7.1.0",
|
||||
"jotai": "^2.12.3",
|
||||
"lodash": "^4.17.21",
|
||||
"motion": "^12.4.1",
|
||||
"nanoid": "^5.1.0",
|
||||
"nanoid": "^5.1.5",
|
||||
"next": "15.1.6",
|
||||
"next-view-transitions": "^0.3.4",
|
||||
"node-fetch": "^3.3.2",
|
||||
"p-limit": "^6.2.0",
|
||||
"prisma": "^6.3.1",
|
||||
"react": "^19.0.0",
|
||||
|
||||
9
prisma/data/desa/profile/profil_perbekel.json
Normal file
9
prisma/data/desa/profile/profil_perbekel.json
Normal file
@@ -0,0 +1,9 @@
|
||||
[
|
||||
{
|
||||
"id": "1",
|
||||
"biodata": "<p>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.</p>",
|
||||
"pengalaman": "<ul><li>2021 - 2027: Perbekel Desa Darmasaba</li><li>2015 - Sekarang: Founder & Managing Director Mantra Legal Consultants & Advocates</li><li>2020 - Sekarang: Founder Ugawa Record Music Studio</li><li>2010 - 2016: Dosen Fakultas Hukum Universitas Mahasaraswati Denpasar</li></ul>",
|
||||
"pengalamanOrganisasi": "<ul> <li>1996 – 1997: Ketua OSIS SMP Negeri 1 Abiansemal</li><li>1999 – 2000: Ketua OSIS SMA Negeri 1 Mengwi</li> <li>2008 – 2009: Ketua BEM Universitas Mahasaraswati Denpasar</li> <li>2008 – 2010: Ketua Sekaa Taruna Sila Dharma, Banjar Tengah, Desa Adat Tegal, Darmasaba</li> <li>2020 – Sekarang: Pengurus Young Lawyer Committee Peradi Denpasar</li> <li>2021 – Sekarang: Dewan Kehormatan Himpunan Pengusaha Muda Indonesia (HIPMI) Badung</li> <li>2023 – 2028: Komite Tetap Advokasi – Bidang Hukum dan Regulasi Kamar Dagang dan Industri Badung</li> </ul>",
|
||||
"programUnggulan": "<h3>Pemberdayaan Ekonomi dan UMKM</h3> <ul> <li>Pelatihan dan pendampingan UMKM lokal</li> <li>Program bantuan modal usaha bagi pelaku usaha kecil</li><li>Digitalisasi UMKM untuk meningkatkan pemasaran produk lokal</li></ul>"
|
||||
}
|
||||
]
|
||||
11
prisma/data/desa/profile/profile_desa.json
Normal file
11
prisma/data/desa/profile/profile_desa.json
Normal file
@@ -0,0 +1,11 @@
|
||||
[
|
||||
{
|
||||
"id": "1",
|
||||
"sejarah" : "<p>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.</p>",
|
||||
"visi" : "<p>Mewujudkan Desa Darmasaba yang sejahtera, unggul, religius, berbudaya, dan aman dengan berlandaskan Tri Hita Karana</p>",
|
||||
"misi" : "<ul><li>Memperkokoh kerukunan hidup masyarakat dalam jalinan adat, budaya, olahraga, dan agama.</li><li>Meningkatkan kualitas pelayanan publik dengan menerapkan teknologi informasi dan komunikasi terintegrasi.</li><li>Meningkatkan tata kelola pemerintah desa dengan menerapkan prinsip good governance dan good clean government.</li><li>Meningkatkan kualitas pendidikan, kesehatan, Keluarga Berencana serta pengelolaan kependudukan.</li><li>Memperkuat usaha mikro kecil dan menengah (UMKM) dan BUMDesa sebagai pilar ekonomi masyarakat.</li><li>Mewujudkan tatanan kehidupan bermasyarakat yang menjunjung tinggi penegakan hukum dan HAM.</li><li>Meningkatkan perlindungan dan pengelolaan terhadap sumber daya alam dan lingkungan hidup.</li><li>Memperkuat daya saing desa melalui peningkatan mutu sumber daya manusia dan infrastruktur desa berbasis potensi desa.</li><li>Meningkatkan sinergisitas potensi budaya, pertanian dalam arti luas dan pariwisata.</li></ul>",
|
||||
"lambang" : "<ul><li>Memperkokoh kerukunan hidup masyarakat dalam jalinan adat, budaya, olahraga, dan agama.</li><li>Meningkatkan kualitas pelayanan publik dengan menerapkan teknologi informasi dan komunikasi terintegrasi.</li><li>Meningkatkan tata kelola pemerintah desa dengan menerapkan prinsip good governance dan good clean government.</li><li>Meningkatkan kualitas pendidikan, kesehatan, Keluarga Berencana serta pengelolaan kependudukan.</li><li>Memperkuat usaha mikro kecil dan menengah (UMKM) dan BUMDesa sebagai pilar ekonomi masyarakat.</li><li>Mewujudkan tatanan kehidupan bermasyarakat yang menjunjung tinggi penegakan hukum dan HAM.</li><li>Meningkatkan perlindungan dan pengelolaan terhadap sumber daya alam dan lingkungan hidup.</li><li>Memperkuat daya saing desa melalui peningkatan mutu sumber daya manusia dan infrastruktur desa berbasis potensi desa.</li><li>Meningkatkan sinergisitas potensi budaya, pertanian dalam arti luas dan pariwisata.</li><li>Memperkuat daya saing desa melalui peningkatan mutu sumber daya manusia dan infrastruktur desa berbasis potensi desa.</li><li>Meningkatkan sinergisitas potensi budaya, pertanian dalam arti luas dan pariwisata.</li></ul>",
|
||||
"maskot" : "<p>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.</p><p>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.</p><p>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.</p><p>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.</p><p>Garapan Tari Maskot Desa Darmasaba Sekar Pudak diwujudkan ke dalam bentuk tari kreasi yang ditarikan secara berkelompok dengan jumlah lima orang penari perempuan (putri).</p><p>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.</p>",
|
||||
"profilPerbekelId" : "1"
|
||||
}
|
||||
]
|
||||
5
prisma/data/list-caraMemperolehInformasi.json
Normal file
5
prisma/data/list-caraMemperolehInformasi.json
Normal file
@@ -0,0 +1,5 @@
|
||||
[
|
||||
{"name": "Melihat/Membaca/Mendengarkan/Mencatat"},
|
||||
{"name": "Mendapatkan Salinan Informasi (Hardcopy)"},
|
||||
{"name": "Mendapatkan Salinan Informasi (Softcopy)"}
|
||||
]
|
||||
5
prisma/data/list-caraMemperolehSalinanInformasi.json
Normal file
5
prisma/data/list-caraMemperolehSalinanInformasi.json
Normal file
@@ -0,0 +1,5 @@
|
||||
[
|
||||
{ "name": "Mengambil Langsung" },
|
||||
{ "name": "Dikirim Via Post" },
|
||||
{ "name": "Dikirim Via Email" }
|
||||
]
|
||||
6
prisma/data/list-jenisInfromasi.json
Normal file
6
prisma/data/list-jenisInfromasi.json
Normal file
@@ -0,0 +1,6 @@
|
||||
[
|
||||
{ "name": "Keuangan Desa" },
|
||||
{ "name": "Pembangunan Desa" },
|
||||
{ "name": "Data Demografi" },
|
||||
{ "name": "Lainnya" }
|
||||
]
|
||||
@@ -0,0 +1,8 @@
|
||||
[
|
||||
{
|
||||
"id": "1",
|
||||
"jenisInformasi": "Peraturan Desa",
|
||||
"deskripsi": "Dokumen yang berisi kebijakan dan regulasi desa",
|
||||
"tanggal": "15 Januari 2024"
|
||||
}
|
||||
]
|
||||
7
prisma/data/ppid/dasar-hukum-ppid/dasarhukumPPID.json
Normal file
7
prisma/data/ppid/dasar-hukum-ppid/dasarhukumPPID.json
Normal file
@@ -0,0 +1,7 @@
|
||||
[
|
||||
{
|
||||
"id": "1",
|
||||
"judul": "DASAR HUKUM PEMBENTUKAN PPID DESA DARMASABA",
|
||||
"content" : "<ul><li>UU Nomor 14 Tahun 2008 tentang Keterbukaan Informasi Publik</li><li>PP Nomor 61 Tahun 2010 tentang Pelaksanaan UU 14 Tahun 2008 tentang Keterbukaan Informasi Publik</li><li>Permendagri Nomor 3 Tahun 2017 tentang Pedoman Pengelolaan Pelayanan Informasi dan Dokumentasi di Lingkungan Kemendagri dan Pemerintah Daerah</li><li>Peraturan Komisi Informasi Nomor 1 Tahun 2010 tentang Standar Layanan Informasi Publik</li><li>Peraturan Komisi Informasi Nomor 1 Tahun 2010 tentang Standar Layanan Informasi Publik</li><li>Peraturan Bupati Badung No. 42 Tahun 2017 tentang Pedoman Pengelolaan Pelayanan Informasi Publik dan Dokumentasi di Lingkungan Pemerintah Kabupaten Badung</li><li>Keputusan Bupati Badung Nomor 99/049/HK/2019 tentang Pengelola Layanan Informasi dan Dokumentasi Kabupaten Badung</li><li>Keputusan Perbekel Darmasaba Nomor 101 Tahun 2019 tentang Penetapan Pelaksana Teknis/Administrasi Pengelola Layanan Informasi Dan Dokumentasi di Desa Punggul</li><li>Peraturan Perbekel Darmasaba Nomor 12 Tahun 2019 tentang Pedoman Pengelolaan Pelayanan Informasi Publik dan Dokumentasi di Lingkungan Pemerintah Desa Darmasaba</li></ul>"
|
||||
}
|
||||
]
|
||||
11
prisma/data/ppid/profile-ppid/profilePPid.json
Normal file
11
prisma/data/ppid/profile-ppid/profilePPid.json
Normal file
@@ -0,0 +1,11 @@
|
||||
[
|
||||
{
|
||||
"id": "1",
|
||||
"name": "I.B Surya Prabhawa Manuaba, S.H., M.H.",
|
||||
"biodata": "<p>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.</p>",
|
||||
"riwayat": "<ul> <li>2021 - 2027: Perbekel Desa Darmasaba</li> <li>2015 - Sekarang: Founder & Managing Director Mantra Legal Consultants & Advocates</li> <li>2020 - Sekarang: Founder Ugawa Record Music Studio</li> <li>2010 - 2016: Dosen Fakultas Hukum Universitas Mahasaraswati Denpasar</li> </ul>",
|
||||
"pengalaman": "<ul> <li>1996 – 1997: Ketua OSIS SMP Negeri 1 Abiansemal</li><li>1999 – 2000: Ketua OSIS SMA Negeri 1 Mengwi</li> <li>2008 – 2009: Ketua BEM Universitas Mahasaraswati Denpasar</li> <li>2008 – 2010: Ketua Sekaa Taruna Sila Dharma, Banjar Tengah, Desa Adat Tegal, Darmasaba</li> <li>2020 – Sekarang: Pengurus Young Lawyer Committee Peradi Denpasar</li> <li>2021 – Sekarang: Dewan Kehormatan Himpunan Pengusaha Muda Indonesia (HIPMI) Badung</li> <li>2023 – 2028: Komite Tetap Advokasi – Bidang Hukum dan Regulasi Kamar Dagang dan Industri Badung</li> </ul>",
|
||||
"unggulan": "<h3>Pemberdayaan Ekonomi dan UMKM</h3> <ul> <li>Pelatihan dan pendampingan UMKM lokal</li> <li>Program bantuan modal usaha bagi pelaku usaha kecil</li><li>Digitalisasi UMKM untuk meningkatkan pemasaran produk lokal</li></ul>",
|
||||
"imageUrl": "/assets/images/ppid/profile-ppid/perbekel.png"
|
||||
}
|
||||
]
|
||||
8
prisma/data/ppid/visi-misi-ppid/visimisiPPID.json
Normal file
8
prisma/data/ppid/visi-misi-ppid/visimisiPPID.json
Normal file
@@ -0,0 +1,8 @@
|
||||
[
|
||||
{
|
||||
"id": "1",
|
||||
"misi": "<ol><li>Meningkatkan pengelolaan dan pelayanan informasi yang berkualitas, benar dan bertanggung jawab.</li><li>Membangun dan mengembangkan sistem penyediaan dan layanan informasi.</li><li>Meningkatkan dan mengembangkan kompetensi dan kualitas SDM dalam bidang pelayanan informasi.</li><li>Mewujudkan keterbukaan informasi Pemerintah Desa Punggul dengan proses yang cepat, tepat, mudah dan sederhana.</li></ol>",
|
||||
"visi": "Memberikan pelayanan informasi yanng transparan dan akuntabel untuk memenuhi hak pemohon informasi sesuai dengan ketentuan peraturan perundang-undangan yang berlaku."
|
||||
|
||||
}
|
||||
]
|
||||
@@ -47,7 +47,195 @@ model AppMenuChild {
|
||||
appMenuId String?
|
||||
}
|
||||
|
||||
//========================================= MENU PPID ========================================= //
|
||||
// ========================================= VISI MISI PPID ========================================= //
|
||||
model VisiMisiPPID {
|
||||
id String @id @default(cuid())
|
||||
visi String @db.Text
|
||||
misi String @db.Text
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
deletedAt DateTime @default(now())
|
||||
isActive Boolean @default(true)
|
||||
}
|
||||
|
||||
// ========================================= DASAR HUKUM PPID ========================================= //
|
||||
model DasarHukumPPID {
|
||||
id String @id @default(cuid())
|
||||
judul String @db.Text
|
||||
content String @db.Text
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
deletedAt DateTime @default(now())
|
||||
isActive Boolean @default(true)
|
||||
}
|
||||
|
||||
// ========================================= PROFILE PPID ========================================= //
|
||||
model ProfilePPID {
|
||||
id String @id @default(cuid())
|
||||
name String @db.Text
|
||||
biodata String @db.Text
|
||||
riwayat String @db.Text
|
||||
pengalaman String @db.Text
|
||||
unggulan String @db.Text
|
||||
imageUrl String?
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
deletedAt DateTime @default(now())
|
||||
isActive Boolean @default(true)
|
||||
}
|
||||
|
||||
// ========================================= DAFTAR INFORMASI PUBLIK ========================================= //
|
||||
model DaftarInformasiPublik {
|
||||
id String @id @default(cuid())
|
||||
nomor Int @default(autoincrement())
|
||||
jenisInformasi String
|
||||
deskripsi String
|
||||
tanggal String
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
deletedAt DateTime @default(now())
|
||||
isActive Boolean @default(true)
|
||||
}
|
||||
|
||||
//=========================================PERMOHONAN INFORMASI PUBLIK========================= //
|
||||
model PermohonanInformasiPublik {
|
||||
id String @id @default(cuid())
|
||||
nomor Int @default(autoincrement())
|
||||
name String
|
||||
nik String
|
||||
notelp String
|
||||
alamat String
|
||||
email String
|
||||
jenisInformasiDiminta JenisInformasiDiminta? @relation(fields: [jenisInformasiDimintaId], references: [id])
|
||||
jenisInformasiDimintaId String?
|
||||
caraMemperolehInformasi CaraMemperolehInformasi? @relation(fields: [caraMemperolehInformasiId], references: [id])
|
||||
caraMemperolehInformasiId String?
|
||||
caraMemperolehSalinanInformasi CaraMemperolehSalinanInformasi? @relation(fields: [caraMemperolehSalinanInformasiId], references: [id])
|
||||
caraMemperolehSalinanInformasiId String?
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
deletedAt DateTime @default(now())
|
||||
isActive Boolean @default(true)
|
||||
}
|
||||
|
||||
model JenisInformasiDiminta {
|
||||
id String @id @default(cuid())
|
||||
name String @unique
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
deletedAt DateTime @default(now())
|
||||
isActive Boolean @default(true)
|
||||
PermohonanInformasiPublik PermohonanInformasiPublik[]
|
||||
}
|
||||
|
||||
model CaraMemperolehInformasi {
|
||||
id String @id @default(cuid())
|
||||
name String @unique
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
deletedAt DateTime @default(now())
|
||||
isActive Boolean @default(true)
|
||||
PermohonanInformasiPublik PermohonanInformasiPublik[]
|
||||
}
|
||||
|
||||
model CaraMemperolehSalinanInformasi {
|
||||
id String @id @default(cuid())
|
||||
name String @unique
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
deletedAt DateTime @default(now())
|
||||
isActive Boolean @default(true)
|
||||
PermohonanInformasiPublik PermohonanInformasiPublik[]
|
||||
}
|
||||
|
||||
//=========================================PERMOHONAN INFORMASI KEBERATAN PUBLIK========================= //
|
||||
model FormulirPermohonanKeberatan {
|
||||
id String @id @default(cuid())
|
||||
name String
|
||||
email String
|
||||
notelp String
|
||||
alasan String
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
deletedAt DateTime @default(now())
|
||||
isActive Boolean @default(true)
|
||||
}
|
||||
|
||||
// ========================================= IKM ========================================= //
|
||||
model IndeksKepuasanMasyarakat {
|
||||
id Int @id @default(autoincrement())
|
||||
label String
|
||||
kepuasan String
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
deletedAt DateTime @default(now())
|
||||
isActive Boolean @default(true)
|
||||
}
|
||||
|
||||
model GrafikBerdasarkanJenisKelamin {
|
||||
id String @id @default(cuid())
|
||||
perempuan String
|
||||
laki String
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
deletedAt DateTime @default(now())
|
||||
isActive Boolean @default(true)
|
||||
}
|
||||
|
||||
model GrafikBerdasarkanResponden {
|
||||
id String @id @default(cuid())
|
||||
sangatbaik String
|
||||
baik String
|
||||
kurangbaik String
|
||||
tidakbaik String
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
deletedAt DateTime @default(now())
|
||||
isActive Boolean @default(true)
|
||||
}
|
||||
|
||||
model GrafikBerdasarkanUmur {
|
||||
id String @id @default(cuid())
|
||||
remaja String
|
||||
dewasa String
|
||||
orangtua String
|
||||
lansia String
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
deletedAt DateTime @default(now())
|
||||
isActive Boolean @default(true)
|
||||
}
|
||||
|
||||
// ========================================= MENU DESA ========================================= //
|
||||
// ========================================= PROFILE DESA ========================================= //
|
||||
model ProfileDesa {
|
||||
id String @id @default(cuid())
|
||||
sejarah String @db.Text
|
||||
visi String @db.Text
|
||||
misi String @db.Text
|
||||
lambang String @db.Text
|
||||
maskot String @db.Text
|
||||
ProfilPerbekel ProfilPerbekel? @relation(fields: [profilPerbekelId], references: [id])
|
||||
profilPerbekelId String?
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
deletedAt DateTime @default(now())
|
||||
isActive Boolean @default(true)
|
||||
}
|
||||
|
||||
model ProfilPerbekel {
|
||||
id String @id @default(cuid())
|
||||
biodata String @db.Text
|
||||
pengalaman String @db.Text
|
||||
pengalamanOrganisasi String @db.Text
|
||||
programUnggulan String @db.Text
|
||||
ProfileDesa ProfileDesa[]
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
deletedAt DateTime @default(now())
|
||||
isActive Boolean @default(true)
|
||||
}
|
||||
// ========================================= BERITA ========================================= //
|
||||
model Berita {
|
||||
id String @id @default(cuid())
|
||||
@@ -323,3 +511,73 @@ model GrafikKepuasan {
|
||||
deletedAt DateTime @default(now())
|
||||
isActive Boolean @default(true)
|
||||
}
|
||||
|
||||
// ========================================= ARTIKEL KESEHATAN ========================================= //
|
||||
model ArtikelKesehatan {
|
||||
id Int @id @default(autoincrement())
|
||||
title String
|
||||
content String
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
deletedAt DateTime @default(now())
|
||||
isActive Boolean @default(true)
|
||||
}
|
||||
|
||||
model Introduction {
|
||||
id Int @id @default(autoincrement())
|
||||
content String
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
deletedAt DateTime @default(now())
|
||||
isActive Boolean @default(true)
|
||||
}
|
||||
|
||||
model Symptom {
|
||||
id Int @id @default(autoincrement())
|
||||
title String
|
||||
content String
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
deletedAt DateTime @default(now())
|
||||
isActive Boolean @default(true)
|
||||
}
|
||||
|
||||
model Prevention {
|
||||
id Int @id @default(autoincrement())
|
||||
title String
|
||||
content String
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
deletedAt DateTime @default(now())
|
||||
isActive Boolean @default(true)
|
||||
}
|
||||
|
||||
model FirstAid {
|
||||
id Int @id @default(autoincrement())
|
||||
title String
|
||||
content String
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
deletedAt DateTime @default(now())
|
||||
isActive Boolean @default(true)
|
||||
}
|
||||
|
||||
model MythVsFact {
|
||||
id Int @id @default(autoincrement())
|
||||
title String
|
||||
mitos String
|
||||
fakta String
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
deletedAt DateTime @default(now())
|
||||
isActive Boolean @default(true)
|
||||
}
|
||||
|
||||
model DoctorSign {
|
||||
id Int @id @default(autoincrement())
|
||||
content String
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
deletedAt DateTime @default(now())
|
||||
isActive Boolean @default(true)
|
||||
}
|
||||
|
||||
170
prisma/seed.ts
170
prisma/seed.ts
@@ -1,8 +1,16 @@
|
||||
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 katagoryBerita from './data/katagory-berita.json'
|
||||
import categoryPengumuman from './data/category-pengumuman.json'
|
||||
import prisma from '@/lib/prisma';
|
||||
import profilePPID from './data/ppid/profile-ppid/profilePPid.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'
|
||||
(async () => {
|
||||
for (const l of layanan) {
|
||||
await prisma.layanan.upsert({
|
||||
@@ -67,6 +75,162 @@ import prisma from '@/lib/prisma';
|
||||
}
|
||||
|
||||
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 ...")
|
||||
|
||||
for (const c of profilePPID) {
|
||||
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: c.imageUrl
|
||||
},
|
||||
create: {
|
||||
id: c.id,
|
||||
name: c.name,
|
||||
biodata: c.biodata,
|
||||
riwayat: c.riwayat,
|
||||
pengalaman: c.pengalaman,
|
||||
unggulan: c.unggulan,
|
||||
imageUrl: c.imageUrl
|
||||
}
|
||||
})
|
||||
}
|
||||
console.log("profile PPID 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 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 ...")
|
||||
|
||||
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 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()
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 275 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 275 KiB |
@@ -87,4 +87,4 @@ const stateDashboardBerita = proxy({
|
||||
berita,
|
||||
});
|
||||
|
||||
export default stateDashboardBerita;
|
||||
export default stateDashboardBerita;
|
||||
@@ -0,0 +1,339 @@
|
||||
import ApiFetch from "@/lib/api-fetch";
|
||||
import { Prisma } from "@prisma/client";
|
||||
import { toast } from "react-toastify";
|
||||
import { proxy } from "valtio";
|
||||
import { z } from "zod";
|
||||
|
||||
/* Introduction */
|
||||
const templateIntroduction = z.object({
|
||||
content: z.string().min(3, "Content minimal 3 karakter"),
|
||||
})
|
||||
|
||||
type Introduction = Prisma.IntroductionGetPayload<{
|
||||
select: {
|
||||
content: true;
|
||||
};
|
||||
}>;
|
||||
|
||||
const introduction = proxy({
|
||||
create: {
|
||||
form: {} as Introduction,
|
||||
loading: false,
|
||||
async create() {
|
||||
const cek = templateIntroduction.safeParse(introduction.create.form);
|
||||
if (!cek.success) {
|
||||
const err = `[${cek.error.issues
|
||||
.map((v) => `${v.path.join(".")}`)
|
||||
.join("\n")}] required`;
|
||||
return toast.error(err);
|
||||
}
|
||||
try {
|
||||
introduction.create.loading = true;
|
||||
const res = await ApiFetch.api.kesehatan.introduction["create"].post(introduction.create.form);
|
||||
if (res.status === 200) {
|
||||
introduction.findMany.load();
|
||||
return toast.success("success create");
|
||||
}
|
||||
return toast.error("failed create");
|
||||
} catch (error) {
|
||||
console.log((error as Error).message);
|
||||
} finally {
|
||||
introduction.create.loading = false;
|
||||
}
|
||||
},
|
||||
},
|
||||
findMany: {
|
||||
data: null as
|
||||
| Prisma.IntroductionGetPayload<{ omit: { isActive: true } }>[]
|
||||
| null,
|
||||
async load() {
|
||||
const res = await ApiFetch.api.kesehatan.introduction["find-many"].get();
|
||||
if (res.status === 200) {
|
||||
introduction.findMany.data = res.data?.data ?? [];
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
/* ======================================================================= */
|
||||
|
||||
/* symptom */
|
||||
const templateSymptom = z.object({
|
||||
title: z.string().min(3, "Title minimal 3 karakter"),
|
||||
content: z.string().min(3, "Content minimal 3 karakter"),
|
||||
})
|
||||
|
||||
type Symptom = Prisma.SymptomGetPayload<{
|
||||
select: {
|
||||
title: true;
|
||||
content: true;
|
||||
};
|
||||
}>;
|
||||
|
||||
const symptom = proxy({
|
||||
create: {
|
||||
form: {} as Symptom,
|
||||
loading: false,
|
||||
async create() {
|
||||
const cek = templateSymptom.safeParse(symptom.create.form);
|
||||
if (!cek.success) {
|
||||
const err = `[${cek.error.issues
|
||||
.map((v) => `${v.path.join(".")}`)
|
||||
.join("\n")}] required`;
|
||||
return toast.error(err);
|
||||
}
|
||||
try {
|
||||
symptom.create.loading = true;
|
||||
const res = await ApiFetch.api.kesehatan.symptom["create"].post(symptom.create.form);
|
||||
if (res.status === 200) {
|
||||
symptom.findMany.load();
|
||||
return toast.success("success create");
|
||||
}
|
||||
return toast.error("failed create");
|
||||
} catch (error) {
|
||||
console.log((error as Error).message);
|
||||
} finally {
|
||||
symptom.create.loading = false;
|
||||
}
|
||||
},
|
||||
},
|
||||
findMany: {
|
||||
data: null as
|
||||
| Prisma.SymptomGetPayload<{ omit: { isActive: true } }>[]
|
||||
| null,
|
||||
async load() {
|
||||
const res = await ApiFetch.api.kesehatan.symptom["find-many"].get();
|
||||
if (res.status === 200) {
|
||||
symptom.findMany.data = res.data?.data ?? [];
|
||||
}
|
||||
},
|
||||
},
|
||||
});
|
||||
/* ======================================================================= */
|
||||
|
||||
/* Prevention */
|
||||
const templatePrevention = z.object({
|
||||
title: z.string().min(3, "Title minimal 3 karakter"),
|
||||
content: z.string().min(3, "Content minimal 3 karakter"),
|
||||
})
|
||||
|
||||
type Prevention = Prisma.PreventionGetPayload<{
|
||||
select: {
|
||||
title: true;
|
||||
content: true;
|
||||
};
|
||||
}>;
|
||||
|
||||
const prevention = proxy({
|
||||
create: {
|
||||
form: {} as Prevention,
|
||||
loading: false,
|
||||
async create() {
|
||||
const cek = templatePrevention.safeParse(prevention.create.form);
|
||||
if (!cek.success) {
|
||||
const err = `[${cek.error.issues
|
||||
.map((v) => `${v.path.join(".")}`)
|
||||
.join("\n")}] required`;
|
||||
return toast.error(err);
|
||||
}
|
||||
try {
|
||||
prevention.create.loading = true;
|
||||
const res = await ApiFetch.api.kesehatan.prevention["create"].post(prevention.create.form);
|
||||
if (res.status === 200) {
|
||||
prevention.findMany.load();
|
||||
return toast.success("success create");
|
||||
}
|
||||
return toast.error("failed create");
|
||||
} catch (error) {
|
||||
console.log((error as Error).message);
|
||||
} finally {
|
||||
prevention.create.loading = false;
|
||||
}
|
||||
},
|
||||
},
|
||||
findMany: {
|
||||
data: null as
|
||||
| Prisma.PreventionGetPayload<{ omit: { isActive: true } }>[]
|
||||
| null,
|
||||
async load() {
|
||||
const res = await ApiFetch.api.kesehatan.prevention["find-many"].get();
|
||||
if (res.status === 200) {
|
||||
prevention.findMany.data = res.data?.data ?? [];
|
||||
}
|
||||
},
|
||||
},
|
||||
});
|
||||
/* ======================================================================= */
|
||||
|
||||
/* First Aid */
|
||||
const templateFirstAid = z.object({
|
||||
title: z.string().min(3, "Title minimal 3 karakter"),
|
||||
content: z.string().min(3, "Content minimal 3 karakter"),
|
||||
})
|
||||
|
||||
type FirstAid = Prisma.FirstAidGetPayload<{
|
||||
select: {
|
||||
title: true;
|
||||
content: true;
|
||||
};
|
||||
}>;
|
||||
|
||||
const firstAid = proxy({
|
||||
create: {
|
||||
form: {} as FirstAid,
|
||||
loading: false,
|
||||
async create() {
|
||||
const cek = templateFirstAid.safeParse(firstAid.create.form);
|
||||
if (!cek.success) {
|
||||
const err = `[${cek.error.issues
|
||||
.map((v) => `${v.path.join(".")}`)
|
||||
.join("\n")}] required`;
|
||||
return toast.error(err);
|
||||
}
|
||||
try {
|
||||
firstAid.create.loading = true;
|
||||
const res = await ApiFetch.api.kesehatan.firstaid["create"].post(firstAid.create.form);
|
||||
if (res.status === 200) {
|
||||
firstAid.findMany.load();
|
||||
return toast.success("success create");
|
||||
}
|
||||
return toast.error("failed create");
|
||||
} catch (error) {
|
||||
console.log((error as Error).message);
|
||||
} finally {
|
||||
firstAid.create.loading = false;
|
||||
}
|
||||
},
|
||||
},
|
||||
findMany: {
|
||||
data: null as
|
||||
| Prisma.FirstAidGetPayload<{ omit: { isActive: true } }>[]
|
||||
| null,
|
||||
async load() {
|
||||
const res = await ApiFetch.api.kesehatan.firstaid["find-many"].get();
|
||||
if (res.status === 200) {
|
||||
firstAid.findMany.data = res.data?.data ?? [];
|
||||
}
|
||||
},
|
||||
},
|
||||
})
|
||||
/* ======================================================================= */
|
||||
|
||||
/* Myth vs Fact */
|
||||
const templateMythFact = z.object({
|
||||
title: z.string().min(3, "Title minimal 3 karakter"),
|
||||
mitos: z.string().min(3, "Mitos minimal 3 karakter"),
|
||||
fakta: z.string().min(3, "Fakta minimal 3 karakter"),
|
||||
})
|
||||
|
||||
type MythFact = Prisma.MythVsFactGetPayload<{
|
||||
select: {
|
||||
title: true;
|
||||
mitos: true;
|
||||
fakta: true;
|
||||
};
|
||||
}>;
|
||||
|
||||
const mythFact = proxy({
|
||||
create: {
|
||||
form: {} as MythFact,
|
||||
loading: false,
|
||||
async create() {
|
||||
const cek = templateMythFact.safeParse(mythFact.create.form);
|
||||
if (!cek.success) {
|
||||
const err = `[${cek.error.issues
|
||||
.map((v) => `${v.path.join(".")}`)
|
||||
.join("\n")}] required`;
|
||||
return toast.error(err);
|
||||
}
|
||||
try {
|
||||
mythFact.create.loading = true;
|
||||
const res = await ApiFetch.api.kesehatan.mythvsfact["create"].post(mythFact.create.form);
|
||||
if (res.status === 200) {
|
||||
mythFact.findMany.load();
|
||||
return toast.success("success create");
|
||||
}
|
||||
return toast.error("failed create");
|
||||
} catch (error) {
|
||||
console.log((error as Error).message);
|
||||
} finally {
|
||||
mythFact.create.loading = false;
|
||||
}
|
||||
},
|
||||
},
|
||||
findMany: {
|
||||
data: null as
|
||||
| Prisma.MythVsFactGetPayload<{ omit: { isActive: true } }>[]
|
||||
| null,
|
||||
async load() {
|
||||
const res = await ApiFetch.api.kesehatan.mythvsfact["find-many"].get();
|
||||
if (res.status === 200) {
|
||||
mythFact.findMany.data = res.data?.data ?? [];
|
||||
}
|
||||
},
|
||||
},
|
||||
})
|
||||
/* ======================================================================= */
|
||||
|
||||
/* Doctor Sign */
|
||||
const templateDoctorSign = z.object({
|
||||
content: z.string().min(3, "Content minimal 3 karakter"),
|
||||
})
|
||||
|
||||
type DoctorSign = Prisma.DoctorSignGetPayload<{
|
||||
select: {
|
||||
content: true
|
||||
}
|
||||
}>
|
||||
|
||||
const doctorSign = proxy({
|
||||
create: {
|
||||
form: {} as DoctorSign,
|
||||
loading: false,
|
||||
async create() {
|
||||
const cek = templateDoctorSign.safeParse(doctorSign.create.form);
|
||||
if (!cek.success) {
|
||||
const err = `[${cek.error.issues
|
||||
.map((v) => `${v.path.join(".")}`)
|
||||
.join("\n")}] required`;
|
||||
return toast.error(err);
|
||||
}
|
||||
try {
|
||||
doctorSign.create.loading = true;
|
||||
const res = await ApiFetch.api.kesehatan.doctor_sign["create"].post(doctorSign.create.form);
|
||||
if (res.status === 200) {
|
||||
doctorSign.findMany.load();
|
||||
return toast.success("success create");
|
||||
}
|
||||
return toast.error("failed create");
|
||||
} catch (error) {
|
||||
console.log((error as Error).message);
|
||||
} finally {
|
||||
doctorSign.create.loading = false;
|
||||
}
|
||||
},
|
||||
},
|
||||
findMany: {
|
||||
data: null as
|
||||
| Prisma.DoctorSignGetPayload<{ omit: { isActive: true } }>[]
|
||||
| null,
|
||||
async load() {
|
||||
const res = await ApiFetch.api.kesehatan.doctor_sign["find-many"].get();
|
||||
if (res.status === 200) {
|
||||
doctorSign.findMany.data = res.data?.data ?? [];
|
||||
}
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
/* ======================================================================= */
|
||||
|
||||
const stateArtikelKesehatan = proxy({
|
||||
introduction,
|
||||
symptom,
|
||||
prevention,
|
||||
firstAid,
|
||||
mythFact,
|
||||
doctorSign
|
||||
})
|
||||
|
||||
export default stateArtikelKesehatan
|
||||
@@ -0,0 +1,65 @@
|
||||
import ApiFetch from "@/lib/api-fetch";
|
||||
import { Prisma } from "@prisma/client";
|
||||
import { toast } from "react-toastify";
|
||||
import { proxy } from "valtio";
|
||||
import { z } from "zod";
|
||||
|
||||
const templateDaftarInformasi = z.object({
|
||||
jenisInformasi: z.string().min(3, "Jenis Informasi minimal 3 karakter"),
|
||||
deskripsi: z.string().min(3, "Deskripsi minimal 3 karakter"),
|
||||
tanggal: z.string().min(3, "Tanggal minimal 3 karakter"),
|
||||
})
|
||||
|
||||
type DaftarInformasi = Prisma.DaftarInformasiPublikGetPayload<{
|
||||
select: {
|
||||
jenisInformasi: true;
|
||||
deskripsi: true;
|
||||
tanggal: true;
|
||||
};
|
||||
}>;
|
||||
|
||||
const daftarInformasi = proxy({
|
||||
create: {
|
||||
form: {} as DaftarInformasi,
|
||||
loading: false,
|
||||
async create() {
|
||||
const cek = templateDaftarInformasi.safeParse(daftarInformasi.create.form);
|
||||
if (!cek.success) {
|
||||
const err = `[${cek.error.issues
|
||||
.map((v) => `${v.path.join(".")}`)
|
||||
.join("\n")}] required`;
|
||||
return toast.error(err);
|
||||
}
|
||||
try {
|
||||
daftarInformasi.create.loading = true;
|
||||
const res = await ApiFetch.api.ppid.daftarinformasipublik["create"].post(daftarInformasi.create.form);
|
||||
if (res.status === 200) {
|
||||
daftarInformasi.findMany.load();
|
||||
return toast.success("success create");
|
||||
}
|
||||
return toast.error("failed create");
|
||||
} catch (error) {
|
||||
console.log((error as Error).message);
|
||||
} finally {
|
||||
daftarInformasi.create.loading = false;
|
||||
}
|
||||
},
|
||||
},
|
||||
findMany: {
|
||||
data: null as
|
||||
| Prisma.DaftarInformasiPublikGetPayload<{ omit: { isActive: true } }>[]
|
||||
| null,
|
||||
async load() {
|
||||
const res = await ApiFetch.api.ppid.daftarinformasipublik["find-many"].get();
|
||||
if (res.status === 200) {
|
||||
daftarInformasi.findMany.data = res.data?.data ?? [];
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
const stateDaftarInformasiPublik = proxy({
|
||||
daftarInformasi
|
||||
})
|
||||
|
||||
export default stateDaftarInformasiPublik;
|
||||
@@ -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;
|
||||
@@ -0,0 +1,77 @@
|
||||
import ApiFetch from "@/lib/api-fetch";
|
||||
import { Prisma } from "@prisma/client";
|
||||
import { toast } from "react-toastify";
|
||||
import { proxy } from "valtio";
|
||||
import { z } from "zod";
|
||||
|
||||
const templateGrafikJenisKelamin = z.object({
|
||||
laki: z.string().min(2, "Data laki-laki harus diisi"),
|
||||
perempuan: z.string().min(2, "Data perempuan harus diisi"),
|
||||
});
|
||||
|
||||
type GrafikJenisKelamin = Prisma.GrafikBerdasarkanJenisKelaminGetPayload<{
|
||||
select: {
|
||||
laki: true;
|
||||
perempuan: true;
|
||||
};
|
||||
}>;
|
||||
|
||||
const defaultForm: GrafikJenisKelamin = {
|
||||
laki: "",
|
||||
perempuan: "",
|
||||
};
|
||||
|
||||
const grafikBerdasarkanJenisKelamin = proxy({
|
||||
create: {
|
||||
form: defaultForm,
|
||||
loading: false,
|
||||
async create() {
|
||||
const cek = templateGrafikJenisKelamin.safeParse(
|
||||
grafikBerdasarkanJenisKelamin.create.form
|
||||
);
|
||||
if (!cek.success) {
|
||||
const err = `[${cek.error.issues
|
||||
.map((v) => `${v.path.join(".")}`)
|
||||
.join("\n")}] required`;
|
||||
return toast.error(err);
|
||||
}
|
||||
try {
|
||||
grafikBerdasarkanJenisKelamin.create.loading = true;
|
||||
const res = await ApiFetch.api.ppid.grafikberdasarkanjeniskelamin[
|
||||
"create"
|
||||
].post(grafikBerdasarkanJenisKelamin.create.form);
|
||||
if (res.status === 200) {
|
||||
grafikBerdasarkanJenisKelamin.create.form = defaultForm;
|
||||
grafikBerdasarkanJenisKelamin.findMany.load();
|
||||
return toast.success("success create");
|
||||
}
|
||||
return toast.error("failed create");
|
||||
} catch (error) {
|
||||
console.log((error as Error).message);
|
||||
} finally {
|
||||
grafikBerdasarkanJenisKelamin.create.loading = false;
|
||||
}
|
||||
},
|
||||
},
|
||||
findMany: {
|
||||
data: null as
|
||||
| Prisma.GrafikBerdasarkanJenisKelaminGetPayload<{
|
||||
omit: { isActive: true };
|
||||
}>[]
|
||||
| null,
|
||||
loading: false,
|
||||
async load() {
|
||||
const res = await ApiFetch.api.ppid.grafikberdasarkanjeniskelamin[
|
||||
"find-many"
|
||||
].get();
|
||||
if (res.status === 200) {
|
||||
grafikBerdasarkanJenisKelamin.findMany.data = res.data?.data ?? [];
|
||||
}
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const stateGrafikBerdasarkanJenisKelamin = proxy({
|
||||
grafikBerdasarkanJenisKelamin,
|
||||
});
|
||||
export default stateGrafikBerdasarkanJenisKelamin;
|
||||
@@ -0,0 +1,84 @@
|
||||
import ApiFetch from "@/lib/api-fetch";
|
||||
import { Prisma } from "@prisma/client";
|
||||
import { toast } from "react-toastify";
|
||||
import { proxy } from "valtio";
|
||||
import { z } from "zod";
|
||||
|
||||
const templateGrafikResponden = z.object({
|
||||
sangatbaik: z.string().min(1, "Data sangat baik harus diisi"),
|
||||
baik: z.string().min(1, "Data baik harus diisi"),
|
||||
kurangbaik: z.string().min(1, "Data kurang baik harus diisi"),
|
||||
tidakbaik: z.string().min(1, "Data tidak baik harus diisi"),
|
||||
});
|
||||
|
||||
type GrafikResponden = Prisma.GrafikBerdasarkanRespondenGetPayload<{
|
||||
select: {
|
||||
sangatbaik: true;
|
||||
baik: true;
|
||||
kurangbaik: true;
|
||||
tidakbaik: true;
|
||||
};
|
||||
}>;
|
||||
|
||||
const defaultForm: GrafikResponden = {
|
||||
sangatbaik: "",
|
||||
baik: "",
|
||||
kurangbaik: "",
|
||||
tidakbaik: "",
|
||||
};
|
||||
|
||||
const grafikBerdasarkanResponden = proxy({
|
||||
create: {
|
||||
form: defaultForm,
|
||||
loading: false,
|
||||
async create() {
|
||||
const cek = templateGrafikResponden.safeParse(
|
||||
grafikBerdasarkanResponden.create.form
|
||||
);
|
||||
if (!cek.success) {
|
||||
const err = `[${cek.error.issues
|
||||
.map((v) => `${v.path.join(".")}`)
|
||||
.join("\n")}] required`;
|
||||
return toast.error(err);
|
||||
}
|
||||
try {
|
||||
grafikBerdasarkanResponden.create.loading = true;
|
||||
const res = await ApiFetch.api.ppid.grafikberdasarkanresponden[
|
||||
"create"
|
||||
].post(grafikBerdasarkanResponden.create.form);
|
||||
if (res.status === 200) {
|
||||
grafikBerdasarkanResponden.create.form = defaultForm;
|
||||
grafikBerdasarkanResponden.findMany.load();
|
||||
return toast.success("success create");
|
||||
}
|
||||
return toast.error("failed create");
|
||||
} catch (error) {
|
||||
console.log((error as Error).message);
|
||||
} finally {
|
||||
grafikBerdasarkanResponden.create.loading = false;
|
||||
}
|
||||
},
|
||||
},
|
||||
findMany: {
|
||||
data: null as
|
||||
| Prisma.GrafikBerdasarkanRespondenGetPayload<{
|
||||
omit: { isActive: true };
|
||||
}>[]
|
||||
| null,
|
||||
loading: false,
|
||||
async load() {
|
||||
const res = await ApiFetch.api.ppid.grafikberdasarkanresponden[
|
||||
"find-many"
|
||||
].get();
|
||||
if (res.status === 200) {
|
||||
grafikBerdasarkanResponden.findMany.data = res.data?.data ?? [];
|
||||
}
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const stateGrafikResponden = proxy({
|
||||
grafikBerdasarkanResponden,
|
||||
});
|
||||
|
||||
export default stateGrafikResponden;
|
||||
@@ -0,0 +1,84 @@
|
||||
import ApiFetch from "@/lib/api-fetch";
|
||||
import { Prisma } from "@prisma/client";
|
||||
import { toast } from "react-toastify";
|
||||
import { proxy } from "valtio";
|
||||
import { z } from "zod";
|
||||
|
||||
const templateGrafikUmur = z.object({
|
||||
remaja: z.string().min(2, "Data remaja harus diisi"),
|
||||
dewasa: z.string().min(2, "Data dewasa harus diisi"),
|
||||
orangtua: z.string().min(2, "Data orangtua harus diisi"),
|
||||
lansia: z.string().min(2, "Data lansia harus diisi"),
|
||||
});
|
||||
|
||||
type GrafikUmur = Prisma.GrafikBerdasarkanUmurGetPayload<{
|
||||
select: {
|
||||
remaja: true;
|
||||
dewasa: true;
|
||||
orangtua: true;
|
||||
lansia: true;
|
||||
};
|
||||
}>;
|
||||
|
||||
const defaultForm: GrafikUmur = {
|
||||
remaja: "",
|
||||
dewasa: "",
|
||||
orangtua: "",
|
||||
lansia: "",
|
||||
};
|
||||
|
||||
const grafikBerdasarkanUmur = proxy({
|
||||
create: {
|
||||
form: defaultForm,
|
||||
loading: false,
|
||||
async create() {
|
||||
const cek = templateGrafikUmur.safeParse(
|
||||
grafikBerdasarkanUmur.create.form
|
||||
);
|
||||
if (!cek.success) {
|
||||
const err = `[${cek.error.issues
|
||||
.map((v) => `${v.path.join(".")}`)
|
||||
.join("\n")}] required`;
|
||||
return toast.error(err);
|
||||
}
|
||||
try {
|
||||
grafikBerdasarkanUmur.create.loading = true;
|
||||
const res = await ApiFetch.api.ppid.grafikberdasarkanumur[
|
||||
"create"
|
||||
].post(grafikBerdasarkanUmur.create.form);
|
||||
if (res.status === 200) {
|
||||
grafikBerdasarkanUmur.create.form = defaultForm;
|
||||
grafikBerdasarkanUmur.findMany.load();
|
||||
return toast.success("success create");
|
||||
}
|
||||
return toast.error("failed create");
|
||||
} catch (error) {
|
||||
console.log((error as Error).message);
|
||||
} finally {
|
||||
grafikBerdasarkanUmur.create.loading = false;
|
||||
}
|
||||
},
|
||||
},
|
||||
findMany: {
|
||||
data: null as
|
||||
| Prisma.GrafikBerdasarkanUmurGetPayload<{
|
||||
omit: { isActive: true };
|
||||
}>[]
|
||||
| null,
|
||||
loading: false,
|
||||
async load() {
|
||||
const res = await ApiFetch.api.ppid.grafikberdasarkanumur[
|
||||
"find-many"
|
||||
].get();
|
||||
if (res.status === 200) {
|
||||
grafikBerdasarkanUmur.findMany.data = res.data?.data ?? [];
|
||||
}
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
const stateGrafikBerdasarkanUmur = proxy({
|
||||
grafikBerdasarkanUmur,
|
||||
})
|
||||
|
||||
export default stateGrafikBerdasarkanUmur;
|
||||
@@ -0,0 +1,76 @@
|
||||
import ApiFetch from "@/lib/api-fetch";
|
||||
import { Prisma } from "@prisma/client";
|
||||
import { toast } from "react-toastify";
|
||||
import { proxy } from "valtio";
|
||||
import { z } from "zod";
|
||||
|
||||
const templateGrafikHasilKepuasanMasyarakat = z.object({
|
||||
label: z.string().min(2, "Label harus diisi"),
|
||||
kepuasan: z.string().min(2, "Kepuasan harus diisi"),
|
||||
});
|
||||
|
||||
type GrafikHasilKepuasanMasyarakat = Prisma.IndeksKepuasanMasyarakatGetPayload<{
|
||||
select: {
|
||||
label: true;
|
||||
kepuasan: true;
|
||||
};
|
||||
}>;
|
||||
|
||||
const defaultForm: GrafikHasilKepuasanMasyarakat = {
|
||||
label: "",
|
||||
kepuasan: "",
|
||||
};
|
||||
|
||||
const grafikHasilKepuasanMasyarakat = proxy({
|
||||
create: {
|
||||
form: defaultForm,
|
||||
loading: false,
|
||||
async create() {
|
||||
const cek = templateGrafikHasilKepuasanMasyarakat.safeParse(
|
||||
grafikHasilKepuasanMasyarakat.create.form
|
||||
);
|
||||
if (!cek.success) {
|
||||
const err = `[${cek.error.issues
|
||||
.map((v) => `${v.path.join(".")}`)
|
||||
.join("\n")}] required`;
|
||||
return toast.error(err);
|
||||
}
|
||||
try {
|
||||
grafikHasilKepuasanMasyarakat.create.loading = true;
|
||||
const res = await ApiFetch.api.ppid.grafikhasilkepuasamanmasyarakat["create"].post(
|
||||
grafikHasilKepuasanMasyarakat.create.form
|
||||
);
|
||||
if (res.status === 200) {
|
||||
grafikHasilKepuasanMasyarakat.create.form = {
|
||||
label: "",
|
||||
kepuasan: ""
|
||||
};
|
||||
grafikHasilKepuasanMasyarakat.findMany.load();
|
||||
return toast.success("success create");
|
||||
}
|
||||
return toast.error("failed create");
|
||||
} catch (error) {
|
||||
console.log((error as Error).message);
|
||||
} finally {
|
||||
grafikHasilKepuasanMasyarakat.create.loading = false;
|
||||
}
|
||||
},
|
||||
},
|
||||
findMany: {
|
||||
data: null as
|
||||
| Prisma.IndeksKepuasanMasyarakatGetPayload<{ omit: { isActive: true } }>[]
|
||||
| null,
|
||||
async load() {
|
||||
const res = await ApiFetch.api.ppid.grafikhasilkepuasamanmasyarakat["find-many"].get();
|
||||
if (res.status === 200) {
|
||||
grafikHasilKepuasanMasyarakat.findMany.data = res.data?.data ?? [];
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
const stateGrafikHasilKepuasanMasyarakat = proxy({
|
||||
grafikHasilKepuasanMasyarakat,
|
||||
});
|
||||
|
||||
export default stateGrafikHasilKepuasanMasyarakat;
|
||||
@@ -0,0 +1,125 @@
|
||||
import ApiFetch from "@/lib/api-fetch";
|
||||
import { Prisma } from "@prisma/client";
|
||||
import { toast } from "react-toastify";
|
||||
import { proxy } from "valtio";
|
||||
import { z } from "zod";
|
||||
|
||||
const templateForm = z.object({
|
||||
name: z.string().min(3, "Nama minimal 3 karakter"),
|
||||
nik: z.string().min(3, "NIK minimal 3 karakter"),
|
||||
notelp: z.string().min(3, "Nomor Telepon minimal 3 karakter"),
|
||||
alamat: z.string().min(3, "Alamat minimal 3 karakter"),
|
||||
email: z.string().min(3, "Email minimal 3 karakter"),
|
||||
jenisInformasiDimintaId: z.string().nonempty(),
|
||||
caraMemperolehInformasiId: z.string().nonempty(),
|
||||
caraMemperolehSalinanInformasiId: z.string().nonempty(),
|
||||
})
|
||||
|
||||
const jenisInformasiDiminta = proxy({
|
||||
findMany: {
|
||||
data: null as
|
||||
| null
|
||||
| Prisma.JenisInformasiDimintaGetPayload<{ omit: { isActive: true } }>[],
|
||||
async load(){
|
||||
const res = await ApiFetch.api.ppid.permohonaninformasipublik.jenisInformasi["find-many"].get();
|
||||
if (res.status === 200) {
|
||||
jenisInformasiDiminta.findMany.data = res.data?.data ?? [];
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const caraMemperolehInformasi = proxy({
|
||||
findMany: {
|
||||
data: null as
|
||||
| null
|
||||
| Prisma.CaraMemperolehInformasiGetPayload<{ omit: { isActive: true } }>[],
|
||||
async load() {
|
||||
const res = await ApiFetch.api.ppid.permohonaninformasipublik.memperolehInformasi["find-many"].get();
|
||||
if (res.status === 200) {
|
||||
caraMemperolehInformasi.findMany.data = res.data?.data ?? [];
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const caraMemperolehSalinanInformasi = proxy({
|
||||
findMany: {
|
||||
data: null as
|
||||
| null
|
||||
| Prisma.CaraMemperolehSalinanInformasiGetPayload<{ omit: { isActive: true } }>[],
|
||||
async load() {
|
||||
const res = await ApiFetch.api.ppid.permohonaninformasipublik.salinanInformasi["find-many"].get();
|
||||
if (res.status === 200) {
|
||||
caraMemperolehSalinanInformasi.findMany.data = res.data?.data ?? [];
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
console.log(caraMemperolehSalinanInformasi)
|
||||
|
||||
type PermohonanInformasiPublikForm = Prisma.PermohonanInformasiPublikGetPayload<{
|
||||
select: {
|
||||
name: true;
|
||||
nik: true;
|
||||
notelp: true;
|
||||
alamat: true;
|
||||
email: true;
|
||||
jenisInformasiDimintaId: true;
|
||||
caraMemperolehInformasiId: true;
|
||||
caraMemperolehSalinanInformasiId: true;
|
||||
};
|
||||
}>;
|
||||
|
||||
const statepermohonanInformasiPublik = proxy({
|
||||
create: {
|
||||
form: {} as PermohonanInformasiPublikForm,
|
||||
loading: false,
|
||||
async create(){
|
||||
const cek = templateForm.safeParse(statepermohonanInformasiPublik.create.form);
|
||||
if(!cek.success) {
|
||||
const err = `[${cek.error.issues
|
||||
.map((v) => `${v.path.join(".")}`)
|
||||
.join("\n")}] required`;
|
||||
return toast.error(err);
|
||||
}
|
||||
try {
|
||||
statepermohonanInformasiPublik.create.loading = true;
|
||||
const res = await ApiFetch.api.ppid.permohonaninformasipublik["create"].post(statepermohonanInformasiPublik.create.form);
|
||||
if (res.status === 200) {
|
||||
statepermohonanInformasiPublik.findMany.load();
|
||||
return toast.success("success create");
|
||||
}
|
||||
return toast.error("failed create");
|
||||
} catch (error) {
|
||||
console.log((error as Error).message);
|
||||
} finally {
|
||||
statepermohonanInformasiPublik.create.loading = false;
|
||||
}
|
||||
}
|
||||
},
|
||||
findMany: {
|
||||
data: null as
|
||||
| Prisma.PermohonanInformasiPublikGetPayload<{ include: {
|
||||
caraMemperolehSalinanInformasi: true,
|
||||
jenisInformasiDiminta: true,
|
||||
caraMemperolehInformasi: true,
|
||||
} }>[]
|
||||
| null,
|
||||
async load() {
|
||||
const res = await ApiFetch.api.ppid.permohonaninformasipublik["find-many"].get();
|
||||
if (res.status === 200) {
|
||||
statepermohonanInformasiPublik.findMany.data = res.data?.data ?? [];
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const statepermohonanInformasiPublikForm = proxy({
|
||||
statepermohonanInformasiPublik,
|
||||
jenisInformasiDiminta,
|
||||
caraMemperolehInformasi,
|
||||
caraMemperolehSalinanInformasi,
|
||||
})
|
||||
|
||||
export default statepermohonanInformasiPublikForm;
|
||||
@@ -0,0 +1,64 @@
|
||||
import ApiFetch from "@/lib/api-fetch";
|
||||
import { Prisma } from "@prisma/client";
|
||||
import { toast } from "react-toastify";
|
||||
import { proxy } from "valtio";
|
||||
import { z } from "zod";
|
||||
|
||||
const templateForm = z.object({
|
||||
name: z.string().min(3, "Nama minimal 3 karakter"),
|
||||
email: z.string().min(3, "Email minimal 3 karakter"),
|
||||
notelp: z.string().min(3, "Nomor Telepon minimal 3 karakter"),
|
||||
alasan: z.string().min(3, "Alasan minimal 3 karakter"),
|
||||
})
|
||||
|
||||
type PermohonanKeberatanInformasiForm = Prisma.FormulirPermohonanKeberatanGetPayload<{
|
||||
select: {
|
||||
name: true;
|
||||
email: true;
|
||||
notelp: true;
|
||||
alasan: true;
|
||||
};
|
||||
}>;
|
||||
|
||||
const permohonanKeberatanInformasi = proxy({
|
||||
create: {
|
||||
form: {} as PermohonanKeberatanInformasiForm,
|
||||
loading: false,
|
||||
async create(){
|
||||
const cek = templateForm.safeParse(permohonanKeberatanInformasi.create.form);
|
||||
if(!cek.success) {
|
||||
const err = `[${cek.error.issues
|
||||
.map((v) => `${v.path.join(".")}`)
|
||||
.join("\n")}] required`;
|
||||
return toast.error(err);
|
||||
}
|
||||
try {
|
||||
permohonanKeberatanInformasi.create.loading = true;
|
||||
const res = await ApiFetch.api.ppid.permohonankeberataninformasipublik["create"].post(permohonanKeberatanInformasi.create.form);
|
||||
if (res.status === 200) {
|
||||
permohonanKeberatanInformasi.findMany.load();
|
||||
return toast.success("success create");
|
||||
}
|
||||
return toast.error("failed create");
|
||||
} catch (error) {
|
||||
console.log((error as Error).message);
|
||||
} finally {
|
||||
permohonanKeberatanInformasi.create.loading = false;
|
||||
}
|
||||
},
|
||||
},
|
||||
findMany: {
|
||||
data: null as
|
||||
| Prisma.FormulirPermohonanKeberatanGetPayload<{omit: {isActive: true}}>[]
|
||||
| null,
|
||||
async load() {
|
||||
const res = await ApiFetch.api.ppid.permohonankeberataninformasipublik["find-many"].get();
|
||||
if (res.status === 200) {
|
||||
permohonanKeberatanInformasi.findMany.data = res.data?.data ?? [];
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
export default permohonanKeberatanInformasi;
|
||||
|
||||
@@ -0,0 +1,125 @@
|
||||
import ApiFetch from "@/lib/api-fetch";
|
||||
import { Prisma } from "@prisma/client";
|
||||
import { toast } from "react-toastify";
|
||||
import { proxy } from "valtio";
|
||||
import { z } from "zod";
|
||||
|
||||
// Schema validasi form
|
||||
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"),
|
||||
});
|
||||
|
||||
// Type ambil dari Prisma
|
||||
type ProfilePPIDForm = Prisma.ProfilePPIDGetPayload<{
|
||||
select: {
|
||||
id: true;
|
||||
name: true;
|
||||
biodata: true;
|
||||
riwayat: true;
|
||||
pengalaman: true;
|
||||
unggulan: true;
|
||||
imageUrl: true;
|
||||
};
|
||||
}>;
|
||||
|
||||
// Proxy utama
|
||||
const stateProfilePPID = proxy({
|
||||
findById: {
|
||||
data: null as ProfilePPIDForm | null,
|
||||
loading: false,
|
||||
initialize() {
|
||||
stateProfilePPID.findById.data = {
|
||||
id: '',
|
||||
name: '',
|
||||
biodata: '',
|
||||
riwayat: '',
|
||||
pengalaman: '',
|
||||
unggulan: '',
|
||||
imageUrl:''
|
||||
} as ProfilePPIDForm;
|
||||
},
|
||||
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;
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
update: {
|
||||
loading: false,
|
||||
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;
|
||||
}
|
||||
},
|
||||
},
|
||||
uploadImage: {
|
||||
loading: false,
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
export default stateProfilePPID;
|
||||
@@ -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;
|
||||
93
src/app/admin/(dashboard)/desa/_com/desaEditor.tsx
Normal file
93
src/app/admin/(dashboard)/desa/_com/desaEditor.tsx
Normal file
@@ -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 =
|
||||
'<h2 style="text-align: center;">Welcome to Mantine rich text editor</h2><p><code>RichTextEditor</code> component focuses on usability and is designed to be as simple as possible to bring a familiar editing experience to regular users. <code>RichTextEditor</code> is based on <a href="https://tiptap.dev/" rel="noopener noreferrer" target="_blank">Tiptap.dev</a> and supports all of its features:</p><ul><li>General text formatting: <strong>bold</strong>, <em>italic</em>, <u>underline</u>, <s>strike-through</s> </li><li>Headings (h1-h6)</li><li>Sub and super scripts (<sup><sup /></sup> and <sub><sub /></sub> tags)</li><li>Ordered and bullet lists</li><li>Text align </li><li>And all <a href="https://tiptap.dev/extensions" target="_blank" rel="noopener noreferrer">other extensions</a></li></ul>';
|
||||
|
||||
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 (
|
||||
<Stack>
|
||||
<RichTextEditor editor={editor}>
|
||||
<RichTextEditor.Toolbar sticky stickyOffset={60}>
|
||||
<RichTextEditor.ControlsGroup>
|
||||
<RichTextEditor.Bold />
|
||||
<RichTextEditor.Italic />
|
||||
<RichTextEditor.Underline />
|
||||
<RichTextEditor.Strikethrough />
|
||||
<RichTextEditor.ClearFormatting />
|
||||
<RichTextEditor.Highlight />
|
||||
<RichTextEditor.Code />
|
||||
</RichTextEditor.ControlsGroup>
|
||||
|
||||
<RichTextEditor.ControlsGroup>
|
||||
<RichTextEditor.H1 />
|
||||
<RichTextEditor.H2 />
|
||||
<RichTextEditor.H3 />
|
||||
<RichTextEditor.H4 />
|
||||
</RichTextEditor.ControlsGroup>
|
||||
|
||||
<RichTextEditor.ControlsGroup>
|
||||
<RichTextEditor.Blockquote />
|
||||
<RichTextEditor.Hr />
|
||||
<RichTextEditor.BulletList />
|
||||
<RichTextEditor.OrderedList />
|
||||
<RichTextEditor.Subscript />
|
||||
<RichTextEditor.Superscript />
|
||||
</RichTextEditor.ControlsGroup>
|
||||
|
||||
<RichTextEditor.ControlsGroup>
|
||||
<RichTextEditor.Link />
|
||||
<RichTextEditor.Unlink />
|
||||
</RichTextEditor.ControlsGroup>
|
||||
|
||||
<RichTextEditor.ControlsGroup>
|
||||
<RichTextEditor.AlignLeft />
|
||||
<RichTextEditor.AlignCenter />
|
||||
<RichTextEditor.AlignJustify />
|
||||
<RichTextEditor.AlignRight />
|
||||
</RichTextEditor.ControlsGroup>
|
||||
|
||||
<RichTextEditor.ControlsGroup>
|
||||
<RichTextEditor.Undo />
|
||||
<RichTextEditor.Redo />
|
||||
</RichTextEditor.ControlsGroup>
|
||||
</RichTextEditor.Toolbar>
|
||||
|
||||
<RichTextEditor.Content />
|
||||
</RichTextEditor>
|
||||
{showSubmit && (
|
||||
<Button
|
||||
mt={10}
|
||||
bg={colors['blue-button']}
|
||||
>
|
||||
Submit
|
||||
</Button>
|
||||
)}
|
||||
</Stack>
|
||||
);
|
||||
}
|
||||
95
src/app/admin/(dashboard)/desa/_com/desaEditorText.tsx
Normal file
95
src/app/admin/(dashboard)/desa/_com/desaEditorText.tsx
Normal file
@@ -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 (
|
||||
<Stack>
|
||||
<RichTextEditor editor={editor}>
|
||||
<RichTextEditor.Toolbar sticky stickyOffset={60}>
|
||||
<RichTextEditor.ControlsGroup>
|
||||
<RichTextEditor.Bold />
|
||||
<RichTextEditor.Italic />
|
||||
<RichTextEditor.Underline />
|
||||
<RichTextEditor.Strikethrough />
|
||||
<RichTextEditor.ClearFormatting />
|
||||
<RichTextEditor.Highlight />
|
||||
<RichTextEditor.Code />
|
||||
</RichTextEditor.ControlsGroup>
|
||||
|
||||
<RichTextEditor.ControlsGroup>
|
||||
<RichTextEditor.H1 />
|
||||
<RichTextEditor.H2 />
|
||||
<RichTextEditor.H3 />
|
||||
<RichTextEditor.H4 />
|
||||
</RichTextEditor.ControlsGroup>
|
||||
|
||||
<RichTextEditor.ControlsGroup>
|
||||
<RichTextEditor.Blockquote />
|
||||
<RichTextEditor.Hr />
|
||||
<RichTextEditor.BulletList />
|
||||
<RichTextEditor.OrderedList />
|
||||
<RichTextEditor.Subscript />
|
||||
<RichTextEditor.Superscript />
|
||||
</RichTextEditor.ControlsGroup>
|
||||
|
||||
<RichTextEditor.ControlsGroup>
|
||||
<RichTextEditor.Link />
|
||||
<RichTextEditor.Unlink />
|
||||
</RichTextEditor.ControlsGroup>
|
||||
|
||||
<RichTextEditor.ControlsGroup>
|
||||
<RichTextEditor.AlignLeft />
|
||||
<RichTextEditor.AlignCenter />
|
||||
<RichTextEditor.AlignJustify />
|
||||
<RichTextEditor.AlignRight />
|
||||
</RichTextEditor.ControlsGroup>
|
||||
|
||||
<RichTextEditor.ControlsGroup>
|
||||
<RichTextEditor.Undo />
|
||||
<RichTextEditor.Redo />
|
||||
</RichTextEditor.ControlsGroup>
|
||||
</RichTextEditor.Toolbar>
|
||||
|
||||
<RichTextEditor.Content />
|
||||
</RichTextEditor>
|
||||
{showSubmit && (
|
||||
<Button onClick={() => {
|
||||
if (!editor) return
|
||||
onSubmit?.(editor?.getHTML())
|
||||
}}>Submit</Button>
|
||||
)}
|
||||
</Stack>
|
||||
);
|
||||
}
|
||||
|
||||
export default DesaEditorText;
|
||||
@@ -24,8 +24,14 @@ export function BeritaEditor({ onSubmit }: { onSubmit: (val: string) => void })
|
||||
TextAlign.configure({ types: ['heading', 'paragraph'] }),
|
||||
],
|
||||
content,
|
||||
immediatelyRender: false
|
||||
});
|
||||
|
||||
if (!editor) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
return (
|
||||
<Stack>
|
||||
<RichTextEditor editor={editor}>
|
||||
|
||||
@@ -10,9 +10,9 @@ import { BeritaEditor } from './_com/BeritaEditor';
|
||||
function Page() {
|
||||
return (
|
||||
<Stack>
|
||||
<SimpleGrid cols={2}>
|
||||
<BeritaList />
|
||||
<SimpleGrid cols={{base: 1, md: 2}}>
|
||||
<BeritaCreate />
|
||||
<BeritaList />
|
||||
</SimpleGrid>
|
||||
</Stack>
|
||||
);
|
||||
|
||||
@@ -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 (
|
||||
<div>
|
||||
Profile
|
||||
</div>
|
||||
<Stack >
|
||||
<Title order={3}>Profile Desa</Title>
|
||||
<Tabs color={colors['blue-button']} variant='pills' defaultValue={"Sejarah Desa"}>
|
||||
<TabsList p={"xs"} bg={"#BBC8E7FF"}>
|
||||
<TabsTab value="Sejarah Desa">
|
||||
Sejarah Desa
|
||||
</TabsTab>
|
||||
<TabsTab value="Visi Misi Desa">
|
||||
Visi Misi Desa
|
||||
</TabsTab>
|
||||
<TabsTab value="Lambang Desa">
|
||||
Lambang Desa
|
||||
</TabsTab>
|
||||
<TabsTab value="Maskot Desa">
|
||||
Maskot Desa
|
||||
</TabsTab>
|
||||
<TabsTab value="Profile Perbekel">
|
||||
Profile Perbekel
|
||||
</TabsTab>
|
||||
</TabsList>
|
||||
|
||||
<TabsPanel value="Sejarah Desa">
|
||||
<SejarahDesa/>
|
||||
</TabsPanel>
|
||||
<TabsPanel value="Visi Misi Desa">
|
||||
<VisiMisiDesa/>
|
||||
</TabsPanel>
|
||||
<TabsPanel value="Lambang Desa">
|
||||
<LambangDesa/>
|
||||
</TabsPanel>
|
||||
<TabsPanel value="Maskot Desa">
|
||||
<MaskotDesa/>
|
||||
</TabsPanel>
|
||||
<TabsPanel value="Profile Perbekel">
|
||||
<ProfilePerbekel/>
|
||||
</TabsPanel>
|
||||
</Tabs>
|
||||
</Stack>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -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 (
|
||||
<Box py={10}>
|
||||
<SimpleGrid cols={{ base: 1, md: 2 }}>
|
||||
<Box>
|
||||
<Paper bg={colors['white-1']} p={'md'}>
|
||||
<Stack>
|
||||
<Title order={3}>Lambang Desa</Title>
|
||||
<Text fw={"bold"}>Deskripsi Lambang Desa</Text>
|
||||
<DesaEditor showSubmit={false} />
|
||||
<Group>
|
||||
<Button
|
||||
mt={10}
|
||||
bg={colors['blue-button']}
|
||||
>
|
||||
Submit
|
||||
</Button>
|
||||
</Group>
|
||||
</Stack>
|
||||
</Paper>
|
||||
</Box>
|
||||
<Box>
|
||||
<Paper bg={colors['white-1']} p={'md'}>
|
||||
<Stack>
|
||||
<Title order={3}>List Lambang Desa</Title>
|
||||
</Stack>
|
||||
</Paper>
|
||||
</Box>
|
||||
</SimpleGrid>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
export default LambangDesa;
|
||||
@@ -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 (
|
||||
<Box py={10}>
|
||||
<SimpleGrid cols={{ base: 1, md: 2 }}>
|
||||
<Box>
|
||||
<Paper bg={colors['white-1']} p={'md'}>
|
||||
<Stack>
|
||||
<Title order={3}>Maskot Desa</Title>
|
||||
<Text fw={"bold"}>Deskripsi Maskot Desa</Text>
|
||||
<DesaEditor showSubmit={false} />
|
||||
<Group>
|
||||
<Button
|
||||
mt={10}
|
||||
bg={colors['blue-button']}
|
||||
>
|
||||
Submit
|
||||
</Button>
|
||||
</Group>
|
||||
</Stack>
|
||||
</Paper>
|
||||
</Box>
|
||||
<Box>
|
||||
<Paper bg={colors['white-1']} p={'md'}>
|
||||
<Stack>
|
||||
<Title order={3}>List Maskot Desa</Title>
|
||||
</Stack>
|
||||
</Paper>
|
||||
</Box>
|
||||
</SimpleGrid>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
export default MaskotDesa;
|
||||
@@ -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 (
|
||||
<Box py={10}>
|
||||
<SimpleGrid cols={{ base: 1, md: 2 }}>
|
||||
<Box>
|
||||
<Paper bg={colors['white-1']} p={'md'}>
|
||||
<Stack>
|
||||
<Title order={3}>Profil Perbekel</Title>
|
||||
<TextInput
|
||||
label="Nama Perbekel"
|
||||
placeholder="masukkan nama perbekel"
|
||||
/>
|
||||
<Text fz={"sm"} fw={"bold"}>Biodata</Text>
|
||||
<DesaEditor showSubmit={false} />
|
||||
<Text fz={"sm"} fw={"bold"}>Pengalaman</Text>
|
||||
<DesaEditor showSubmit={false} />
|
||||
<Text fz={"sm"} fw={"bold"}>Pengalaman Organisasi</Text>
|
||||
<DesaEditor showSubmit={false} />
|
||||
<Text fz={"sm"} fw={"bold"}>Program Unggulan</Text>
|
||||
<DesaEditor showSubmit={false} />
|
||||
<Group>
|
||||
<Button
|
||||
mt={10}
|
||||
bg={colors['blue-button']}
|
||||
>
|
||||
Submit
|
||||
</Button>
|
||||
</Group>
|
||||
</Stack>
|
||||
</Paper>
|
||||
</Box>
|
||||
<Box>
|
||||
<Paper bg={colors['white-1']} p={'md'}>
|
||||
<Stack>
|
||||
<Title order={3}>List Profil Perbekel</Title>
|
||||
</Stack>
|
||||
</Paper>
|
||||
</Box>
|
||||
</SimpleGrid>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
export default ProfilePerbekel;
|
||||
@@ -0,0 +1,38 @@
|
||||
import colors from '@/con/colors';
|
||||
import { Box, Button, Group, Paper, SimpleGrid, Stack, Text, Title } from '@mantine/core';
|
||||
import { DesaEditor } from '../../../_com/desaEditor';
|
||||
|
||||
function SejarahDesa() {
|
||||
return (
|
||||
<Box py={10}>
|
||||
<SimpleGrid cols={{ base: 1, md: 2 }}>
|
||||
<Box>
|
||||
<Paper bg={colors['white-1']} p={'md'}>
|
||||
<Stack>
|
||||
<Title order={3}>Sejarah Desa</Title>
|
||||
<Text fw={"bold"}>Deskripsi Sejarah Desa</Text>
|
||||
<DesaEditor showSubmit={false}/>
|
||||
<Group>
|
||||
<Button
|
||||
mt={10}
|
||||
bg={colors['blue-button']}
|
||||
>
|
||||
Submit
|
||||
</Button>
|
||||
</Group>
|
||||
</Stack>
|
||||
</Paper>
|
||||
</Box>
|
||||
<Box>
|
||||
<Paper bg={colors['white-1']} p={'md'}>
|
||||
<Stack>
|
||||
<Title order={3}>List Sejarah Desa</Title>
|
||||
</Stack>
|
||||
</Paper>
|
||||
</Box>
|
||||
</SimpleGrid>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
export default SejarahDesa;
|
||||
@@ -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 (
|
||||
<Box py={10}>
|
||||
<SimpleGrid cols={{ base: 1, md: 2 }}>
|
||||
<Box>
|
||||
<Paper bg={colors['white-1']} p={'md'}>
|
||||
<Stack>
|
||||
<Title order={3}>Visi Desa</Title>
|
||||
<Text fw={"bold"}>Deskripsi Visi Desa</Text>
|
||||
<DesaEditor showSubmit={false} />
|
||||
<Group>
|
||||
<Button
|
||||
mt={10}
|
||||
bg={colors['blue-button']}
|
||||
>
|
||||
Submit
|
||||
</Button>
|
||||
</Group>
|
||||
</Stack>
|
||||
</Paper>
|
||||
</Box>
|
||||
<Box>
|
||||
<Paper bg={colors['white-1']} p={'md'}>
|
||||
<Stack>
|
||||
<Title order={3}>List Visi Desa</Title>
|
||||
</Stack>
|
||||
</Paper>
|
||||
</Box>
|
||||
</SimpleGrid>
|
||||
<SimpleGrid py={30} cols={{ base: 1, md: 2 }}>
|
||||
<Box>
|
||||
<Paper bg={colors['white-1']} p={'md'}>
|
||||
<Stack>
|
||||
<Title order={3}>Misi Desa</Title>
|
||||
<Text fw={"bold"}>Deskripsi Misi Desa</Text>
|
||||
<DesaEditor showSubmit={false}/>
|
||||
<Group>
|
||||
<Button
|
||||
mt={10}
|
||||
bg={colors['blue-button']}
|
||||
>
|
||||
Submit
|
||||
</Button>
|
||||
</Group>
|
||||
</Stack>
|
||||
</Paper>
|
||||
</Box>
|
||||
<Box>
|
||||
<Paper bg={colors['white-1']} p={'md'}>
|
||||
<Stack>
|
||||
<Title order={3}>List Misi Desa</Title>
|
||||
</Stack>
|
||||
</Paper>
|
||||
</Box>
|
||||
</SimpleGrid>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
export default VisiMisiDesa;
|
||||
@@ -0,0 +1,23 @@
|
||||
'use client'
|
||||
import { Box, 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';
|
||||
|
||||
function DoctorSignUI() {
|
||||
const doctorSign = useProxy(stateArtikelKesehatan.doctorSign)
|
||||
return (
|
||||
<Box>
|
||||
<Text fw={"bold"}>Kapan Harus ke Dokter</Text>
|
||||
<KesehatanEditor
|
||||
showSubmit={false}
|
||||
onChange={(val) => {
|
||||
doctorSign.create.form.content = val
|
||||
}}
|
||||
/>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
export default DoctorSignUI;
|
||||
@@ -0,0 +1,29 @@
|
||||
'use client'
|
||||
import { Box, 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';
|
||||
|
||||
function FirstAidUI() {
|
||||
const firstAidState = useProxy(stateArtikelKesehatan.firstAid)
|
||||
return (
|
||||
<Box>
|
||||
<TextInput
|
||||
label={<Text fw={"bold"}>Title Pertolongan Pertama</Text>}
|
||||
placeholder="Masukkan title"
|
||||
onChange={(val) => {
|
||||
firstAidState.create.form.title = val.target.value
|
||||
}}
|
||||
/>
|
||||
<KesehatanEditor
|
||||
showSubmit={false}
|
||||
onChange={(val) => {
|
||||
firstAidState.create.form.content = val
|
||||
}}
|
||||
/>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
export default FirstAidUI;
|
||||
@@ -0,0 +1,23 @@
|
||||
'use client'
|
||||
import { Box, 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';
|
||||
|
||||
function IntoductionUI() {
|
||||
const introduction = useProxy(stateArtikelKesehatan.introduction)
|
||||
return (
|
||||
<Box py={10}>
|
||||
<Text fw={"bold"}>Pendahuluan</Text>
|
||||
<KesehatanEditor
|
||||
showSubmit={false}
|
||||
onChange={(val) => {
|
||||
introduction.create.form.content = val;
|
||||
}}
|
||||
/>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
export default IntoductionUI;
|
||||
@@ -0,0 +1,35 @@
|
||||
'use client'
|
||||
import stateArtikelKesehatan from '@/app/admin/(dashboard)/_state/kesehatan/data_kesehatan_warga/artikelKesehatan';
|
||||
import { Box, Text, TextInput } from '@mantine/core';
|
||||
import { useProxy } from 'valtio/utils';
|
||||
|
||||
function MythFactUI() {
|
||||
const mythFact = useProxy(stateArtikelKesehatan.mythFact)
|
||||
return (
|
||||
<Box py={10}>
|
||||
<TextInput
|
||||
label={<Text fw={"bold"}>Title Pertolongan Pertama Penyakit</Text>}
|
||||
placeholder="Masukkan title"
|
||||
onChange={(val) => {
|
||||
mythFact.create.form.title = val.target.value
|
||||
}}
|
||||
/>
|
||||
<TextInput
|
||||
label={<Text fw={"bold"}>Mitos</Text>}
|
||||
placeholder="Masukkan mitos"
|
||||
onChange={(val) => {
|
||||
mythFact.create.form.mitos = val.target.value
|
||||
}}
|
||||
/>
|
||||
<TextInput
|
||||
label={<Text fw={"bold"}>Fakta</Text>}
|
||||
placeholder="Masukkan fakta"
|
||||
onChange={(val) => {
|
||||
mythFact.create.form.fakta = val.target.value
|
||||
}}
|
||||
/>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
export default MythFactUI;
|
||||
@@ -1,26 +1,149 @@
|
||||
import { Box, SimpleGrid, Stack, TextInput, Title } from '@mantine/core';
|
||||
import React from 'react';
|
||||
'use client'
|
||||
import { Box, Button, Center, SimpleGrid, Skeleton, Stack, Table, TableTbody, TableTd, TableTh, TableThead, TableTr, Text, Title } from '@mantine/core';
|
||||
import IntoductionUI from './introduction/page';
|
||||
import SymptomUI from './symptom/page';
|
||||
import PreventionUI from './prevention/page';
|
||||
import MythFactUI from './mythVsfact/page';
|
||||
import DoctorSignUI from './doctor_sign/page';
|
||||
import { useProxy } from 'valtio/utils';
|
||||
import stateArtikelKesehatan from '@/app/admin/(dashboard)/_state/kesehatan/data_kesehatan_warga/artikelKesehatan';
|
||||
import FirstAidUI from './first_aid/page';
|
||||
import { useShallowEffect } from '@mantine/hooks';
|
||||
import colors from '@/con/colors';
|
||||
|
||||
function ArtikelKesehatan() {
|
||||
const state = useProxy(stateArtikelKesehatan)
|
||||
const submitAllForms = () => {
|
||||
if (state.introduction.create.form.content) {
|
||||
state.introduction.create.create()
|
||||
}
|
||||
if (state.symptom.create.form.title && state.symptom.create.form.content) {
|
||||
state.symptom.create.create()
|
||||
}
|
||||
if (state.prevention.create.form.title && state.prevention.create.form.content) {
|
||||
state.prevention.create.create()
|
||||
}
|
||||
if (state.firstAid.create.form.title && state.firstAid.create.form.content) {
|
||||
state.firstAid.create.create()
|
||||
}
|
||||
if (state.mythFact.create.form.title && state.mythFact.create.form.mitos && state.mythFact.create.form.fakta) {
|
||||
state.mythFact.create.create()
|
||||
}
|
||||
if (state.doctorSign.create.form.content) {
|
||||
state.doctorSign.create.create()
|
||||
}
|
||||
}
|
||||
return (
|
||||
<Stack py={10}>
|
||||
<SimpleGrid cols={{
|
||||
base: 1, md: 2
|
||||
}}>
|
||||
<Box>
|
||||
<Box >
|
||||
<Title order={3}>Artikel Kesehatan</Title>
|
||||
<TextInput
|
||||
label="Jadwal"
|
||||
placeholder='masukkan artikel kesehatan'
|
||||
/>
|
||||
<IntoductionUI />
|
||||
<SymptomUI />
|
||||
<PreventionUI />
|
||||
<FirstAidUI />
|
||||
<MythFactUI />
|
||||
<DoctorSignUI />
|
||||
<Button mt={10} onClick={submitAllForms}>Submit</Button>
|
||||
</Box>
|
||||
|
||||
<Box>
|
||||
<Title order={3}>List Artikel Kesehatan</Title>
|
||||
<AllList />
|
||||
</Box>
|
||||
</SimpleGrid>
|
||||
</Stack>
|
||||
);
|
||||
}
|
||||
|
||||
function AllList() {
|
||||
const listState = useProxy(stateArtikelKesehatan)
|
||||
useShallowEffect(() => {
|
||||
listState.introduction.findMany.load();
|
||||
listState.symptom.findMany.load();
|
||||
listState.prevention.findMany.load();
|
||||
listState.firstAid.findMany.load();
|
||||
listState.mythFact.findMany.load();
|
||||
listState.doctorSign.findMany.load();
|
||||
}, [])
|
||||
|
||||
if (!listState.introduction.findMany.data
|
||||
|| !listState.symptom.findMany.data
|
||||
|| !listState.prevention.findMany.data
|
||||
|| !listState.firstAid.findMany.data
|
||||
|| !listState.mythFact.findMany.data
|
||||
|| !listState.doctorSign.findMany.data
|
||||
) return <Stack>
|
||||
{Array.from({ length: 10 }).map((v, k) => <Skeleton key={k} h={40} />)}
|
||||
</Stack>
|
||||
return <Stack>
|
||||
<Title order={4}>Intoduction</Title>
|
||||
{listState.introduction.findMany.data?.map((item) => (
|
||||
<Box key={item.id}>
|
||||
<Text dangerouslySetInnerHTML={{ __html: item.content }}></Text>
|
||||
</Box>
|
||||
))}
|
||||
{/* Symptom */}
|
||||
{listState.symptom.findMany.data?.map((item) => (
|
||||
<Box key={item.id}>
|
||||
<Title order={4}>{item.title}</Title>
|
||||
<Text dangerouslySetInnerHTML={{ __html: item.content }}></Text>
|
||||
</Box>
|
||||
))}
|
||||
{/* Prevention */}
|
||||
{listState.prevention.findMany.data?.map((item) => (
|
||||
<Box key={item.id}>
|
||||
<Title order={4}>{item.title}</Title>
|
||||
<Text dangerouslySetInnerHTML={{ __html: item.content }}></Text>
|
||||
</Box>
|
||||
))}
|
||||
{/* First Aid */}
|
||||
{listState.firstAid.findMany.data?.map((item) => (
|
||||
<Box key={item.id}>
|
||||
<Title order={4}>{item.title}</Title>
|
||||
<Text dangerouslySetInnerHTML={{ __html: item.content }}></Text>
|
||||
</Box>
|
||||
))}
|
||||
{/* Myth Fact */}
|
||||
{listState.mythFact.findMany.data?.map((item) => (
|
||||
<Box key={item.id}>
|
||||
<Title order={4}>{item.title}</Title>
|
||||
<Table
|
||||
striped
|
||||
highlightOnHover
|
||||
withTableBorder
|
||||
withColumnBorders
|
||||
bg={colors['white-1']}
|
||||
>
|
||||
<TableThead >
|
||||
<TableTr >
|
||||
<TableTh >
|
||||
<Center>Mitos</Center>
|
||||
</TableTh>
|
||||
<TableTh >
|
||||
<Center>Fakta</Center>
|
||||
</TableTh>
|
||||
</TableTr>
|
||||
</TableThead>
|
||||
<TableTbody >
|
||||
<TableTr>
|
||||
<TableTd ta="center">{item.mitos}</TableTd>
|
||||
<TableTd ta="center">{item.fakta}</TableTd>
|
||||
</TableTr>
|
||||
</TableTbody>
|
||||
</Table>
|
||||
</Box>
|
||||
))}
|
||||
{/* Doctor Sign */}
|
||||
<Title order={4}>Kapan Harus Ke Dokter?</Title>
|
||||
{listState.doctorSign.findMany.data?.map((item) => (
|
||||
<Box key={item.id}>
|
||||
<Text dangerouslySetInnerHTML={{ __html: item.content }}/>
|
||||
</Box>
|
||||
))}
|
||||
</Stack>
|
||||
}
|
||||
|
||||
export default ArtikelKesehatan;
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
'use client'
|
||||
import stateArtikelKesehatan from '@/app/admin/(dashboard)/_state/kesehatan/data_kesehatan_warga/artikelKesehatan';
|
||||
import { Box, Text, TextInput } from '@mantine/core';
|
||||
import React from 'react';
|
||||
import { useProxy } from 'valtio/utils';
|
||||
import { KesehatanEditor } from '../../../_com/kesehatanEditor';
|
||||
|
||||
function PreventionUI() {
|
||||
const preventionState = useProxy(stateArtikelKesehatan.prevention)
|
||||
return (
|
||||
<Box py={10}>
|
||||
<TextInput
|
||||
mb={10}
|
||||
label={<Text fw={"bold"}>Title Pencegahan Penyakit</Text>}
|
||||
placeholder="Masukkan title"
|
||||
onChange={(val) => {
|
||||
preventionState.create.form.title = val.target.value
|
||||
}}
|
||||
/>
|
||||
<KesehatanEditor
|
||||
showSubmit={false}
|
||||
onChange={(val) => {
|
||||
preventionState.create.form.content = val
|
||||
}}
|
||||
/>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
export default PreventionUI;
|
||||
@@ -0,0 +1,29 @@
|
||||
'use client'
|
||||
import stateArtikelKesehatan from '@/app/admin/(dashboard)/_state/kesehatan/data_kesehatan_warga/artikelKesehatan';
|
||||
import { Box, Text, TextInput } from '@mantine/core';
|
||||
import { useProxy } from 'valtio/utils';
|
||||
import { KesehatanEditor } from '../../../_com/kesehatanEditor';
|
||||
|
||||
function SymptomUI() {
|
||||
const symptomState = useProxy(stateArtikelKesehatan.symptom)
|
||||
return (
|
||||
<Box py={10}>
|
||||
<TextInput
|
||||
mb={10}
|
||||
label={<Text fw={"bold"}>Title Gejala Penyakit</Text>}
|
||||
placeholder='masukkan title'
|
||||
onChange={(val) => {
|
||||
symptomState.create.form.title = val.target.value
|
||||
}}
|
||||
/>
|
||||
<KesehatanEditor
|
||||
showSubmit={false}
|
||||
onChange={(val) => {
|
||||
symptomState.create.form.content = val
|
||||
}}
|
||||
/>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
export default SymptomUI;
|
||||
@@ -1,16 +1,20 @@
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
'use client'
|
||||
import stategrafikKepuasan from '@/app/admin/(dashboard)/_state/kesehatan/data_kesehatan_warga/grafikKepuasan';
|
||||
import colors from '@/con/colors';
|
||||
import { Box, Button, Group, Stack, TextInput, Title } from '@mantine/core';
|
||||
import { useShallowEffect } from '@mantine/hooks';
|
||||
import { useState } from 'react';
|
||||
import { Bar, Legend, RadialBarChart, ResponsiveContainer, Tooltip, XAxis, YAxis } from 'recharts';
|
||||
import { useMediaQuery, useShallowEffect } from '@mantine/hooks';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { Bar, BarChart, Legend, Tooltip, XAxis, YAxis } from 'recharts';
|
||||
import { useProxy } from 'valtio/utils';
|
||||
|
||||
function GrafikHasilKepuasan() {
|
||||
const grafikkepuasan = useProxy(stategrafikKepuasan.grafikkepuasan)
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const [mounted, setMounted] = useState(false);
|
||||
const isTablet = useMediaQuery('(max-width: 1024px)')
|
||||
const isMobile = useMediaQuery('(max-width: 768px)')
|
||||
const [chartData, setChartData] = useState<any[]>([])
|
||||
|
||||
useShallowEffect(() => {
|
||||
const fetchData = async () => {
|
||||
await grafikkepuasan.findMany.load();
|
||||
@@ -20,11 +24,22 @@ function GrafikHasilKepuasan() {
|
||||
};
|
||||
fetchData();
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
setMounted(true); // setelah komponen siap di client
|
||||
}, []);
|
||||
|
||||
if (!mounted) {
|
||||
return null; // Jangan render apa-apa dulu sebelum mounted
|
||||
}
|
||||
|
||||
|
||||
return (
|
||||
<Stack gap={"xs"}>
|
||||
<Title order={3}>Grafik Hasil Kepuasan</Title>
|
||||
<Box>
|
||||
<TextInput
|
||||
w={{ base: '100%', md: '50%' }}
|
||||
label="Label"
|
||||
placeholder='Masukkan label yang diinginkan'
|
||||
value={grafikkepuasan.create.form.label}
|
||||
@@ -33,9 +48,10 @@ function GrafikHasilKepuasan() {
|
||||
}}
|
||||
/>
|
||||
<TextInput
|
||||
label="Jumlah Penderita Farangitis Akut"
|
||||
w={{ base: '100%', md: '50%' }}
|
||||
label="Jumlah Penderita"
|
||||
type='number'
|
||||
placeholder='Masukkan jumlah penderita farangitis akut'
|
||||
placeholder='Masukkan jumlah penderita'
|
||||
value={grafikkepuasan.create.form.jumlah}
|
||||
onChange={(val) => {
|
||||
grafikkepuasan.create.form.jumlah = val.currentTarget.value
|
||||
@@ -43,29 +59,29 @@ function GrafikHasilKepuasan() {
|
||||
/>
|
||||
</Box>
|
||||
<Group>
|
||||
<Button mt={10}
|
||||
onClick={async () => {
|
||||
await grafikkepuasan.create.create();
|
||||
await grafikkepuasan.findMany.load();
|
||||
if (grafikkepuasan.findMany.data) {
|
||||
setChartData(grafikkepuasan.findMany.data);
|
||||
}
|
||||
}}
|
||||
<Button mt={10}
|
||||
onClick={async () => {
|
||||
await grafikkepuasan.create.create();
|
||||
await grafikkepuasan.findMany.load();
|
||||
if (grafikkepuasan.findMany.data) {
|
||||
setChartData(grafikkepuasan.findMany.data);
|
||||
}
|
||||
}}
|
||||
>Submit</Button>
|
||||
</Group>
|
||||
<Box h={400} w={{ base: "100%", md: "80%" }}>
|
||||
<Title order={3}>Data Kelahiran & Kematian</Title>
|
||||
<ResponsiveContainer width="100%" height="100%">
|
||||
<RadialBarChart
|
||||
<Title py={15} order={3}>Data Kelahiran & Kematian</Title>
|
||||
<BarChart
|
||||
width={isMobile ? 450 : isTablet ? 600 : 900}
|
||||
height={380}
|
||||
data={chartData}
|
||||
>
|
||||
<XAxis dataKey="label" />
|
||||
<YAxis />
|
||||
<Tooltip />
|
||||
<Legend />
|
||||
<Bar dataKey="jumlah" fill={colors['blue-button']} name="Jumlah" />
|
||||
</RadialBarChart>
|
||||
</ResponsiveContainer>
|
||||
>
|
||||
<XAxis dataKey="label" />
|
||||
<YAxis />
|
||||
<Tooltip />
|
||||
<Legend />
|
||||
<Bar dataKey="jumlah" fill={colors['blue-button']} name="Jumlah" />
|
||||
</BarChart>
|
||||
</Box>
|
||||
</Stack>
|
||||
);
|
||||
|
||||
@@ -2,15 +2,17 @@
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
import statePersentase from '@/app/admin/(dashboard)/_state/kesehatan/data_kesehatan_warga/persentaseKelahiran';
|
||||
import { Box, Button, Stack, TextInput, Title } from '@mantine/core';
|
||||
import { useShallowEffect } from '@mantine/hooks';
|
||||
import { useMediaQuery, useShallowEffect } from '@mantine/hooks';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { Bar, BarChart, Legend, ResponsiveContainer, Tooltip, XAxis, YAxis } from 'recharts';
|
||||
import { Bar, BarChart, Legend, Tooltip, XAxis, YAxis } from 'recharts';
|
||||
import { useProxy } from 'valtio/utils';
|
||||
|
||||
function PersentaseDataKelahiranKematian() {
|
||||
const persentase = useProxy(statePersentase.persentasekelahiran);
|
||||
const [chartData, setChartData] = useState<any[]>([]);
|
||||
const [mounted, setMounted] = useState(false); // untuk memastikan DOM sudah ready
|
||||
const isTablet = useMediaQuery('(max-width: 1024px)')
|
||||
const isMobile = useMediaQuery('(max-width: 768px)')
|
||||
|
||||
useEffect(() => {
|
||||
setMounted(true);
|
||||
@@ -87,19 +89,17 @@ function PersentaseDataKelahiranKematian() {
|
||||
|
||||
{/* Chart */}
|
||||
<Box style={{ width: '100%', minWidth: 300, height: 400, minHeight: 300 }}>
|
||||
<Title order={3}>Data Kelahiran & Kematian</Title>
|
||||
<Title pb={10} order={3}>Data Kelahiran & Kematian</Title>
|
||||
{mounted && chartData.length > 0 && (
|
||||
<ResponsiveContainer width="100%" aspect={2}>
|
||||
<BarChart width={300} data={chartData}>
|
||||
<XAxis dataKey="tahun" />
|
||||
<YAxis />
|
||||
<Tooltip />
|
||||
<Legend />
|
||||
<Bar dataKey="kematianKasar" fill="#f03e3e" name="Kematian Kasar" />
|
||||
<Bar dataKey="kematianBayi" fill="#ff922b" name="Kematian Bayi" />
|
||||
<Bar dataKey="kelahiranKasar" fill="#4dabf7" name="Kelahiran Kasar" />
|
||||
</BarChart>
|
||||
</ResponsiveContainer>
|
||||
<BarChart width={isMobile ? 450 : isTablet ? 600 : 900} height={380} data={chartData} >
|
||||
<XAxis dataKey="tahun" />
|
||||
<YAxis />
|
||||
<Tooltip />
|
||||
<Legend />
|
||||
<Bar dataKey="kematianKasar" fill="#f03e3e" name="Kematian Kasar" />
|
||||
<Bar dataKey="kematianBayi" fill="#ff922b" name="Kematian Bayi" />
|
||||
<Bar dataKey="kelahiranKasar" fill="#4dabf7" name="Kelahiran Kasar" />
|
||||
</BarChart>
|
||||
)}
|
||||
</Box>
|
||||
</Stack>
|
||||
|
||||
93
src/app/admin/(dashboard)/ppid/_com/PPIDTextEditor.tsx
Normal file
93
src/app/admin/(dashboard)/ppid/_com/PPIDTextEditor.tsx
Normal file
@@ -0,0 +1,93 @@
|
||||
'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';
|
||||
|
||||
|
||||
export function PPIDTextEditor({ onSubmit, onChange, showSubmit = true, initialContent = '', }: {
|
||||
onSubmit?: (val: string) => void,
|
||||
onChange: (val: string) => void,
|
||||
showSubmit?: boolean,
|
||||
initialContent?: string }) {
|
||||
const editor = useEditor({
|
||||
extensions: [
|
||||
StarterKit,
|
||||
Underline,
|
||||
Link,
|
||||
Superscript,
|
||||
SubScript,
|
||||
Highlight,
|
||||
TextAlign.configure({ types: ['heading', 'paragraph'] }),
|
||||
],
|
||||
immediatelyRender: false,
|
||||
content: initialContent,
|
||||
onUpdate : ({editor}) => {
|
||||
onChange(editor.getHTML())
|
||||
}
|
||||
});
|
||||
|
||||
return (
|
||||
<Stack>
|
||||
<RichTextEditor editor={editor}>
|
||||
<RichTextEditor.Toolbar sticky stickyOffset={60}>
|
||||
<RichTextEditor.ControlsGroup>
|
||||
<RichTextEditor.Bold />
|
||||
<RichTextEditor.Italic />
|
||||
<RichTextEditor.Underline />
|
||||
<RichTextEditor.Strikethrough />
|
||||
<RichTextEditor.ClearFormatting />
|
||||
<RichTextEditor.Highlight />
|
||||
<RichTextEditor.Code />
|
||||
</RichTextEditor.ControlsGroup>
|
||||
|
||||
<RichTextEditor.ControlsGroup>
|
||||
<RichTextEditor.H1 />
|
||||
<RichTextEditor.H2 />
|
||||
<RichTextEditor.H3 />
|
||||
<RichTextEditor.H4 />
|
||||
</RichTextEditor.ControlsGroup>
|
||||
|
||||
<RichTextEditor.ControlsGroup>
|
||||
<RichTextEditor.Blockquote />
|
||||
<RichTextEditor.Hr />
|
||||
<RichTextEditor.BulletList />
|
||||
<RichTextEditor.OrderedList />
|
||||
<RichTextEditor.Subscript />
|
||||
<RichTextEditor.Superscript />
|
||||
</RichTextEditor.ControlsGroup>
|
||||
|
||||
<RichTextEditor.ControlsGroup>
|
||||
<RichTextEditor.Link />
|
||||
<RichTextEditor.Unlink />
|
||||
</RichTextEditor.ControlsGroup>
|
||||
|
||||
<RichTextEditor.ControlsGroup>
|
||||
<RichTextEditor.AlignLeft />
|
||||
<RichTextEditor.AlignCenter />
|
||||
<RichTextEditor.AlignJustify />
|
||||
<RichTextEditor.AlignRight />
|
||||
</RichTextEditor.ControlsGroup>
|
||||
|
||||
<RichTextEditor.ControlsGroup>
|
||||
<RichTextEditor.Undo />
|
||||
<RichTextEditor.Redo />
|
||||
</RichTextEditor.ControlsGroup>
|
||||
</RichTextEditor.Toolbar>
|
||||
|
||||
<RichTextEditor.Content />
|
||||
</RichTextEditor>
|
||||
{showSubmit && (
|
||||
<Button onClick={() => {
|
||||
if (!editor) return
|
||||
onSubmit?.(editor?.getHTML())
|
||||
}}>Submit</Button>
|
||||
)}
|
||||
</Stack>
|
||||
);
|
||||
}
|
||||
94
src/app/admin/(dashboard)/ppid/_com/ppid_Editor.tsx
Normal file
94
src/app/admin/(dashboard)/ppid/_com/ppid_Editor.tsx
Normal file
@@ -0,0 +1,94 @@
|
||||
'use client'
|
||||
import { Button, Stack } from '@mantine/core';
|
||||
import { Link, RichTextEditor } from '@mantine/tiptap';
|
||||
import Highlight from '@tiptap/extension-highlight';
|
||||
import SubScript from '@tiptap/extension-subscript';
|
||||
import Superscript from '@tiptap/extension-superscript';
|
||||
import TextAlign from '@tiptap/extension-text-align';
|
||||
import Underline from '@tiptap/extension-underline';
|
||||
import { useEditor } from '@tiptap/react';
|
||||
import StarterKit from '@tiptap/starter-kit';
|
||||
|
||||
const content =
|
||||
'<p>Dokumen yang berisi kebijakan dan regulasi desa</p>';
|
||||
|
||||
export function PPIDEditor({ onSubmit, onChange, showSubmit = true }: {
|
||||
onSubmit?: (val: string) => void,
|
||||
onChange: (val: string) => void,
|
||||
showSubmit?: boolean }) {
|
||||
const editor = useEditor({
|
||||
extensions: [
|
||||
StarterKit,
|
||||
Underline,
|
||||
Link,
|
||||
Superscript,
|
||||
SubScript,
|
||||
Highlight,
|
||||
TextAlign.configure({ types: ['heading', 'paragraph'] }),
|
||||
],
|
||||
immediatelyRender: false,
|
||||
content,
|
||||
onUpdate : ({editor}) => {
|
||||
onChange(editor.getHTML())
|
||||
}
|
||||
});
|
||||
|
||||
return (
|
||||
<Stack>
|
||||
<RichTextEditor editor={editor}>
|
||||
<RichTextEditor.Toolbar sticky stickyOffset={60}>
|
||||
<RichTextEditor.ControlsGroup>
|
||||
<RichTextEditor.Bold />
|
||||
<RichTextEditor.Italic />
|
||||
<RichTextEditor.Underline />
|
||||
<RichTextEditor.Strikethrough />
|
||||
<RichTextEditor.ClearFormatting />
|
||||
<RichTextEditor.Highlight />
|
||||
<RichTextEditor.Code />
|
||||
</RichTextEditor.ControlsGroup>
|
||||
|
||||
<RichTextEditor.ControlsGroup>
|
||||
<RichTextEditor.H1 />
|
||||
<RichTextEditor.H2 />
|
||||
<RichTextEditor.H3 />
|
||||
<RichTextEditor.H4 />
|
||||
</RichTextEditor.ControlsGroup>
|
||||
|
||||
<RichTextEditor.ControlsGroup>
|
||||
<RichTextEditor.Blockquote />
|
||||
<RichTextEditor.Hr />
|
||||
<RichTextEditor.BulletList />
|
||||
<RichTextEditor.OrderedList />
|
||||
<RichTextEditor.Subscript />
|
||||
<RichTextEditor.Superscript />
|
||||
</RichTextEditor.ControlsGroup>
|
||||
|
||||
<RichTextEditor.ControlsGroup>
|
||||
<RichTextEditor.Link />
|
||||
<RichTextEditor.Unlink />
|
||||
</RichTextEditor.ControlsGroup>
|
||||
|
||||
<RichTextEditor.ControlsGroup>
|
||||
<RichTextEditor.AlignLeft />
|
||||
<RichTextEditor.AlignCenter />
|
||||
<RichTextEditor.AlignJustify />
|
||||
<RichTextEditor.AlignRight />
|
||||
</RichTextEditor.ControlsGroup>
|
||||
|
||||
<RichTextEditor.ControlsGroup>
|
||||
<RichTextEditor.Undo />
|
||||
<RichTextEditor.Redo />
|
||||
</RichTextEditor.ControlsGroup>
|
||||
</RichTextEditor.Toolbar>
|
||||
|
||||
<RichTextEditor.Content />
|
||||
</RichTextEditor>
|
||||
{showSubmit && (
|
||||
<Button onClick={() => {
|
||||
if (!editor) return
|
||||
onSubmit?.(editor?.getHTML())
|
||||
}}>Submit</Button>
|
||||
)}
|
||||
</Stack>
|
||||
);
|
||||
}
|
||||
@@ -1,11 +1,116 @@
|
||||
import React from 'react';
|
||||
'use client'
|
||||
import colors from '@/con/colors';
|
||||
import { Box, Button, Group, Paper, SimpleGrid, Skeleton, Stack, Table, TableTbody, TableTd, TableTh, TableThead, TableTr, TextInput, Title } from '@mantine/core';
|
||||
import { useShallowEffect } from '@mantine/hooks';
|
||||
import { useProxy } from 'valtio/utils';
|
||||
import stateDaftarInformasiPublik from '../../_state/ppid/daftar_informasi_publik/daftarInformasiPublik';
|
||||
import { PPIDTextEditor } from '../_com/PPIDTextEditor';
|
||||
|
||||
function Page() {
|
||||
const daftarInformasi = useProxy(stateDaftarInformasiPublik.daftarInformasi)
|
||||
const submit = () => {
|
||||
if (daftarInformasi.create.form.jenisInformasi &&
|
||||
daftarInformasi.create.form.deskripsi &&
|
||||
daftarInformasi.create.form.tanggal) {
|
||||
daftarInformasi.create.create()
|
||||
}
|
||||
}
|
||||
return (
|
||||
<div>
|
||||
daftar-informasi-publik-desa-darmasaba
|
||||
</div>
|
||||
<Box>
|
||||
<SimpleGrid cols={{ base: 1, md: 2 }}>
|
||||
<Box>
|
||||
<Paper bg={colors['white-1']} p={'md'}>
|
||||
<Stack gap={"xs"}>
|
||||
<Title fw={"bold"} order={3}>Daftar Informasi Publik Desa Darmasaba</Title>
|
||||
<TextInput
|
||||
label="Jenis Informasi"
|
||||
placeholder="masukkan jenis informasi"
|
||||
onChange={(val) => {
|
||||
daftarInformasi.create.form.jenisInformasi = val.target.value
|
||||
}}
|
||||
/>
|
||||
<PPIDTextEditor
|
||||
showSubmit={false}
|
||||
onChange={(val) => {
|
||||
daftarInformasi.create.form.deskripsi = val
|
||||
}}
|
||||
/>
|
||||
<TextInput
|
||||
label="Tanggal Publikasi"
|
||||
placeholder="masukkan tanggal publikasi"
|
||||
onChange={(val) => {
|
||||
daftarInformasi.create.form.tanggal = val.target.value
|
||||
}}
|
||||
/>
|
||||
<Group>
|
||||
<Button
|
||||
bg={colors['blue-button']}
|
||||
onClick={submit}
|
||||
>Submit</Button>
|
||||
</Group>
|
||||
</Stack>
|
||||
</Paper>
|
||||
</Box>
|
||||
<Box>
|
||||
<ListDaftarInformasi />
|
||||
</Box>
|
||||
</SimpleGrid>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
function ListDaftarInformasi() {
|
||||
const listData = useProxy(stateDaftarInformasiPublik.daftarInformasi)
|
||||
useShallowEffect(() => {
|
||||
listData.findMany.load()
|
||||
}, [])
|
||||
if (!listData.findMany.data) return <Stack>
|
||||
{Array.from({ length: 10 }).map((v, k) => <Skeleton key={k} h={40} />)}
|
||||
</Stack>
|
||||
return (
|
||||
<Box>
|
||||
<Paper bg={colors['white-1']} p={'md'}>
|
||||
<Stack gap={"xs"}>
|
||||
<Title fw={"bold"} order={3}>List Daftar Informasi Publik Desa Darmasaba</Title>
|
||||
<Table
|
||||
suppressHydrationWarning
|
||||
striped
|
||||
highlightOnHover
|
||||
withTableBorder
|
||||
withColumnBorders
|
||||
bg={colors['white-1']}
|
||||
>
|
||||
<TableThead>
|
||||
<TableTr>
|
||||
<TableTh>
|
||||
No
|
||||
</TableTh>
|
||||
<TableTh>
|
||||
Jenis Informasi
|
||||
</TableTh>
|
||||
<TableTh>
|
||||
Deskripsi
|
||||
</TableTh>
|
||||
<TableTh>
|
||||
Tanggal Publikasi
|
||||
</TableTh>
|
||||
</TableTr>
|
||||
</TableThead>
|
||||
<TableTbody>
|
||||
{listData.findMany.data?.map((item) => (
|
||||
<TableTr key={item.id}>
|
||||
<TableTd>{item.nomor}</TableTd>
|
||||
<TableTd>{item.jenisInformasi}</TableTd>
|
||||
<TableTd dangerouslySetInnerHTML={{ __html: item.deskripsi }}></TableTd>
|
||||
<TableTd>{item.tanggal}</TableTd>
|
||||
</TableTr>
|
||||
))}
|
||||
</TableTbody>
|
||||
</Table>
|
||||
</Stack>
|
||||
</Paper>
|
||||
</Box>
|
||||
)
|
||||
}
|
||||
|
||||
export default Page;
|
||||
|
||||
64
src/app/admin/(dashboard)/ppid/dasar-hukum/create/page.tsx
Normal file
64
src/app/admin/(dashboard)/ppid/dasar-hukum/create/page.tsx
Normal file
@@ -0,0 +1,64 @@
|
||||
'use client'
|
||||
import { Box, Button, Group, Stack, Text } from '@mantine/core';
|
||||
import { useProxy } from 'valtio/utils';
|
||||
import stateDasarHukumPPID from '../../../_state/ppid/dasar_hukum/dasarHukum';
|
||||
import dynamic from 'next/dynamic';
|
||||
import colors from '@/con/colors';
|
||||
import { useShallowEffect } from '@mantine/hooks';
|
||||
|
||||
const PPIDTextEditor = dynamic(() => import('../../_com/PPIDTextEditor').then(mod => mod.PPIDTextEditor), {
|
||||
ssr: false,
|
||||
});
|
||||
function CreateDasarHukum() {
|
||||
const dasarHukumState = useProxy(stateDasarHukumPPID)
|
||||
useShallowEffect(() => {
|
||||
if (!dasarHukumState.findById.data) {
|
||||
dasarHukumState.findById.load(""); // biar masuk ke `findFirst` route kamu
|
||||
}
|
||||
}, []);
|
||||
|
||||
const submit = () => {
|
||||
if (dasarHukumState.findById.data?.judul && dasarHukumState.findById.data?.content) {
|
||||
dasarHukumState.update.save(dasarHukumState.findById.data)
|
||||
}
|
||||
}
|
||||
return (
|
||||
<Box>
|
||||
<Stack gap={"xs"}>
|
||||
<Text fw={"bold"}>Judul</Text>
|
||||
<PPIDTextEditor
|
||||
showSubmit={false}
|
||||
key={`judul-${dasarHukumState.findById.data?.id ?? 'new'}`}
|
||||
onChange={(val) => {
|
||||
if (dasarHukumState.findById.data) {
|
||||
dasarHukumState.findById.data.judul = val
|
||||
}
|
||||
}}
|
||||
initialContent={dasarHukumState.findById.data?.judul ?? ''}
|
||||
/>
|
||||
<Text fw={"bold"}>Content</Text>
|
||||
<PPIDTextEditor
|
||||
showSubmit={false}
|
||||
key={`content-${dasarHukumState.findById.data?.id ?? 'baru'}`}
|
||||
onChange={(val) => {
|
||||
if (dasarHukumState.findById.data) {
|
||||
dasarHukumState.findById.data.content = val
|
||||
}
|
||||
}}
|
||||
initialContent={dasarHukumState.findById.data?.content ?? ''}
|
||||
/>
|
||||
<Group>
|
||||
<Button
|
||||
bg={colors['blue-button']}
|
||||
onClick={submit}
|
||||
loading={dasarHukumState.update.loading}
|
||||
>
|
||||
Submit
|
||||
</Button>
|
||||
</Group>
|
||||
</Stack>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
export default CreateDasarHukum;
|
||||
40
src/app/admin/(dashboard)/ppid/dasar-hukum/listData/page.tsx
Normal file
40
src/app/admin/(dashboard)/ppid/dasar-hukum/listData/page.tsx
Normal file
@@ -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 <Stack>
|
||||
{Array.from({length: 10}).map((v, k) => <Skeleton key={k} h={40} />)}
|
||||
</Stack>
|
||||
|
||||
const dataArray = Array.isArray(dataList.findById.data)
|
||||
? dataList.findById.data
|
||||
: [dataList.findById.data];
|
||||
|
||||
return (
|
||||
<Paper bg={colors['white-1']} p={'md'} radius={10}>
|
||||
<Stack gap={"xs"}>
|
||||
<Title order={3}>List Dasar Hukum PPID</Title>
|
||||
{dataArray.map((item) => (
|
||||
<Box key={item.id}>
|
||||
<Text fw={"bold"}>Judul</Text>
|
||||
<Text dangerouslySetInnerHTML={{ __html: item.judul }}></Text>
|
||||
<Text fw={"bold"}>Content</Text>
|
||||
<Text dangerouslySetInnerHTML={{ __html: item.content }}></Text>
|
||||
</Box>
|
||||
))}
|
||||
</Stack>
|
||||
</Paper>
|
||||
);
|
||||
}
|
||||
|
||||
export default ListDataDasarHukum;
|
||||
@@ -1,11 +1,24 @@
|
||||
import React from 'react';
|
||||
'use client'
|
||||
import colors from '@/con/colors';
|
||||
import { Box, Paper, SimpleGrid, Stack, Title } from '@mantine/core';
|
||||
import CreateDasarHukum from './create/page';
|
||||
import ListDataDasarHukum from './listData/page';
|
||||
|
||||
function Page() {
|
||||
|
||||
return (
|
||||
<div>
|
||||
dasar-hukum
|
||||
</div>
|
||||
);
|
||||
<Stack gap={"xs"}>
|
||||
<SimpleGrid cols={{ base: 1, md: 2 }}>
|
||||
<Box>
|
||||
<Paper bg={colors['white-1']} p={'md'} radius={10}>
|
||||
<Title order={3}>Dasar Hukum PPID</Title>
|
||||
<CreateDasarHukum/>
|
||||
</Paper>
|
||||
</Box>
|
||||
<ListDataDasarHukum/>
|
||||
</SimpleGrid>
|
||||
</Stack>
|
||||
)
|
||||
}
|
||||
|
||||
export default Page;
|
||||
|
||||
@@ -0,0 +1,142 @@
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
'use client'
|
||||
import stateGrafikBerdasarkanJenisKelamin from '@/app/admin/(dashboard)/_state/ppid/indeks_kepuasan_masyarakat/grafikBerdasarkanJenisKelamin';
|
||||
import colors from '@/con/colors';
|
||||
import { Box, Button, Center, Flex, Paper, Stack, Text, TextInput, Title } from '@mantine/core';
|
||||
import { useShallowEffect } from '@mantine/hooks';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { Cell, Pie, PieChart } from 'recharts';
|
||||
import { useProxy } from 'valtio/utils';
|
||||
|
||||
function GrafikBerdasarkanJenisKelamin() {
|
||||
const grafikBerdasarkanJenisKelamin = useProxy(stateGrafikBerdasarkanJenisKelamin.grafikBerdasarkanJenisKelamin)
|
||||
const [donutData, setDonutData] = useState<any[]>([]);
|
||||
const [mounted, setMounted] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
setMounted(true);
|
||||
}, [])
|
||||
|
||||
const updateChartData = (data: any) => {
|
||||
if (data && data.length > 0) {
|
||||
const totalLaki = data.reduce((acc: number, cur: any) => acc + Number(cur.laki || 0), 0);
|
||||
const totalPerempuan = data.reduce((acc: number, cur: any) => acc + Number(cur.perempuan || 0), 0);
|
||||
|
||||
setDonutData([
|
||||
{ name: 'Laki-laki', value: totalLaki, color: colors['blue-button'], key: 'laki-laki' },
|
||||
{ name: 'Perempuan', value: totalPerempuan, color: '#FF6384', key: 'perempuan' }
|
||||
]);
|
||||
}
|
||||
};
|
||||
|
||||
useShallowEffect(() => {
|
||||
fetchData();
|
||||
}, []);
|
||||
|
||||
const fetchData = async () => {
|
||||
await grafikBerdasarkanJenisKelamin.findMany.load();
|
||||
if (grafikBerdasarkanJenisKelamin.findMany.data) {
|
||||
updateChartData(grafikBerdasarkanJenisKelamin.findMany.data);
|
||||
}
|
||||
};
|
||||
|
||||
const handleSubmit = async () => {
|
||||
try {
|
||||
// Simpan data baru
|
||||
await grafikBerdasarkanJenisKelamin.create.create();
|
||||
|
||||
// Muat ulang data
|
||||
await grafikBerdasarkanJenisKelamin.findMany.load();
|
||||
|
||||
// Update chart dengan data baru
|
||||
if (grafikBerdasarkanJenisKelamin.findMany.data) {
|
||||
updateChartData(grafikBerdasarkanJenisKelamin.findMany.data);
|
||||
}
|
||||
|
||||
// Reset form setelah submit
|
||||
grafikBerdasarkanJenisKelamin.create.form.laki = '';
|
||||
grafikBerdasarkanJenisKelamin.create.form.perempuan = '';
|
||||
} catch (error) {
|
||||
console.error("Error submitting data:", error);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Box>
|
||||
<Box py={15}>
|
||||
<Paper bg={colors['white-1']} w={{ base: '100%', md: '50%' }} p={'md'}>
|
||||
<Title order={3}>Grafik Hasil Kepuasan Masyarakat Terhadap Pelayanan Publik</Title>
|
||||
<TextInput
|
||||
w={{ base: '100%', md: '50%' }}
|
||||
label="Laki-laki"
|
||||
placeholder="masukkan jumlah laki-laki"
|
||||
value={grafikBerdasarkanJenisKelamin.create.form.laki}
|
||||
onChange={(val) => {
|
||||
grafikBerdasarkanJenisKelamin.create.form.laki = val.currentTarget.value;
|
||||
}}
|
||||
/>
|
||||
<TextInput
|
||||
w={{ base: '100%', md: '50%' }}
|
||||
label="Perempuan"
|
||||
type="number"
|
||||
placeholder="masukkan jumlah perempuan"
|
||||
value={grafikBerdasarkanJenisKelamin.create.form.perempuan}
|
||||
onChange={(val) => {
|
||||
grafikBerdasarkanJenisKelamin.create.form.perempuan = val.currentTarget.value;
|
||||
}}
|
||||
/>
|
||||
<Button
|
||||
mt={10}
|
||||
bg={colors['blue-button']}
|
||||
onClick={handleSubmit}
|
||||
>
|
||||
Submit
|
||||
</Button>
|
||||
</Paper>
|
||||
</Box>
|
||||
|
||||
{/* Chart */}
|
||||
<Box>
|
||||
<Paper bg={colors['white-1']} w={{ base: '100%', md: '50%' }} p={'md'}>
|
||||
<Stack>
|
||||
<Title pb={10} order={3}>Grafik Berdasarkan Jenis Kelamin Responden</Title>
|
||||
{mounted && donutData.length > 0 && (
|
||||
<Box style={{ width: '100%', height: 'auto', minHeight: 900 }}>
|
||||
<Center>
|
||||
<PieChart
|
||||
width={1000} height={400}
|
||||
data={donutData}
|
||||
>
|
||||
|
||||
<Pie
|
||||
dataKey="value"
|
||||
nameKey="name"
|
||||
data={donutData}
|
||||
innerRadius={120}
|
||||
outerRadius={230}
|
||||
label={true}
|
||||
>
|
||||
{donutData.map((entry, index) => (
|
||||
<Cell key={`cell-${index}`} fill={entry.color} />
|
||||
))}
|
||||
</Pie>
|
||||
</PieChart>
|
||||
</Center>
|
||||
<Flex gap={"md"} align={"center"}>
|
||||
<Box bg={'#FF6384'} w={20} h={20} />
|
||||
<Text>Perempuan: {donutData.find((entry) => entry.name === 'Perempuan')?.value}</Text>
|
||||
</Flex>
|
||||
<Flex gap={"md"} align={"center"}>
|
||||
<Box bg={colors['blue-button']} w={20} h={20} />
|
||||
<Text>Laki-laki: {donutData.find((entry) => entry.name === 'Laki-laki')?.value}</Text>
|
||||
</Flex>
|
||||
</Box>
|
||||
)}
|
||||
</Stack>
|
||||
</Paper>
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
export default GrafikBerdasarkanJenisKelamin;
|
||||
@@ -0,0 +1,173 @@
|
||||
'use client'
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
import stateGrafikResponden from '@/app/admin/(dashboard)/_state/ppid/indeks_kepuasan_masyarakat/grafikBerdasarkanResponden';
|
||||
import colors from '@/con/colors';
|
||||
import { Box, Button, Center, Flex, Group, Paper, Stack, Text, TextInput, Title } from '@mantine/core';
|
||||
import { useShallowEffect } from '@mantine/hooks';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { PieChart, Pie, Cell } from 'recharts';
|
||||
import { useProxy } from 'valtio/utils';
|
||||
|
||||
function GrafikBerdasarkanResponden() {
|
||||
const grafikBerdasarkanResponden = useProxy(stateGrafikResponden.grafikBerdasarkanResponden)
|
||||
const [donutData, setDonutData] = useState<any[]>([]);
|
||||
const [mounted, setMounted] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
setMounted(true);
|
||||
}, [])
|
||||
|
||||
const updateChartData = (data: any) => {
|
||||
if (data && data.length > 0) {
|
||||
const totalSangatBaik = data.reduce((acc: number, cur: any) => acc + Number(cur.sangatbaik || 0), 0);
|
||||
const totalBaik = data.reduce((acc: number, cur: any) => acc + Number(cur.baik || 0), 0);
|
||||
const totalKurangBaik = data.reduce((acc: number, cur: any) => acc + Number(cur.kurangbaik || 0), 0);
|
||||
const totalTidakBaik = data.reduce((acc: number, cur: any) => acc + Number(cur.tidakbaik || 0), 0);
|
||||
setDonutData([
|
||||
{ name: 'sangatbaik', value: totalSangatBaik, color: colors['blue-button'], key: 'sangatbaik' },
|
||||
{ name: 'baik', value: totalBaik, color: '#10A85AFF', key: 'baik' },
|
||||
{ name: 'kurangbaik', value: totalKurangBaik, color: '#B3AA12FF', key: 'kurangbaik' },
|
||||
{ name: 'tidakbaik', value: totalTidakBaik, color: '#B21313FF', key: 'tidakbaik' }
|
||||
]);
|
||||
}
|
||||
};
|
||||
|
||||
useShallowEffect(() => {
|
||||
fetchData();
|
||||
}, []);
|
||||
|
||||
const fetchData = async () => {
|
||||
await grafikBerdasarkanResponden.findMany.load();
|
||||
if (grafikBerdasarkanResponden.findMany.data) {
|
||||
updateChartData(grafikBerdasarkanResponden.findMany.data);
|
||||
}
|
||||
};
|
||||
|
||||
const handleSubmit = async () => {
|
||||
try {
|
||||
// Simpan data baru
|
||||
await grafikBerdasarkanResponden.create.create();
|
||||
|
||||
// Muat ulang data
|
||||
await grafikBerdasarkanResponden.findMany.load();
|
||||
|
||||
// Update chart dengan data baru
|
||||
if (grafikBerdasarkanResponden.findMany.data) {
|
||||
updateChartData(grafikBerdasarkanResponden.findMany.data);
|
||||
}
|
||||
|
||||
// Reset form setelah submit
|
||||
grafikBerdasarkanResponden.create.form.sangatbaik = '';
|
||||
grafikBerdasarkanResponden.create.form.baik = '';
|
||||
grafikBerdasarkanResponden.create.form.kurangbaik = '';
|
||||
grafikBerdasarkanResponden.create.form.tidakbaik = '';
|
||||
} catch (error) {
|
||||
console.error("Error submitting data:", error);
|
||||
}
|
||||
};
|
||||
return (
|
||||
<Box>
|
||||
<Box py={15}>
|
||||
<Paper bg={colors['white-1']} w={{ base: '100%', md: '50%' }} p={'md'}>
|
||||
<Stack gap={"xs"}>
|
||||
<Title order={3}>Grafik Berdasarkan Responden</Title>
|
||||
<TextInput
|
||||
w={{ base: '100%', md: '50%' }}
|
||||
label="Sangat Baik"
|
||||
value={grafikBerdasarkanResponden.create.form.sangatbaik}
|
||||
placeholder="masukkan jumlah respon sangat baik"
|
||||
onChange={(val) => {
|
||||
grafikBerdasarkanResponden.create.form.sangatbaik = val.currentTarget.value;
|
||||
}}
|
||||
/>
|
||||
<TextInput
|
||||
w={{ base: '100%', md: '50%' }}
|
||||
label="Baik"
|
||||
value={grafikBerdasarkanResponden.create.form.baik}
|
||||
placeholder="masukkan jumlah respon baik"
|
||||
onChange={(val) => {
|
||||
grafikBerdasarkanResponden.create.form.baik = val.currentTarget.value;
|
||||
}}
|
||||
/>
|
||||
<TextInput
|
||||
w={{ base: '100%', md: '50%' }}
|
||||
label="Kurang Baik"
|
||||
value={grafikBerdasarkanResponden.create.form.kurangbaik}
|
||||
placeholder="masukkan jumlah respon kurang baik"
|
||||
onChange={(val) => {
|
||||
grafikBerdasarkanResponden.create.form.kurangbaik = val.currentTarget.value;
|
||||
}}
|
||||
/>
|
||||
<TextInput
|
||||
w={{ base: '100%', md: '50%' }}
|
||||
label="Tidak Baik"
|
||||
value={grafikBerdasarkanResponden.create.form.tidakbaik}
|
||||
placeholder="masukkan jumlah respon tidak baik"
|
||||
onChange={(val) => {
|
||||
grafikBerdasarkanResponden.create.form.tidakbaik = val.currentTarget.value;
|
||||
}}
|
||||
/>
|
||||
<Group>
|
||||
<Button
|
||||
bg={colors['blue-button']}
|
||||
onClick={handleSubmit}
|
||||
>
|
||||
Submit
|
||||
</Button>
|
||||
</Group>
|
||||
</Stack>
|
||||
</Paper>
|
||||
</Box>
|
||||
|
||||
{/* Chart */}
|
||||
<Box>
|
||||
<Paper bg={colors['white-1']} w={{ base: '100%', md: '50%' }} p={'md'}>
|
||||
<Stack>
|
||||
<Title pb={10} order={3}>Grafik Berdasarkan Responden</Title>
|
||||
{mounted && donutData.length > 0 && (
|
||||
<Box style={{ width: '100%', height: 'auto', minHeight: 900 }}>
|
||||
<Center>
|
||||
<PieChart
|
||||
width={1000} height={400}
|
||||
data={donutData}
|
||||
>
|
||||
<Pie
|
||||
dataKey="value"
|
||||
nameKey="name"
|
||||
data={donutData}
|
||||
innerRadius={120}
|
||||
outerRadius={230}
|
||||
label={true}
|
||||
>
|
||||
{donutData.map((entry, index) => (
|
||||
<Cell key={`cell-${index}`} fill={entry.color} />
|
||||
))}
|
||||
</Pie>
|
||||
</PieChart>
|
||||
</Center>
|
||||
<Flex gap={"md"} align={"center"}>
|
||||
<Box bg={colors['blue-button']} w={20} h={20} />
|
||||
<Text>Sangat Baik: {donutData.find((entry) => entry.name === 'sangatbaik')?.value}</Text>
|
||||
</Flex>
|
||||
<Flex gap={"md"} align={"center"}>
|
||||
<Box bg={'#10A85AFF'} w={20} h={20} />
|
||||
<Text>Baik: {donutData.find((entry) => entry.name === 'baik')?.value}</Text>
|
||||
</Flex>
|
||||
<Flex gap={"md"} align={"center"}>
|
||||
<Box bg={'#B3AA12FF'} w={20} h={20} />
|
||||
<Text>Kurang Baik: {donutData.find((entry) => entry.name === 'kurangbaik')?.value}</Text>
|
||||
</Flex>
|
||||
<Flex gap={"md"} align={"center"}>
|
||||
<Box bg={'#B21313FF'} w={20} h={20} />
|
||||
<Text>Tidak Baik: {donutData.find((entry) => entry.name === 'tidakbaik')?.value}</Text>
|
||||
</Flex>
|
||||
</Box>
|
||||
)}
|
||||
</Stack>
|
||||
</Paper>
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
export default GrafikBerdasarkanResponden;
|
||||
@@ -0,0 +1,164 @@
|
||||
'use client'
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
import colors from '@/con/colors';
|
||||
import { Box, Button, Center, Flex, Group, Paper, Stack, Text, TextInput, Title } from '@mantine/core';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { useProxy } from 'valtio/utils';
|
||||
import stateGrafikBerdasarkanUmur from '@/app/admin/(dashboard)/_state/ppid/indeks_kepuasan_masyarakat/grafikBerdasarkanUmur';
|
||||
import { useShallowEffect } from '@mantine/hooks';
|
||||
import { PieChart, Pie, Cell } from 'recharts';
|
||||
|
||||
function GrafikBerdasarakanUmur() {
|
||||
const grafikBerdasarkanUmur = useProxy(stateGrafikBerdasarkanUmur.grafikBerdasarkanUmur)
|
||||
const [donutData, setDonutData] = useState<any[]>([]);
|
||||
const [mounted, setMounted] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
setMounted(true);
|
||||
}, []);
|
||||
|
||||
const updateChartData = (data: any) => {
|
||||
if (data && data.length > 0) {
|
||||
const totalRemaja = data.reduce((acc: number, cur: any) => acc + Number(cur.remaja || 0), 0);
|
||||
const totalDewasa = data.reduce((acc: number, cur: any) => acc + Number(cur.dewasa || 0), 0);
|
||||
const totalOrangtua = data.reduce((acc: number, cur: any) => acc + Number(cur.orangtua || 0), 0);
|
||||
const totalLansia = data.reduce((acc: number, cur: any) => acc + Number(cur.lansia || 0), 0);
|
||||
|
||||
setDonutData([
|
||||
{ name: 'Remaja', value: totalRemaja, color: colors['blue-button'], key: 'remaja' },
|
||||
{ name: 'Dewasa', value: totalDewasa, color: '#D32711FF', key: 'dewasa' },
|
||||
{ name: 'Orangtua', value: totalOrangtua, color: '#B46B04FF', key: 'orangtua' },
|
||||
{ name: 'Lansia', value: totalLansia, color: '#038617FF', key: 'lansia' }
|
||||
]);
|
||||
}
|
||||
};
|
||||
|
||||
useShallowEffect(() => {
|
||||
fetchData();
|
||||
}, []);
|
||||
|
||||
const fetchData = async () => {
|
||||
await grafikBerdasarkanUmur.findMany.load();
|
||||
if (grafikBerdasarkanUmur.findMany.data) {
|
||||
updateChartData(grafikBerdasarkanUmur.findMany.data);
|
||||
}
|
||||
}
|
||||
|
||||
const handleSubmit = async () => {
|
||||
try {
|
||||
await grafikBerdasarkanUmur.create.create();
|
||||
await grafikBerdasarkanUmur.findMany.load();
|
||||
if (grafikBerdasarkanUmur.findMany.data) {
|
||||
updateChartData(grafikBerdasarkanUmur.findMany.data);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error submitting data:", error);
|
||||
}
|
||||
}
|
||||
return (
|
||||
<Box>
|
||||
<Box py={15}>
|
||||
<Paper bg={colors['white-1']} w={{ base: '100%', md: '50%' }} p={'md'}>
|
||||
<Stack gap={"xs"}>
|
||||
<Title order={3}>Grafik Berdasarkan Umur Responden</Title>
|
||||
<TextInput
|
||||
w={{ base: '100%', md: '50%' }}
|
||||
label="Remaja"
|
||||
placeholder="masukkan jumlah responden remaja"
|
||||
value={grafikBerdasarkanUmur.create.form.remaja}
|
||||
onChange={(val) => {
|
||||
grafikBerdasarkanUmur.create.form.remaja = val.currentTarget.value;
|
||||
}}
|
||||
/>
|
||||
<TextInput
|
||||
w={{ base: '100%', md: '50%' }}
|
||||
label="Dewasa"
|
||||
placeholder="masukkan jumlah responden dewasa"
|
||||
value={grafikBerdasarkanUmur.create.form.dewasa}
|
||||
onChange={(val) => {
|
||||
grafikBerdasarkanUmur.create.form.dewasa = val.currentTarget.value;
|
||||
}}
|
||||
/>
|
||||
<TextInput
|
||||
w={{ base: '100%', md: '50%' }}
|
||||
label="Orangtua"
|
||||
placeholder="masukkan jumlah responden orangtua"
|
||||
value={grafikBerdasarkanUmur.create.form.orangtua}
|
||||
onChange={(val) => {
|
||||
grafikBerdasarkanUmur.create.form.orangtua = val.currentTarget.value;
|
||||
}}
|
||||
/>
|
||||
<TextInput
|
||||
w={{ base: '100%', md: '50%' }}
|
||||
label="Lansia"
|
||||
placeholder="masukkan jumlah responden lansia"
|
||||
value={grafikBerdasarkanUmur.create.form.lansia}
|
||||
onChange={(val) => {
|
||||
grafikBerdasarkanUmur.create.form.lansia = val.currentTarget.value;
|
||||
}}
|
||||
/>
|
||||
<Group>
|
||||
<Button
|
||||
mt={10}
|
||||
bg={colors['blue-button']}
|
||||
onClick={handleSubmit}
|
||||
>
|
||||
Submit
|
||||
</Button>
|
||||
</Group>
|
||||
</Stack>
|
||||
</Paper>
|
||||
</Box>
|
||||
|
||||
{/* Chart */}
|
||||
<Box>
|
||||
<Paper bg={colors['white-1']} w={{ base: '100%', md: '50%' }} p={'md'}>
|
||||
<Stack>
|
||||
<Title pb={10} order={3}>Grafik Berdasarkan Umur Responden</Title>
|
||||
{mounted && donutData.length > 0 && (
|
||||
<Box style={{ width: '100%', height: 'auto', minHeight: 900 }}>
|
||||
<Center>
|
||||
<PieChart
|
||||
width={1000} height={400}
|
||||
data={donutData}
|
||||
>
|
||||
<Pie
|
||||
dataKey="value"
|
||||
nameKey="name"
|
||||
data={donutData}
|
||||
innerRadius={120}
|
||||
outerRadius={230}
|
||||
label={true}
|
||||
>
|
||||
{donutData.map((entry, index) => (
|
||||
<Cell key={`cell-${index}`} fill={entry.color} />
|
||||
))}
|
||||
</Pie>
|
||||
</PieChart>
|
||||
</Center>
|
||||
<Flex gap={"md"} align={"center"}>
|
||||
<Box bg={colors['blue-button']} w={20} h={20} />
|
||||
<Text>17 - 25 tahun: {donutData.find((entry) => entry.name === 'remaja')?.value}</Text>
|
||||
</Flex>
|
||||
<Flex gap={"md"} align={"center"}>
|
||||
<Box bg={'#D32711FF'} w={20} h={20} />
|
||||
<Text>26 - 45 tahun: {donutData.find((entry) => entry.name === 'dewasa')?.value}</Text>
|
||||
</Flex>
|
||||
<Flex gap={"md"} align={"center"}>
|
||||
<Box bg={'#B46B04FF'} w={20} h={20} />
|
||||
<Text>46 - 60 tahun: {donutData.find((entry) => entry.name === 'orangtua')?.value}</Text>
|
||||
</Flex>
|
||||
<Flex gap={"md"} align={"center"}>
|
||||
<Box bg={'#038617FF'} w={20} h={20} />
|
||||
<Text>di atas 60 tahun: {donutData.find((entry) => entry.name === 'lansia')?.value}</Text>
|
||||
</Flex>
|
||||
</Box>
|
||||
)}
|
||||
</Stack>
|
||||
</Paper>
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
export default GrafikBerdasarakanUmur;
|
||||
@@ -0,0 +1,96 @@
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
'use client'
|
||||
import stateGrafikHasilKepuasanMasyarakat from '@/app/admin/(dashboard)/_state/ppid/indeks_kepuasan_masyarakat/grafikHasilKepuasan';
|
||||
import colors from '@/con/colors';
|
||||
import { Box, Button, Paper, Stack, TextInput, Title } from '@mantine/core';
|
||||
import { useMediaQuery, useShallowEffect } from '@mantine/hooks';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { Bar, BarChart, Legend, Tooltip, XAxis, YAxis } from 'recharts';
|
||||
import { useProxy } from 'valtio/utils';
|
||||
|
||||
function GrafikHasilKepuasan() {
|
||||
const grafikHasilKepuasan = useProxy(stateGrafikHasilKepuasanMasyarakat.grafikHasilKepuasanMasyarakat)
|
||||
const [chartData, setChartData] = useState<any[]>([]);
|
||||
const [mounted, setMounted] = useState(false);
|
||||
const isTablet = useMediaQuery('(max-width: 1024px)')
|
||||
const isMobile = useMediaQuery('(max-width: 768px)')
|
||||
|
||||
useEffect(() => {
|
||||
setMounted(true);
|
||||
}, [])
|
||||
|
||||
useShallowEffect(() => {
|
||||
const fetchData = async () => {
|
||||
await grafikHasilKepuasan.findMany.load();
|
||||
if (grafikHasilKepuasan.findMany.data && grafikHasilKepuasan.findMany.data.length > 0) {
|
||||
setChartData(grafikHasilKepuasan.findMany.data);
|
||||
}
|
||||
};
|
||||
fetchData();
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<Box>
|
||||
<Box py={15}>
|
||||
<Paper bg={colors['white-1']} w={{ base: '100%', md: '50%' }} p={'md'}>
|
||||
<Stack>
|
||||
<Title order={3}>Grafik Hasil Kepuasan Masyarakat Terhadap Pelayanan Publik</Title>
|
||||
<TextInput
|
||||
w={{ base: '100%', md: '50%' }}
|
||||
label="Label"
|
||||
placeholder="masukkan label"
|
||||
value={grafikHasilKepuasan.create.form.label}
|
||||
onChange={(val) => {
|
||||
grafikHasilKepuasan.create.form.label = val.currentTarget.value;
|
||||
}}
|
||||
/>
|
||||
<TextInput
|
||||
w={{ base: '100%', md: '50%' }}
|
||||
label="Jumlah Kepuasan"
|
||||
type="number"
|
||||
placeholder="masukkan jumlah kepuasan"
|
||||
value={grafikHasilKepuasan.create.form.kepuasan}
|
||||
onChange={(val) => {
|
||||
grafikHasilKepuasan.create.form.kepuasan = val.currentTarget.value;
|
||||
}}
|
||||
/>
|
||||
<Button
|
||||
mt={10}
|
||||
bg={colors['blue-button']}
|
||||
onClick={async () => {
|
||||
await grafikHasilKepuasan.create.create();
|
||||
await grafikHasilKepuasan.findMany.load();
|
||||
if (grafikHasilKepuasan.findMany.data) {
|
||||
setChartData(grafikHasilKepuasan.findMany.data);
|
||||
}
|
||||
}}
|
||||
>
|
||||
Submit
|
||||
</Button>
|
||||
</Stack>
|
||||
</Paper>
|
||||
</Box>
|
||||
|
||||
{/* Chart */}
|
||||
<Box style={{ width: '100%', minWidth: 300, height: 400, minHeight: 300 }}>
|
||||
<Paper style={{ width: '100%', minWidth: 300, height: 400, minHeight: 300 }} bg={colors['white-1']} p={'md'}>
|
||||
<Stack gap={"xs"}>
|
||||
<Title pb={10} order={3}>Data Kepuasan Masyarakat</Title>
|
||||
{mounted && chartData.length > 0 && (
|
||||
<BarChart width={isMobile ? 300 : isTablet ? 600 : 900} height={380} data={chartData} >
|
||||
<XAxis dataKey="label" />
|
||||
<YAxis />
|
||||
<Tooltip />
|
||||
<Legend />
|
||||
<Bar dataKey="kepuasan" fill={colors['blue-button']} name="Kepuasan" />
|
||||
</BarChart>
|
||||
)}
|
||||
</Stack>
|
||||
</Paper>
|
||||
</Box>
|
||||
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
export default GrafikHasilKepuasan;
|
||||
@@ -1,10 +1,45 @@
|
||||
import { Stack, Tabs, TabsList, TabsPanel, TabsTab, Title } from '@mantine/core';
|
||||
import React from 'react';
|
||||
import colors from '@/con/colors';
|
||||
import GrafikHasilKepuasan from './_ui/grafik_hasil_kepuasan_masyarakat/page';
|
||||
import GrafikBerdasarkanJenisKelamin from './_ui/grafik_berdasarkan_jenis_kelamin_responden/page';
|
||||
import GrafikBerdasarkanResponden from './_ui/grafik_berdasarkan_responden/page';
|
||||
import GrafikBerdasarakanUmur from './_ui/grafik_berdasarkan_umur/page';
|
||||
|
||||
function Page() {
|
||||
return (
|
||||
<div>
|
||||
ikm-desa-darmasaba
|
||||
</div>
|
||||
<Stack >
|
||||
<Title order={3}>Indeks Kepuasan Masyarakat (IKM) Desa Darmasaba</Title>
|
||||
<Tabs color={colors['blue-button']} variant='pills' defaultValue={"Grafik Hasil Kepuasan Masyarakat Terhadap Pelayanan Publik"}>
|
||||
<TabsList p={"xs"} bg={"#BBC8E7FF"}>
|
||||
<TabsTab value="Grafik Hasil Kepuasan Masyarakat Terhadap Pelayanan Publik">
|
||||
Grafik Hasil Kepuasan Masyarakat Terhadap Pelayanan Publik
|
||||
</TabsTab>
|
||||
<TabsTab value="Grafik Berdasarkan Jenis Kelamin Responden">
|
||||
Grafik Berdasarkan Jenis Kelamin Responden
|
||||
</TabsTab>
|
||||
<TabsTab value="Grafik Berdasarkan Pilihan Responden">
|
||||
Grafik Berdasarkan Pilihan Responden
|
||||
</TabsTab>
|
||||
<TabsTab value="Grafik Berdasarkan Umur Responden">
|
||||
Grafik Berdasarkan Umur Responden
|
||||
</TabsTab>
|
||||
</TabsList>
|
||||
|
||||
<TabsPanel value="Grafik Hasil Kepuasan Masyarakat Terhadap Pelayanan Publik">
|
||||
<GrafikHasilKepuasan/>
|
||||
</TabsPanel>
|
||||
<TabsPanel value="Grafik Berdasarkan Jenis Kelamin Responden">
|
||||
<GrafikBerdasarkanJenisKelamin/>
|
||||
</TabsPanel>
|
||||
<TabsPanel value="Grafik Berdasarkan Pilihan Responden">
|
||||
<GrafikBerdasarkanResponden/>
|
||||
</TabsPanel>
|
||||
<TabsPanel value="Grafik Berdasarkan Umur Responden">
|
||||
<GrafikBerdasarakanUmur/>
|
||||
</TabsPanel>
|
||||
</Tabs>
|
||||
</Stack>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,11 +1,57 @@
|
||||
import React from 'react';
|
||||
'use client'
|
||||
import colors from '@/con/colors';
|
||||
import { Box, Paper, Skeleton, Stack, Table, TableTbody, TableTd, TableTh, TableThead, TableTr, Title } from '@mantine/core';
|
||||
import { useProxy } from 'valtio/utils';
|
||||
import { useShallowEffect } from '@mantine/hooks';
|
||||
import statepermohonanInformasiPublikForm from '../../_state/ppid/permohonan_informasi_publik/permohonanInformasiPublik';
|
||||
|
||||
function Page() {
|
||||
const permohonanInformasiPublikState = useProxy(statepermohonanInformasiPublikForm)
|
||||
useShallowEffect(() => {
|
||||
permohonanInformasiPublikState.statepermohonanInformasiPublik.findMany.load()
|
||||
}, [])
|
||||
if (!permohonanInformasiPublikState.statepermohonanInformasiPublik.findMany.data) return <Stack pos={"relative"} bg={colors.Bg} py={"xl"} gap={"22"}>
|
||||
{Array.from({ length: 10 }).map((v, k) => <Skeleton key={k} h={40} />)}
|
||||
</Stack>
|
||||
|
||||
return (
|
||||
<div>
|
||||
permohonan-informasi-publik
|
||||
</div>
|
||||
<Box py={5}>
|
||||
<Paper bg={colors['white-1']} p={'md'}>
|
||||
<Stack gap={"xs"}>
|
||||
<Title order={3}>Permohonan Informasi Publik</Title>
|
||||
<Box p={"xl"}>
|
||||
<Table striped withRowBorders withColumnBorders withTableBorder>
|
||||
<TableThead>
|
||||
<TableTr>
|
||||
<TableTh>No</TableTh>
|
||||
<TableTh>Nama</TableTh>
|
||||
<TableTh>NIK</TableTh>
|
||||
<TableTh>Telepon</TableTh>
|
||||
<TableTh>Email</TableTh>
|
||||
<TableTh>Jenis Informasi</TableTh>
|
||||
<TableTh>Cara Memperoleh Informasi</TableTh>
|
||||
<TableTh>Cara Memperoleh Salinan Informasi</TableTh>
|
||||
</TableTr>
|
||||
</TableThead>
|
||||
<TableTbody>
|
||||
{permohonanInformasiPublikState.statepermohonanInformasiPublik.findMany.data?.map((item, index) => (
|
||||
<TableTr key={item.id}>
|
||||
<TableTd>{index + 1}</TableTd>
|
||||
<TableTd>{item.name}</TableTd>
|
||||
<TableTd>{item.nik}</TableTd>
|
||||
<TableTd>{item.notelp}</TableTd>
|
||||
<TableTd>{item.email}</TableTd>
|
||||
<TableTd>{item.jenisInformasiDiminta?.name}</TableTd>
|
||||
<TableTd>{item.caraMemperolehInformasi?.name}</TableTd>
|
||||
<TableTd>{item.caraMemperolehSalinanInformasi?.name}</TableTd>
|
||||
</TableTr>
|
||||
))}
|
||||
</TableTbody>
|
||||
</Table> </Box>
|
||||
</Stack>
|
||||
</Paper>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
export default Page;
|
||||
export default Page;
|
||||
@@ -1,11 +1,49 @@
|
||||
import React from 'react';
|
||||
'use client'
|
||||
import colors from '@/con/colors';
|
||||
import { Box, Paper, Skeleton, Stack, Table, TableTbody, TableTd, TableTh, TableThead, TableTr, Title } from '@mantine/core';
|
||||
import { useShallowEffect } from '@mantine/hooks';
|
||||
import { useProxy } from 'valtio/utils';
|
||||
import statePermohonanKeberatan from '../../_state/ppid/permohonan_keberatan_informasi_publik/permohonanKeberatanInformasi';
|
||||
|
||||
function Page() {
|
||||
const listState = useProxy(statePermohonanKeberatan)
|
||||
useShallowEffect(() => {
|
||||
listState.findMany.load()
|
||||
}, [])
|
||||
|
||||
if (!listState.findMany.data) return <Stack>
|
||||
{Array.from({ length: 10 }).map((v, k) => <Skeleton key={k} h={40} />)}
|
||||
</Stack>
|
||||
return (
|
||||
<div>
|
||||
permohonan-keberatan-informasi-publik
|
||||
</div>
|
||||
<Box py={10}>
|
||||
<Paper bg={colors['white-1']} p={'md'}>
|
||||
<Stack gap={"xs"}>
|
||||
<Title order={3}>Permohonan Keberatan Informasi Publik</Title>
|
||||
<Table striped withRowBorders withColumnBorders withTableBorder>
|
||||
<TableThead>
|
||||
<TableTr>
|
||||
<TableTh>No</TableTh>
|
||||
<TableTh>Nama</TableTh>
|
||||
<TableTh>Email</TableTh>
|
||||
<TableTh>Telepon</TableTh>
|
||||
<TableTh>Alasan</TableTh>
|
||||
</TableTr>
|
||||
</TableThead>
|
||||
<TableTbody>
|
||||
{listState.findMany.data?.map((item, index) => (
|
||||
<TableTr key={item.id}>
|
||||
<TableTd>{index + 1}</TableTd>
|
||||
<TableTd>{item.name}</TableTd>
|
||||
<TableTd>{item.email}</TableTd>
|
||||
<TableTd>{item.notelp}</TableTd>
|
||||
<TableTd dangerouslySetInnerHTML={{ __html: item.alasan }} />
|
||||
</TableTr>
|
||||
))}
|
||||
</TableTbody>
|
||||
</Table>
|
||||
</Stack>
|
||||
</Paper>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
export default Page;
|
||||
|
||||
10
src/app/admin/(dashboard)/ppid/profile-ppid/_com/biodata.ts
Normal file
10
src/app/admin/(dashboard)/ppid/profile-ppid/_com/biodata.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
const biodata = {
|
||||
id: "1",
|
||||
name: "<p>I.B Surya Prabhawa Manuaba, S.H., M.H.</p>",
|
||||
biodata: "<h2>Biodata</h2> <p>....</p>",
|
||||
riwayat: "<h2>Riwayat Karir</h2> <ul>...</ul>",
|
||||
pengalaman: "<h2>Pengalaman Organisasi</h2> <ul>...</ul>",
|
||||
unggulan: "<h2>Program Kerja Unggulan</h2> <h3>...</h3>",
|
||||
}
|
||||
|
||||
export default biodata
|
||||
76
src/app/admin/(dashboard)/ppid/profile-ppid/biodata/page.tsx
Normal file
76
src/app/admin/(dashboard)/ppid/profile-ppid/biodata/page.tsx
Normal file
@@ -0,0 +1,76 @@
|
||||
'use client'
|
||||
import { Box, Group, Text } from '@mantine/core';
|
||||
import { useState } from 'react';
|
||||
|
||||
import ApiFetch from '@/lib/api-fetch';
|
||||
import { Dropzone, MIME_TYPES } from '@mantine/dropzone';
|
||||
import { IconPhoto, IconUpload, IconX } from '@tabler/icons-react';
|
||||
import { useProxy } from 'valtio/utils';
|
||||
import stateProfilePPID from '../../../_state/ppid/profile_ppid/profile_PPID';
|
||||
import { PPIDTextEditor } from '../../_com/PPIDTextEditor';
|
||||
|
||||
function Biodata() {
|
||||
const biodataState = useProxy(stateProfilePPID)
|
||||
const [loading, setLoading] = useState(false);
|
||||
|
||||
return (<Box>
|
||||
<Text fw={"bold"}>Biodata</Text>
|
||||
<Dropzone
|
||||
mb={20}
|
||||
onDrop={async (droppedFiles) => {
|
||||
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}
|
||||
>
|
||||
<Group justify="center" gap="md" mih={150} style={{ pointerEvents: 'none' }}>
|
||||
<Dropzone.Accept>
|
||||
<IconUpload size={50} stroke={1.5} />
|
||||
</Dropzone.Accept>
|
||||
<Dropzone.Reject>
|
||||
<IconX size={50} stroke={1.5} />
|
||||
</Dropzone.Reject>
|
||||
<Dropzone.Idle>
|
||||
<IconPhoto size={50} stroke={1.5} />
|
||||
</Dropzone.Idle>
|
||||
|
||||
<div>
|
||||
<Text size="xl" inline>
|
||||
Drag & drop gambar di sini atau klik untuk pilih file
|
||||
</Text>
|
||||
<Text size="sm" c="dimmed" inline mt={7}>
|
||||
Maksimal ukuran file 5MB. Format: JPG, PNG, WebP
|
||||
</Text>
|
||||
</div>
|
||||
</Group>
|
||||
</Dropzone>
|
||||
|
||||
|
||||
|
||||
<PPIDTextEditor
|
||||
key={biodataState.findById.data?.id ?? 'new'}
|
||||
showSubmit={false}
|
||||
onChange={(val) => {
|
||||
if (biodataState.findById.data) {
|
||||
biodataState.findById.data.biodata = val;
|
||||
}
|
||||
}}
|
||||
initialContent={biodataState.findById.data?.biodata ?? ''}
|
||||
/>
|
||||
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
export default Biodata;
|
||||
65
src/app/admin/(dashboard)/ppid/profile-ppid/listPage.tsx
Normal file
65
src/app/admin/(dashboard)/ppid/profile-ppid/listPage.tsx
Normal file
@@ -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 <Stack>
|
||||
{Array.from({ length: 10 }).map((v, k) => <Skeleton key={k} h={40} />)}
|
||||
</Stack>
|
||||
|
||||
const dataArray = Array.isArray(allList.findById.data)
|
||||
? allList.findById.data
|
||||
: [allList.findById.data];
|
||||
|
||||
return (
|
||||
<Paper bg={colors['white-1']} p={'md'}>
|
||||
<Stack gap={"xs"}>
|
||||
<Title order={3}>List Profile PPID</Title>
|
||||
{dataArray.map((item) => (
|
||||
<Box key={item.id}>
|
||||
{item.imageUrl && (
|
||||
<Box mb={20}>
|
||||
<Text fw={"bold"} mb={5}>Preview Gambar:</Text>
|
||||
<Image
|
||||
src={item.imageUrl}
|
||||
alt="Profile"
|
||||
w={200}
|
||||
/>
|
||||
</Box>
|
||||
)}
|
||||
<Box>
|
||||
<Text fw={"bold"}>Nama</Text>
|
||||
<Text dangerouslySetInnerHTML={{ __html: item.name }}></Text>
|
||||
</Box>
|
||||
<Box>
|
||||
<Text fw={"bold"}>Biodata</Text>
|
||||
<Text dangerouslySetInnerHTML={{ __html: item.biodata }}></Text>
|
||||
</Box>
|
||||
<Box>
|
||||
<Text fw={"bold"}>Riwayat</Text>
|
||||
<Text dangerouslySetInnerHTML={{ __html: item.riwayat }}></Text>
|
||||
</Box>
|
||||
<Box>
|
||||
<Text fw={"bold"}>Pengalaman</Text>
|
||||
<Text dangerouslySetInnerHTML={{ __html: item.pengalaman }}></Text>
|
||||
</Box>
|
||||
<Box>
|
||||
<Text fw={"bold"}>Program Kerja Unggulan</Text>
|
||||
<Text dangerouslySetInnerHTML={{ __html: item.unggulan }}></Text>
|
||||
</Box>
|
||||
</Box>
|
||||
))}
|
||||
</Stack>
|
||||
</Paper>
|
||||
)
|
||||
}
|
||||
|
||||
export default ProfileList;
|
||||
@@ -1,11 +1,79 @@
|
||||
import React from 'react';
|
||||
'use client'
|
||||
import colors from '@/con/colors';
|
||||
import { Box, Button, Group, Paper, SimpleGrid, Stack, Text, TextInput, Title } from '@mantine/core';
|
||||
import Biodata from './biodata/page';
|
||||
import PengalamanOrganisasi from './pengalaman_organisasi/page';
|
||||
import RiwayatKarir from './riwayat_karir/page';
|
||||
import ProgramKerjaUnggulan from './program_kerja_unggulan/page';
|
||||
import { useProxy } from 'valtio/utils';
|
||||
import stateProfilePPID from '../../_state/ppid/profile_ppid/profile_PPID';
|
||||
import { useShallowEffect } from '@mantine/hooks';
|
||||
import ProfileList from './listPage';
|
||||
|
||||
|
||||
function Page() {
|
||||
return (
|
||||
<div>
|
||||
profile-ppid
|
||||
</div>
|
||||
<Box>
|
||||
<SimpleGrid cols={{ base: 1, md: 2 }}>
|
||||
<ProfileCreate />
|
||||
<ProfileList />
|
||||
</SimpleGrid>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
export default Page;
|
||||
function ProfileCreate() {
|
||||
const allState = useProxy(stateProfilePPID)
|
||||
|
||||
// Initialize data if it doesn't exist
|
||||
useShallowEffect(() => {
|
||||
if (!allState.findById.data) {
|
||||
allState.findById.initialize()
|
||||
}
|
||||
}, [])
|
||||
|
||||
const submit = () => {
|
||||
if (
|
||||
allState.findById.data?.name &&
|
||||
allState.findById.data?.biodata &&
|
||||
allState.findById.data?.riwayat &&
|
||||
allState.findById.data?.pengalaman &&
|
||||
allState.findById.data?.unggulan
|
||||
) {
|
||||
allState.update.save(allState.findById.data)
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<Paper bg={colors['white-1']} p={'md'} radius={10}>
|
||||
<Stack gap={"xs"}>
|
||||
<Title order={3}>Profile PPID</Title>
|
||||
<TextInput
|
||||
label={<Text fw={"bold"}>Nama Perbekel</Text>}
|
||||
placeholder="masukkan nama perbekel"
|
||||
value={allState.findById.data?.name || ''}
|
||||
onChange={(val) => {
|
||||
if (allState.findById.data) {
|
||||
allState.findById.data.name = val.currentTarget.value
|
||||
}
|
||||
}}
|
||||
/>
|
||||
<Biodata />
|
||||
<RiwayatKarir />
|
||||
<PengalamanOrganisasi />
|
||||
<ProgramKerjaUnggulan />
|
||||
<Group>
|
||||
<Button
|
||||
bg={colors['blue-button']}
|
||||
onClick={submit}
|
||||
loading={allState.update.loading}
|
||||
>
|
||||
Submit
|
||||
</Button>
|
||||
</Group>
|
||||
</Stack>
|
||||
</Paper>
|
||||
)
|
||||
}
|
||||
|
||||
export default Page;
|
||||
@@ -0,0 +1,26 @@
|
||||
'use client'
|
||||
import { Box, Text } from '@mantine/core';
|
||||
import React from 'react';
|
||||
import { useProxy } from 'valtio/utils';
|
||||
import stateProfilePPID from '../../../_state/ppid/profile_ppid/profile_PPID';
|
||||
import { PPIDTextEditor } from '../../_com/PPIDTextEditor';
|
||||
|
||||
function PengalamanOrganisasi() {
|
||||
const pengalamanOrganisasiState = useProxy(stateProfilePPID)
|
||||
return (<Box>
|
||||
<Text fw={"bold"}>Pengalaman Organisasi</Text>
|
||||
<PPIDTextEditor
|
||||
key={pengalamanOrganisasiState.findById.data?.id ?? 'new'}
|
||||
showSubmit={false}
|
||||
onChange={(val) => {
|
||||
if (pengalamanOrganisasiState.findById.data) {
|
||||
pengalamanOrganisasiState.findById.data.pengalaman = val;
|
||||
}
|
||||
}}
|
||||
initialContent={pengalamanOrganisasiState.findById.data?.pengalaman ?? ''}
|
||||
/>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
export default PengalamanOrganisasi;
|
||||
@@ -0,0 +1,26 @@
|
||||
'use client'
|
||||
import { Box, Text } from '@mantine/core';
|
||||
import React from 'react';
|
||||
import { useProxy } from 'valtio/utils';
|
||||
import stateProfilePPID from '../../../_state/ppid/profile_ppid/profile_PPID';
|
||||
import { PPIDTextEditor } from '../../_com/PPIDTextEditor';
|
||||
|
||||
function ProgramKerjaUnggulan() {
|
||||
const programKerjaUnggulanState = useProxy(stateProfilePPID)
|
||||
return (<Box>
|
||||
<Text fw={"bold"}>Program Kerja Unggulan</Text>
|
||||
<PPIDTextEditor
|
||||
key={programKerjaUnggulanState.findById.data?.id ?? 'new'}
|
||||
showSubmit={false}
|
||||
onChange={(val) => {
|
||||
if (programKerjaUnggulanState.findById.data) {
|
||||
programKerjaUnggulanState.findById.data.unggulan = val;
|
||||
}
|
||||
}}
|
||||
initialContent={programKerjaUnggulanState.findById.data?.unggulan ?? ''}
|
||||
/>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
export default ProgramKerjaUnggulan;
|
||||
@@ -0,0 +1,33 @@
|
||||
'use client';
|
||||
|
||||
import { Box, Text } from '@mantine/core';
|
||||
import React from 'react';
|
||||
import { useProxy } from 'valtio/utils';
|
||||
import dynamic from 'next/dynamic';
|
||||
import stateProfilePPID from '../../../_state/ppid/profile_ppid/profile_PPID';
|
||||
|
||||
// ini penting
|
||||
const PPIDTextEditor = dynamic(() => import('../../_com/PPIDTextEditor').then(mod => mod.PPIDTextEditor), {
|
||||
ssr: false, // disable server side rendering
|
||||
});
|
||||
function RiwayatKarir() {
|
||||
const riwayatKarirState = useProxy(stateProfilePPID);
|
||||
|
||||
return (
|
||||
<Box>
|
||||
<Text fw={"bold"}>Riwayat Karir</Text>
|
||||
<PPIDTextEditor
|
||||
key={riwayatKarirState.findById.data?.id ?? 'new'}
|
||||
showSubmit={false}
|
||||
onChange={(val) => {
|
||||
if (riwayatKarirState.findById.data) {
|
||||
riwayatKarirState.findById.data.riwayat = val;
|
||||
}
|
||||
}}
|
||||
initialContent={riwayatKarirState.findById.data?.riwayat ?? ''}
|
||||
/>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
export default RiwayatKarir;
|
||||
@@ -0,0 +1,26 @@
|
||||
'use client'
|
||||
import { Box, Text } from '@mantine/core';
|
||||
import { useProxy } from 'valtio/utils';
|
||||
import { PPIDTextEditor } from '../../_com/PPIDTextEditor';
|
||||
import stateVisiMisiPPID from '../../../_state/ppid/visi_misi_ppid/visimisiPPID';
|
||||
|
||||
function MisiPPID() {
|
||||
const misiState = useProxy(stateVisiMisiPPID)
|
||||
return (
|
||||
<Box>
|
||||
<Text fw={"bold"}>Misi PPID</Text>
|
||||
<PPIDTextEditor
|
||||
key={misiState.findById.data?.id ?? 'new'}
|
||||
showSubmit={false}
|
||||
onChange={(val) => {
|
||||
if(misiState.findById.data){
|
||||
misiState.findById.data.misi = val
|
||||
}
|
||||
}}
|
||||
initialContent={misiState.findById.data?.misi ?? ''}
|
||||
/>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
export default MisiPPID;
|
||||
@@ -1,11 +1,83 @@
|
||||
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 stateVisiMisiPPID from '../../_state/ppid/visi_misi_ppid/visimisiPPID';
|
||||
import MisiPPID from './misiPPID/page';
|
||||
import VisiPPID from './visiPPID/page';
|
||||
|
||||
function Page() {
|
||||
return (
|
||||
<div>
|
||||
visi-misi-ppid
|
||||
</div>
|
||||
<Box>
|
||||
<SimpleGrid cols={{ base: 1, md: 2 }}>
|
||||
<VisiMisiPPIDCreate />
|
||||
<VisiMisiPPIDList />
|
||||
</SimpleGrid>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
function VisiMisiPPIDCreate() {
|
||||
const visiMisi = useProxy(stateVisiMisiPPID)
|
||||
|
||||
useShallowEffect(() => {
|
||||
if(!visiMisi.findById.data){
|
||||
visiMisi.findById.initialize()
|
||||
}
|
||||
}, [])
|
||||
|
||||
const submit = () => {
|
||||
if(visiMisi.findById.data?.misi && visiMisi.findById.data?.visi){
|
||||
visiMisi.update.save(visiMisi.findById.data)
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<Paper bg={colors['white-1']} p={'md'} radius={10}>
|
||||
<Stack gap={"xs"}>
|
||||
<Title order={3}>Visi Misi PPID</Title>
|
||||
<VisiPPID />
|
||||
<MisiPPID />
|
||||
<Group>
|
||||
<Button
|
||||
bg={colors['blue-button']}
|
||||
onClick={submit}
|
||||
loading={visiMisi.update.loading}
|
||||
>
|
||||
Submit
|
||||
</Button>
|
||||
</Group>
|
||||
</Stack>
|
||||
</Paper>
|
||||
)
|
||||
}
|
||||
|
||||
function VisiMisiPPIDList() {
|
||||
const listVisiMisi = useProxy(stateVisiMisiPPID)
|
||||
useShallowEffect(() => {
|
||||
listVisiMisi.findById.load("1")
|
||||
}, [])
|
||||
|
||||
if(!listVisiMisi.findById.data) return <Stack>
|
||||
{Array.from({length: 10}).map((v, k) => <Skeleton key={k} h={40} />)}
|
||||
</Stack>
|
||||
|
||||
return (
|
||||
<Paper bg={colors['white-1']} p={'md'} radius={10}>
|
||||
<Stack gap={"xs"}>
|
||||
<Title order={3}>List Visi Misi PPID</Title>
|
||||
<Box>
|
||||
<Text fw={"bold"}>Visi PPID</Text>
|
||||
<Text dangerouslySetInnerHTML={{__html: listVisiMisi.findById.data?.visi}}></Text>
|
||||
</Box>
|
||||
<Box>
|
||||
<Text fw={"bold"}>Misi PPID</Text>
|
||||
<Text dangerouslySetInnerHTML={{__html: listVisiMisi.findById.data?.misi}}></Text>
|
||||
</Box>
|
||||
</Stack>
|
||||
</Paper>
|
||||
)
|
||||
}
|
||||
|
||||
export default Page;
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
'use client'
|
||||
import { Box, Text } from '@mantine/core';
|
||||
import { useProxy } from 'valtio/utils';
|
||||
import { PPIDTextEditor } from '../../_com/PPIDTextEditor';
|
||||
import stateVisiMisiPPID from '../../../_state/ppid/visi_misi_ppid/visimisiPPID';
|
||||
|
||||
function VisiPPID() {
|
||||
const visiState = useProxy(stateVisiMisiPPID)
|
||||
return (
|
||||
<Box>
|
||||
<Text fw={"bold"}>Visi PPID</Text>
|
||||
<PPIDTextEditor
|
||||
key={visiState.findById.data?.id ?? 'new'}
|
||||
showSubmit={false}
|
||||
onChange={(val) => {
|
||||
if(visiState.findById.data){
|
||||
visiState.findById.data.visi = val
|
||||
}
|
||||
}}
|
||||
initialContent={visiState.findById.data?.visi ?? ''}
|
||||
/>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
export default VisiPPID;
|
||||
@@ -1,9 +1,11 @@
|
||||
import Elysia from "elysia";
|
||||
import Berita from "./berita";
|
||||
import Pengumuman from "./pengumuman";
|
||||
import ProfileDesa from "./profile/profile_desa";
|
||||
|
||||
const Desa = new Elysia({ prefix: "/api/desa", tags: ["Desa"] })
|
||||
.use(Berita)
|
||||
.use(Pengumuman)
|
||||
.use(ProfileDesa)
|
||||
|
||||
export default Desa;
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
import prisma from "@/lib/prisma";
|
||||
|
||||
export default async function profileDesaFindMany() {
|
||||
const res = await prisma.profileDesa.findMany({
|
||||
include: {
|
||||
ProfilPerbekel: true,
|
||||
},
|
||||
});
|
||||
return {
|
||||
data: res,
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
import Elysia, { t } from "elysia";
|
||||
import profileDesaFindMany from "./find-many";
|
||||
import lambangDesaUpdate from "./lambangDesa";
|
||||
import maskotDesaUpdate from "./maskotDesa";
|
||||
import profilePerbekelUpdate from "./profilePerbekel";
|
||||
import sejarahDesaUpdate from "./sejarahDesa";
|
||||
import visimisiDesaUpdate from "./visimisiDesa";
|
||||
|
||||
const ProfileDesa = new Elysia({
|
||||
prefix: "/profile",
|
||||
tags: ["Desa/Profile"]
|
||||
})
|
||||
.get("/find-many", profileDesaFindMany)
|
||||
.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("/sejarahDesa/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
|
||||
@@ -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",
|
||||
}
|
||||
}
|
||||
@@ -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",
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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",
|
||||
}
|
||||
}
|
||||
@@ -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",
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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",
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
import prisma from "@/lib/prisma";
|
||||
import { Prisma } from "@prisma/client";
|
||||
import { Context } from "elysia";
|
||||
|
||||
type FormCreate = Prisma.DoctorSignGetPayload<{
|
||||
select: {
|
||||
content: true;
|
||||
}
|
||||
}>
|
||||
|
||||
export default async function doctorSignCreate(context: Context) {
|
||||
const body = context.body as FormCreate;
|
||||
|
||||
await prisma.doctorSign.create({
|
||||
data: {
|
||||
content: body.content,
|
||||
},
|
||||
});
|
||||
return {
|
||||
success: true,
|
||||
message: "Success create doctor sign",
|
||||
data: {
|
||||
...body,
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
import prisma from "@/lib/prisma";
|
||||
|
||||
export default async function doctorSignFindMany() {
|
||||
const data = await prisma.doctorSign.findMany();
|
||||
return {
|
||||
success: true,
|
||||
message: "Success get doctor sign",
|
||||
data,
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
import Elysia, { t } from "elysia"
|
||||
import doctorSignCreate from "./create"
|
||||
import doctorSignFindMany from "./find-many"
|
||||
|
||||
const DoctorSign = new Elysia({
|
||||
prefix: "/doctor_sign",
|
||||
tags: ["Data Kesehatan/Artikel Kesehatan/Doctor Sign"],
|
||||
})
|
||||
.get("/find-many", doctorSignFindMany)
|
||||
.post("/create", doctorSignCreate, {
|
||||
body: t.Object({
|
||||
content: t.String(),
|
||||
}),
|
||||
})
|
||||
export default DoctorSign
|
||||
@@ -0,0 +1,27 @@
|
||||
import prisma from "@/lib/prisma";
|
||||
import { Prisma } from "@prisma/client";
|
||||
import { Context } from "elysia";
|
||||
|
||||
type FormCreate = Prisma.FirstAidGetPayload<{
|
||||
select: {
|
||||
title: true;
|
||||
content: true;
|
||||
}
|
||||
}>
|
||||
export default async function firstAidCreate(context: Context) {
|
||||
const body = context.body as FormCreate;
|
||||
|
||||
await prisma.firstAid.create({
|
||||
data: {
|
||||
title: body.title,
|
||||
content: body.content,
|
||||
},
|
||||
});
|
||||
return {
|
||||
success: true,
|
||||
message: "Success create first aid",
|
||||
data: {
|
||||
...body,
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
import prisma from "@/lib/prisma"
|
||||
|
||||
export default async function firstAidFindMany() {
|
||||
const res = await prisma.firstAid.findMany()
|
||||
return {
|
||||
data: res
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
import Elysia, { t } from "elysia"
|
||||
import firstAidCreate from "./create"
|
||||
import firstAidFindMany from "./find-many"
|
||||
|
||||
const FirstAid = new Elysia({
|
||||
prefix: "/firstaid",
|
||||
tags: ["Data Kesehatan/Artikel Kesehatan/First Aid"]
|
||||
})
|
||||
.get("/find-many", firstAidFindMany)
|
||||
.post("/create", firstAidCreate, {
|
||||
body: t.Object({
|
||||
title: t.String(),
|
||||
content: t.String(),
|
||||
}),
|
||||
})
|
||||
export default FirstAid
|
||||
@@ -0,0 +1,26 @@
|
||||
import prisma from "@/lib/prisma";
|
||||
import { Prisma } from "@prisma/client";
|
||||
import { Context } from "elysia";
|
||||
|
||||
type FormCreate = Prisma.IntroductionGetPayload<{
|
||||
select: {
|
||||
content: true;
|
||||
};
|
||||
}>;
|
||||
|
||||
export default async function introductionCreate(context: Context) {
|
||||
const body = context.body as FormCreate;
|
||||
|
||||
await prisma.introduction.create({
|
||||
data: {
|
||||
content: body.content,
|
||||
},
|
||||
});
|
||||
return {
|
||||
success: true,
|
||||
message: "Success create introduction",
|
||||
data: {
|
||||
...body,
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
import prisma from "@/lib/prisma";
|
||||
|
||||
export default async function introductionFindMany() {
|
||||
const res = await prisma.introduction.findMany();
|
||||
return {
|
||||
data: res,
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
import Elysia, { t } from "elysia";
|
||||
import introductionCreate from "./create";
|
||||
import introductionFindMany from "./find-many";
|
||||
|
||||
const Introduction = new Elysia({
|
||||
prefix: "/introduction",
|
||||
tags: ["Data Kesehatan/Artikel Kesehatan/Introduction"]
|
||||
})
|
||||
.get("/find-many", introductionFindMany)
|
||||
.post("/create", introductionCreate, {
|
||||
body: t.Object({
|
||||
content: t.String(),
|
||||
}),
|
||||
})
|
||||
|
||||
export default Introduction;
|
||||
@@ -0,0 +1,30 @@
|
||||
import prisma from "@/lib/prisma";
|
||||
import { Context } from "elysia";
|
||||
import { Prisma } from "@prisma/client";
|
||||
|
||||
type FormCreate = Prisma.MythVsFactGetPayload<{
|
||||
select: {
|
||||
title: true;
|
||||
mitos: true;
|
||||
fakta: true;
|
||||
}
|
||||
}>
|
||||
|
||||
export default async function mythVsFactCreate(context: Context) {
|
||||
const body = context.body as FormCreate;
|
||||
|
||||
await prisma.mythVsFact.create({
|
||||
data: {
|
||||
title: body.title,
|
||||
mitos: body.mitos,
|
||||
fakta: body.fakta,
|
||||
},
|
||||
});
|
||||
return {
|
||||
success: true,
|
||||
message: "Success create myth vs fact",
|
||||
data: {
|
||||
...body,
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
import prisma from "@/lib/prisma";
|
||||
|
||||
export default async function mythVsFactFindMany() {
|
||||
const mythVsFacts = await prisma.mythVsFact.findMany();
|
||||
return {
|
||||
success: true,
|
||||
message: "Success get myth vs fact",
|
||||
data: mythVsFacts,
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
import Elysia, { t } from "elysia";
|
||||
import mythVsFactCreate from "./create";
|
||||
import mythVsFactFindMany from "./find-many";
|
||||
|
||||
const MythVsFact = new Elysia({
|
||||
prefix: "/mythvsfact",
|
||||
tags: ["Data Kesehatan/Artikel Kesehatan/Myth vs Fact"]
|
||||
})
|
||||
.get("/find-many", mythVsFactFindMany)
|
||||
.post("/create", mythVsFactCreate, {
|
||||
body: t.Object({
|
||||
title: t.String(),
|
||||
mitos: t.String(),
|
||||
fakta: t.String(),
|
||||
}),
|
||||
})
|
||||
export default MythVsFact
|
||||
@@ -0,0 +1,28 @@
|
||||
import prisma from "@/lib/prisma";
|
||||
import { Prisma } from "@prisma/client";
|
||||
import { Context } from "elysia";
|
||||
|
||||
type FormCreate = Prisma.PreventionGetPayload<{
|
||||
select: {
|
||||
title: true;
|
||||
content: true;
|
||||
}
|
||||
}>
|
||||
|
||||
export default async function preventionCreate(context: Context) {
|
||||
const body = context.body as FormCreate;
|
||||
|
||||
await prisma.prevention.create({
|
||||
data: {
|
||||
title: body.title,
|
||||
content: body.content,
|
||||
},
|
||||
});
|
||||
return {
|
||||
success: true,
|
||||
message: "Success create prevention",
|
||||
data: {
|
||||
...body,
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
import prisma from "@/lib/prisma"
|
||||
|
||||
export default async function preventionFindMany() {
|
||||
const res = await prisma.prevention.findMany()
|
||||
return {
|
||||
data: res
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
import Elysia, { t } from "elysia"
|
||||
import preventionCreate from "./create"
|
||||
import preventionFindMany from "./find-many"
|
||||
|
||||
const Prevention = new Elysia({
|
||||
prefix: "/prevention",
|
||||
tags: ["Data Kesehatan/Artikel Kesehatan/Prevention"]
|
||||
})
|
||||
.get("/find-many", preventionFindMany)
|
||||
.post("/create", preventionCreate, {
|
||||
body: t.Object({
|
||||
title: t.String(),
|
||||
content: t.String(),
|
||||
}),
|
||||
})
|
||||
export default Prevention
|
||||
@@ -0,0 +1,27 @@
|
||||
import prisma from "@/lib/prisma";
|
||||
import { Prisma } from "@prisma/client";
|
||||
import { Context } from "elysia";
|
||||
|
||||
type FormCreate = Prisma.SymptomGetPayload<{
|
||||
select: {
|
||||
title: true;
|
||||
content: true;
|
||||
}
|
||||
}>
|
||||
export default async function symptomCreate(context: Context) {
|
||||
const body = context.body as FormCreate;
|
||||
|
||||
await prisma.symptom.create({
|
||||
data: {
|
||||
title: body.title,
|
||||
content: body.content,
|
||||
},
|
||||
});
|
||||
return {
|
||||
success: true,
|
||||
message: "Success create symptom",
|
||||
data: {
|
||||
...body,
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
import prisma from "@/lib/prisma"
|
||||
|
||||
export default async function symptomFindMany() {
|
||||
const res = await prisma.symptom.findMany()
|
||||
return {
|
||||
data: res
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
import Elysia, { t } from "elysia";
|
||||
import symptomCreate from "./create";
|
||||
import symptomFindMany from "./find-many";
|
||||
|
||||
const Syptom = new Elysia({
|
||||
prefix: "/symptom",
|
||||
tags: ["Data Kesehatan/Artikel Kesehatan/Syptom"]
|
||||
})
|
||||
.get("/find-many", symptomFindMany)
|
||||
.post("/create", symptomCreate, {
|
||||
body: t.Object({
|
||||
title: t.String(),
|
||||
content: t.String(),
|
||||
}),
|
||||
})
|
||||
export default Syptom
|
||||
@@ -13,6 +13,12 @@ import DokumenDiperlukan from "./data_kesehatan_warga/jadwal_kegiatan/dokumen_ya
|
||||
import PendaftaranJadwal from "./data_kesehatan_warga/jadwal_kegiatan/pendaftaran";
|
||||
import PersentaseKelahiranKematian from "./data_kesehatan_warga/persentase_kelahiran_kematian";
|
||||
import GrafikKepuasan from "./data_kesehatan_warga/grafik_kepuasan";
|
||||
import Introduction from "./data_kesehatan_warga/artikel_kesehatan/introduction";
|
||||
import Syptom from "./data_kesehatan_warga/artikel_kesehatan/syptom";
|
||||
import Prevention from "./data_kesehatan_warga/artikel_kesehatan/prevention";
|
||||
import FirstAid from "./data_kesehatan_warga/artikel_kesehatan/first_aid";
|
||||
import MythVsFact from "./data_kesehatan_warga/artikel_kesehatan/myth_vs_fact";
|
||||
import DoctorSign from "./data_kesehatan_warga/artikel_kesehatan/doctor_sign";
|
||||
|
||||
|
||||
const Kesehatan = new Elysia({
|
||||
@@ -33,4 +39,10 @@ const Kesehatan = new Elysia({
|
||||
.use(PendaftaranJadwal)
|
||||
.use(PersentaseKelahiranKematian)
|
||||
.use(GrafikKepuasan)
|
||||
.use(Introduction)
|
||||
.use(Syptom)
|
||||
.use(Prevention)
|
||||
.use(FirstAid)
|
||||
.use(MythVsFact)
|
||||
.use(DoctorSign)
|
||||
export default Kesehatan;
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
import prisma from "@/lib/prisma";
|
||||
import { Prisma } from "@prisma/client";
|
||||
import { Context } from "elysia";
|
||||
|
||||
type FormCreate = Prisma.DaftarInformasiPublikGetPayload<{
|
||||
select: {
|
||||
jenisInformasi: true;
|
||||
deskripsi: true;
|
||||
tanggal: true;
|
||||
}
|
||||
}>
|
||||
export default async function daftarInformasiPublikCreate(context: Context) {
|
||||
const body = context.body as FormCreate;
|
||||
const jumlahData = await prisma.daftarInformasiPublik.count({
|
||||
where: { isActive: true }, // hitung data aktif aja
|
||||
})
|
||||
await prisma.daftarInformasiPublik.create({
|
||||
data: {
|
||||
nomor: jumlahData + 1,
|
||||
jenisInformasi: body.jenisInformasi,
|
||||
deskripsi: body.deskripsi,
|
||||
tanggal: body.tanggal,
|
||||
},
|
||||
})
|
||||
return {
|
||||
success: true,
|
||||
message: "Success create daftar informasi publik",
|
||||
data: {
|
||||
...body,
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
import prisma from "@/lib/prisma";
|
||||
|
||||
export default async function daftarInformasiPublikFindMany() {
|
||||
const res = await prisma.daftarInformasiPublik.findMany();
|
||||
return {
|
||||
data: res
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
import Elysia, { t } from "elysia";
|
||||
import daftarInformasiPublikCreate from "./create";
|
||||
import daftarInformasiPublikFindMany from "./find-many";
|
||||
|
||||
const DaftarInformasiPublik = new Elysia({
|
||||
prefix: "/daftarinformasipublik",
|
||||
tags: ["PPID/Daftar Informasi Publik"]
|
||||
})
|
||||
.get("/find-many", daftarInformasiPublikFindMany)
|
||||
.post("/create", daftarInformasiPublikCreate, {
|
||||
body: t.Object({
|
||||
jenisInformasi: t.String(),
|
||||
deskripsi: t.String(),
|
||||
tanggal: t.String(),
|
||||
}),
|
||||
})
|
||||
|
||||
export default DaftarInformasiPublik
|
||||
33
src/app/api/[[...slugs]]/_lib/ppid/dasar_hukum/find-by-id.ts
Normal file
33
src/app/api/[[...slugs]]/_lib/ppid/dasar_hukum/find-by-id.ts
Normal file
@@ -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",
|
||||
};
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user