ProfilePPID bagian Profile, VisiMisiPPD sudah ada seed dan bisa di edit
This commit is contained in:
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>"
|
||||||
|
}
|
||||||
|
]
|
||||||
@@ -1,7 +1,11 @@
|
|||||||
[
|
[
|
||||||
{"name": "<p>I.B Surya Prabhawa Manuaba, S.H., M.H.</p>"},
|
{
|
||||||
{"biodata" : "<h2>Biodata</h2> <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>"},
|
"id": "1",
|
||||||
{"riwayat" : "<h2>Riwayat Karir</h2> <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>"},
|
"name": "I.B Surya Prabhawa Manuaba, S.H., M.H.",
|
||||||
{"pengalaman" : "<h2>Pengalaman Organisasi</h2> <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>"},
|
"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>",
|
||||||
{"unggulan" : "<h2>Program Kerja Unggulan</h2> <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><h3>Peningkatan Infrastruktur Desa</h3><ul><li>Pembangunan dan perbaikan jalan desa</li><li>Penyediaan fasilitas umum dan ruang terbuka hijau</li><li>Optimalisasi layanan publik berbasis digital</li></ul>"}
|
"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."
|
||||||
|
|
||||||
|
}
|
||||||
|
]
|
||||||
@@ -49,18 +49,21 @@ model AppMenuChild {
|
|||||||
|
|
||||||
//========================================= MENU PPID ========================================= //
|
//========================================= MENU PPID ========================================= //
|
||||||
// ========================================= VISI MISI PPID ========================================= //
|
// ========================================= VISI MISI PPID ========================================= //
|
||||||
model VisiPPID {
|
model VisiMisiPPID {
|
||||||
id String @id @default(cuid())
|
id String @id @default(cuid())
|
||||||
content String
|
visi String @db.Text
|
||||||
|
misi String @db.Text
|
||||||
createdAt DateTime @default(now())
|
createdAt DateTime @default(now())
|
||||||
updatedAt DateTime @updatedAt
|
updatedAt DateTime @updatedAt
|
||||||
deletedAt DateTime @default(now())
|
deletedAt DateTime @default(now())
|
||||||
isActive Boolean @default(true)
|
isActive Boolean @default(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
model MisiPPID {
|
// ========================================= DASAR HUKUM PPID ========================================= //
|
||||||
|
model DasarHukumPPID {
|
||||||
id String @id @default(cuid())
|
id String @id @default(cuid())
|
||||||
content String
|
judul String @db.Text
|
||||||
|
content String @db.Text
|
||||||
createdAt DateTime @default(now())
|
createdAt DateTime @default(now())
|
||||||
updatedAt DateTime @updatedAt
|
updatedAt DateTime @updatedAt
|
||||||
deletedAt DateTime @default(now())
|
deletedAt DateTime @default(now())
|
||||||
@@ -70,11 +73,12 @@ model MisiPPID {
|
|||||||
// ========================================= PROFILE PPID ========================================= //
|
// ========================================= PROFILE PPID ========================================= //
|
||||||
model ProfilePPID {
|
model ProfilePPID {
|
||||||
id String @id @default(cuid())
|
id String @id @default(cuid())
|
||||||
name String @unique
|
name String @db.Text
|
||||||
biodata String
|
biodata String @db.Text
|
||||||
riwayat String
|
riwayat String @db.Text
|
||||||
pengalaman String
|
pengalaman String @db.Text
|
||||||
unggulan String
|
unggulan String @db.Text
|
||||||
|
imageUrl String?
|
||||||
createdAt DateTime @default(now())
|
createdAt DateTime @default(now())
|
||||||
updatedAt DateTime @updatedAt
|
updatedAt DateTime @updatedAt
|
||||||
deletedAt DateTime @default(now())
|
deletedAt DateTime @default(now())
|
||||||
|
|||||||
@@ -6,6 +6,9 @@ import caraMemperolehSalinanInformasi from './data/list-caraMemperolehSalinanInf
|
|||||||
import jenisInformasiDiminta from './data/list-jenisInfromasi.json'
|
import jenisInformasiDiminta from './data/list-jenisInfromasi.json'
|
||||||
import layanan from './data/list-layanan.json'
|
import layanan from './data/list-layanan.json'
|
||||||
import potensi from './data/list-potensi.json'
|
import potensi from './data/list-potensi.json'
|
||||||
|
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'
|
||||||
(async () => {
|
(async () => {
|
||||||
for (const l of layanan) {
|
for (const l of layanan) {
|
||||||
await prisma.layanan.upsert({
|
await prisma.layanan.upsert({
|
||||||
@@ -116,7 +119,67 @@ import potensi from './data/list-potensi.json'
|
|||||||
}
|
}
|
||||||
console.log("cara memperoleh salinan informasi success ...")
|
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 ...")
|
||||||
|
|
||||||
})().then(() => prisma.$disconnect()).catch((e) => {
|
})().then(() => prisma.$disconnect()).catch((e) => {
|
||||||
console.error(e)
|
console.error(e)
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 275 KiB |
@@ -4,66 +4,122 @@ import { toast } from "react-toastify";
|
|||||||
import { proxy } from "valtio";
|
import { proxy } from "valtio";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
|
||||||
|
// Schema validasi form
|
||||||
const templateForm = z.object({
|
const templateForm = z.object({
|
||||||
name: z.string().min(3, "Nama minimal 3 karakter"),
|
name: z.string().min(3, "Nama minimal 3 karakter"),
|
||||||
biodata: z.string().min(3, "Biodata minimal 3 karakter"),
|
biodata: z.string().min(3, "Biodata minimal 3 karakter"),
|
||||||
riwayat: z.string().min(3, "Riwayat minimal 3 karakter"),
|
riwayat: z.string().min(3, "Riwayat minimal 3 karakter"),
|
||||||
pengalaman: z.string().min(3, "Pengalaman minimal 3 karakter"),
|
pengalaman: z.string().min(3, "Pengalaman minimal 3 karakter"),
|
||||||
unggulan: z.string().min(3, "Unggulan minimal 3 karakter"),
|
unggulan: z.string().min(3, "Unggulan minimal 3 karakter"),
|
||||||
})
|
});
|
||||||
|
|
||||||
|
// Type ambil dari Prisma
|
||||||
type ProfilePPIDForm = Prisma.ProfilePPIDGetPayload<{
|
type ProfilePPIDForm = Prisma.ProfilePPIDGetPayload<{
|
||||||
select: {
|
select: {
|
||||||
name: true;
|
id: true;
|
||||||
biodata: true;
|
name: true;
|
||||||
riwayat: true;
|
biodata: true;
|
||||||
pengalaman: true;
|
riwayat: true;
|
||||||
unggulan: true;
|
pengalaman: true;
|
||||||
}
|
unggulan: true;
|
||||||
}>
|
imageUrl: true;
|
||||||
|
};
|
||||||
const profilePPID = proxy({
|
}>;
|
||||||
create: {
|
|
||||||
form: {} as ProfilePPIDForm,
|
|
||||||
loading: false,
|
|
||||||
async create() {
|
|
||||||
const cek = templateForm.safeParse(profilePPID.create.form);
|
|
||||||
if (!cek.success) {
|
|
||||||
const err = `[${cek.error.issues
|
|
||||||
.map((v) => `${v.path.join(".")}`)
|
|
||||||
.join("\n")}] required`;
|
|
||||||
return toast.error(err);
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
profilePPID.create.loading = true;
|
|
||||||
const res = await ApiFetch.api.ppid.profileppid["create"].post(profilePPID.create.form);
|
|
||||||
if (res.status === 200) {
|
|
||||||
profilePPID.findMany.load();
|
|
||||||
return toast.success("success create");
|
|
||||||
}
|
|
||||||
return toast.error("failed create");
|
|
||||||
} catch (error) {
|
|
||||||
console.log((error as Error).message);
|
|
||||||
} finally {
|
|
||||||
profilePPID.create.loading = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
findMany: {
|
|
||||||
data: null as
|
|
||||||
| Prisma.ProfilePPIDGetPayload<{omit: {isActive: true}}>[]
|
|
||||||
| null,
|
|
||||||
async load() {
|
|
||||||
const res = await ApiFetch.api.ppid.profileppid["find-many"].get();
|
|
||||||
if (res.status === 200) {
|
|
||||||
profilePPID.findMany.data = res.data?.data ?? [];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
|
// Proxy utama
|
||||||
const stateProfilePPID = proxy({
|
const stateProfilePPID = proxy({
|
||||||
profilePPID
|
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;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
export default stateProfilePPID;
|
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;
|
||||||
@@ -9,13 +9,12 @@ import Underline from '@tiptap/extension-underline';
|
|||||||
import { useEditor } from '@tiptap/react';
|
import { useEditor } from '@tiptap/react';
|
||||||
import StarterKit from '@tiptap/starter-kit';
|
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 PPIDTextEditor({ onSubmit, onChange, showSubmit = true }: {
|
export function PPIDTextEditor({ onSubmit, onChange, showSubmit = true, initialContent = '', }: {
|
||||||
onSubmit?: (val: string) => void,
|
onSubmit?: (val: string) => void,
|
||||||
onChange: (val: string) => void,
|
onChange: (val: string) => void,
|
||||||
showSubmit?: boolean }) {
|
showSubmit?: boolean,
|
||||||
|
initialContent?: string }) {
|
||||||
const editor = useEditor({
|
const editor = useEditor({
|
||||||
extensions: [
|
extensions: [
|
||||||
StarterKit,
|
StarterKit,
|
||||||
@@ -27,7 +26,7 @@ export function PPIDTextEditor({ onSubmit, onChange, showSubmit = true }: {
|
|||||||
TextAlign.configure({ types: ['heading', 'paragraph'] }),
|
TextAlign.configure({ types: ['heading', 'paragraph'] }),
|
||||||
],
|
],
|
||||||
immediatelyRender: false,
|
immediatelyRender: false,
|
||||||
content,
|
content: initialContent,
|
||||||
onUpdate : ({editor}) => {
|
onUpdate : ({editor}) => {
|
||||||
onChange(editor.getHTML())
|
onChange(editor.getHTML())
|
||||||
}
|
}
|
||||||
|
|||||||
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
|
||||||
@@ -1,23 +1,82 @@
|
|||||||
'use client'
|
'use client'
|
||||||
import { Box, Text } from '@mantine/core';
|
import { Box, Group, Text } from '@mantine/core';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import { useProxy } from 'valtio/utils';
|
import { useProxy } from 'valtio/utils';
|
||||||
import stateProfilePPID from '../../../_state/ppid/profile_ppid/profile_PPID';
|
import stateProfilePPID from '../../../_state/ppid/profile_ppid/profile_PPID';
|
||||||
import { PPIDEditor } from '../../_com/ppid_Editor';
|
import { PPIDTextEditor } from '../../_com/PPIDTextEditor';
|
||||||
|
import { Dropzone, MIME_TYPES } from '@mantine/dropzone';
|
||||||
|
import { IconUpload, IconX, IconPhoto } from '@tabler/icons-react';
|
||||||
|
|
||||||
|
|
||||||
function Biodata() {
|
function Biodata() {
|
||||||
const biodataState = useProxy(stateProfilePPID.profilePPID)
|
const biodataState = useProxy(stateProfilePPID)
|
||||||
|
const handleUpload = async (file: File) => {
|
||||||
|
const formData = new FormData();
|
||||||
|
formData.append("file", file);
|
||||||
|
formData.append("id", biodataState.findById.data?.id ?? ''); // pastikan ID-nya sesuai
|
||||||
|
|
||||||
|
const res = await fetch("/api/ppid/profileppid/edit-img", {
|
||||||
|
method: "POST",
|
||||||
|
body: formData,
|
||||||
|
});
|
||||||
|
|
||||||
|
const result = await res.json();
|
||||||
|
|
||||||
|
if (result.success && biodataState.findById.data) {
|
||||||
|
biodataState.findById.data.imageUrl = result.url;
|
||||||
|
}
|
||||||
|
};
|
||||||
return (<Box>
|
return (<Box>
|
||||||
<Text fw={"bold"}>Biodata</Text>
|
<Text fw={"bold"}>Biodata</Text>
|
||||||
<PPIDEditor
|
<Dropzone
|
||||||
showSubmit={false}
|
mb={20}
|
||||||
onChange={(val) => {
|
onDrop={(files) => {
|
||||||
biodataState.create.form.biodata = val
|
const file = files[0];
|
||||||
}}
|
const currentId = biodataState.findById.data?.id;
|
||||||
|
if (file && currentId) {
|
||||||
|
handleUpload(file);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
onReject={() => console.log('File rejected')}
|
||||||
|
maxSize={5 * 1024 ** 2} // 5MB
|
||||||
|
accept={[MIME_TYPES.jpeg, MIME_TYPES.png, MIME_TYPES.webp]}
|
||||||
|
loading={stateProfilePPID.uploadImage.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>
|
</Box>
|
||||||
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
68
src/app/admin/(dashboard)/ppid/profile-ppid/listPage.tsx
Normal file
68
src/app/admin/(dashboard)/ppid/profile-ppid/listPage.tsx
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
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}>
|
||||||
|
<Box>
|
||||||
|
<Text fw={"bold"}>Gambar</Text>
|
||||||
|
{item.imageUrl ? (
|
||||||
|
<Image
|
||||||
|
src={item.imageUrl}
|
||||||
|
alt="Foto Profil"
|
||||||
|
w={200}
|
||||||
|
radius="md"
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<Text c="dimmed">Belum ada foto</Text>
|
||||||
|
)}
|
||||||
|
</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,6 +1,6 @@
|
|||||||
'use client'
|
'use client'
|
||||||
import colors from '@/con/colors';
|
import colors from '@/con/colors';
|
||||||
import { Box, Button, Group, Paper, SimpleGrid, Skeleton, Stack, Text, TextInput, Title } from '@mantine/core';
|
import { Box, Button, Group, Paper, SimpleGrid, Stack, Text, TextInput, Title } from '@mantine/core';
|
||||||
import Biodata from './biodata/page';
|
import Biodata from './biodata/page';
|
||||||
import PengalamanOrganisasi from './pengalaman_organisasi/page';
|
import PengalamanOrganisasi from './pengalaman_organisasi/page';
|
||||||
import RiwayatKarir from './riwayat_karir/page';
|
import RiwayatKarir from './riwayat_karir/page';
|
||||||
@@ -8,6 +8,7 @@ import ProgramKerjaUnggulan from './program_kerja_unggulan/page';
|
|||||||
import { useProxy } from 'valtio/utils';
|
import { useProxy } from 'valtio/utils';
|
||||||
import stateProfilePPID from '../../_state/ppid/profile_ppid/profile_PPID';
|
import stateProfilePPID from '../../_state/ppid/profile_ppid/profile_PPID';
|
||||||
import { useShallowEffect } from '@mantine/hooks';
|
import { useShallowEffect } from '@mantine/hooks';
|
||||||
|
import ProfileList from './listPage';
|
||||||
|
|
||||||
|
|
||||||
function Page() {
|
function Page() {
|
||||||
@@ -23,15 +24,24 @@ function Page() {
|
|||||||
|
|
||||||
function ProfileCreate() {
|
function ProfileCreate() {
|
||||||
const allState = useProxy(stateProfilePPID)
|
const allState = useProxy(stateProfilePPID)
|
||||||
|
|
||||||
|
// Initialize data if it doesn't exist
|
||||||
|
useShallowEffect(() => {
|
||||||
|
if (!allState.findById.data) {
|
||||||
|
allState.findById.initialize()
|
||||||
|
}
|
||||||
|
}, [])
|
||||||
|
|
||||||
const submit = () => {
|
const submit = () => {
|
||||||
if (
|
if (
|
||||||
allState.profilePPID.create.form.name &&
|
allState.findById.data?.name &&
|
||||||
allState.profilePPID.create.form.biodata &&
|
allState.findById.data?.biodata &&
|
||||||
allState.profilePPID.create.form.riwayat &&
|
allState.findById.data?.riwayat &&
|
||||||
allState.profilePPID.create.form.pengalaman &&
|
allState.findById.data?.pengalaman &&
|
||||||
allState.profilePPID.create.form.unggulan) {
|
allState.findById.data?.unggulan
|
||||||
allState.profilePPID.create.create()
|
) {
|
||||||
}
|
allState.update.save(allState.findById.data)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -41,8 +51,11 @@ function ProfileCreate() {
|
|||||||
<TextInput
|
<TextInput
|
||||||
label={<Text fw={"bold"}>Nama Perbekel</Text>}
|
label={<Text fw={"bold"}>Nama Perbekel</Text>}
|
||||||
placeholder="masukkan nama perbekel"
|
placeholder="masukkan nama perbekel"
|
||||||
|
value={allState.findById.data?.name || ''}
|
||||||
onChange={(val) => {
|
onChange={(val) => {
|
||||||
allState.profilePPID.create.form.name = val.currentTarget.value
|
if (allState.findById.data) {
|
||||||
|
allState.findById.data.name = val.currentTarget.value
|
||||||
|
}
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<Biodata />
|
<Biodata />
|
||||||
@@ -50,53 +63,17 @@ function ProfileCreate() {
|
|||||||
<PengalamanOrganisasi />
|
<PengalamanOrganisasi />
|
||||||
<ProgramKerjaUnggulan />
|
<ProgramKerjaUnggulan />
|
||||||
<Group>
|
<Group>
|
||||||
<Button bg={colors['blue-button']} onClick={submit}>Submit</Button>
|
<Button
|
||||||
|
bg={colors['blue-button']}
|
||||||
|
onClick={submit}
|
||||||
|
loading={allState.update.loading}
|
||||||
|
>
|
||||||
|
Submit
|
||||||
|
</Button>
|
||||||
</Group>
|
</Group>
|
||||||
</Stack>
|
</Stack>
|
||||||
</Paper>
|
</Paper>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
function ProfileList() {
|
export default Page;
|
||||||
const allList = useProxy(stateProfilePPID)
|
|
||||||
useShallowEffect(() => {
|
|
||||||
allList.profilePPID.findMany.load()
|
|
||||||
}, [])
|
|
||||||
|
|
||||||
if (!allList.profilePPID.findMany.data) return <Stack>
|
|
||||||
{Array.from({ length: 10 }).map((v, k) => <Skeleton key={k} h={40} />)}
|
|
||||||
</Stack>
|
|
||||||
return (
|
|
||||||
<Paper bg={colors['white-1']} p={'md'}>
|
|
||||||
<Stack gap={"xs"}>
|
|
||||||
<Title order={3}>List Profile PPID</Title>
|
|
||||||
{allList.profilePPID.findMany.data?.map((item) => (
|
|
||||||
<Box key={item.id}>
|
|
||||||
<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 Page;
|
|
||||||
@@ -3,17 +3,21 @@ import { Box, Text } from '@mantine/core';
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { useProxy } from 'valtio/utils';
|
import { useProxy } from 'valtio/utils';
|
||||||
import stateProfilePPID from '../../../_state/ppid/profile_ppid/profile_PPID';
|
import stateProfilePPID from '../../../_state/ppid/profile_ppid/profile_PPID';
|
||||||
import { PPIDEditor } from '../../_com/ppid_Editor';
|
import { PPIDTextEditor } from '../../_com/PPIDTextEditor';
|
||||||
|
|
||||||
function PengalamanOrganisasi() {
|
function PengalamanOrganisasi() {
|
||||||
const pengalamanOrganisasiState = useProxy(stateProfilePPID.profilePPID)
|
const pengalamanOrganisasiState = useProxy(stateProfilePPID)
|
||||||
return (<Box>
|
return (<Box>
|
||||||
<Text fw={"bold"}>Pengalaman Organisasi</Text>
|
<Text fw={"bold"}>Pengalaman Organisasi</Text>
|
||||||
<PPIDEditor
|
<PPIDTextEditor
|
||||||
|
key={pengalamanOrganisasiState.findById.data?.id ?? 'new'}
|
||||||
showSubmit={false}
|
showSubmit={false}
|
||||||
onChange={(val) => {
|
onChange={(val) => {
|
||||||
pengalamanOrganisasiState.create.form.pengalaman = val
|
if (pengalamanOrganisasiState.findById.data) {
|
||||||
|
pengalamanOrganisasiState.findById.data.pengalaman = val;
|
||||||
|
}
|
||||||
}}
|
}}
|
||||||
|
initialContent={pengalamanOrganisasiState.findById.data?.pengalaman ?? ''}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -3,17 +3,21 @@ import { Box, Text } from '@mantine/core';
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { useProxy } from 'valtio/utils';
|
import { useProxy } from 'valtio/utils';
|
||||||
import stateProfilePPID from '../../../_state/ppid/profile_ppid/profile_PPID';
|
import stateProfilePPID from '../../../_state/ppid/profile_ppid/profile_PPID';
|
||||||
import { PPIDEditor } from '../../_com/ppid_Editor';
|
import { PPIDTextEditor } from '../../_com/PPIDTextEditor';
|
||||||
|
|
||||||
function ProgramKerjaUnggulan() {
|
function ProgramKerjaUnggulan() {
|
||||||
const programKerjaUnggulanState = useProxy(stateProfilePPID.profilePPID)
|
const programKerjaUnggulanState = useProxy(stateProfilePPID)
|
||||||
return (<Box>
|
return (<Box>
|
||||||
<Text fw={"bold"}>Program Kerja Unggulan</Text>
|
<Text fw={"bold"}>Program Kerja Unggulan</Text>
|
||||||
<PPIDEditor
|
<PPIDTextEditor
|
||||||
|
key={programKerjaUnggulanState.findById.data?.id ?? 'new'}
|
||||||
showSubmit={false}
|
showSubmit={false}
|
||||||
onChange={(val) => {
|
onChange={(val) => {
|
||||||
programKerjaUnggulanState.create.form.unggulan = val
|
if (programKerjaUnggulanState.findById.data) {
|
||||||
|
programKerjaUnggulanState.findById.data.unggulan = val;
|
||||||
|
}
|
||||||
}}
|
}}
|
||||||
|
initialContent={programKerjaUnggulanState.findById.data?.unggulan ?? ''}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -7,21 +7,24 @@ import dynamic from 'next/dynamic';
|
|||||||
import stateProfilePPID from '../../../_state/ppid/profile_ppid/profile_PPID';
|
import stateProfilePPID from '../../../_state/ppid/profile_ppid/profile_PPID';
|
||||||
|
|
||||||
// ini penting
|
// ini penting
|
||||||
const PPIDEditor = dynamic(() => import('../../_com/ppid_Editor').then(mod => mod.PPIDEditor), {
|
const PPIDTextEditor = dynamic(() => import('../../_com/PPIDTextEditor').then(mod => mod.PPIDTextEditor), {
|
||||||
ssr: false, // disable server side rendering
|
ssr: false, // disable server side rendering
|
||||||
});
|
});
|
||||||
|
|
||||||
function RiwayatKarir() {
|
function RiwayatKarir() {
|
||||||
const biodataState = useProxy(stateProfilePPID.profilePPID);
|
const riwayatKarirState = useProxy(stateProfilePPID);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box>
|
<Box>
|
||||||
<Text fw={"bold"}>Riwayat Karir</Text>
|
<Text fw={"bold"}>Riwayat Karir</Text>
|
||||||
<PPIDEditor
|
<PPIDTextEditor
|
||||||
|
key={riwayatKarirState.findById.data?.id ?? 'new'}
|
||||||
showSubmit={false}
|
showSubmit={false}
|
||||||
onChange={(val) => {
|
onChange={(val) => {
|
||||||
biodataState.create.form.riwayat = val;
|
if (riwayatKarirState.findById.data) {
|
||||||
|
riwayatKarirState.findById.data.riwayat = val;
|
||||||
|
}
|
||||||
}}
|
}}
|
||||||
|
initialContent={riwayatKarirState.findById.data?.riwayat ?? ''}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -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() {
|
function Page() {
|
||||||
return (
|
return (
|
||||||
<div>
|
<Box>
|
||||||
visi-misi-ppid
|
<SimpleGrid cols={{ base: 1, md: 2 }}>
|
||||||
</div>
|
<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;
|
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;
|
||||||
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",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
18
src/app/api/[[...slugs]]/_lib/ppid/dasar_hukum/index.ts
Normal file
18
src/app/api/[[...slugs]]/_lib/ppid/dasar_hukum/index.ts
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
import Elysia, { t } from "elysia";
|
||||||
|
import dasarHukumPPIDFindById from "./find-by-id";
|
||||||
|
import dasarHukumPPIDUpdate from "./update";
|
||||||
|
|
||||||
|
const DasarHukumPPID = new Elysia({
|
||||||
|
prefix: "/dasarhukumppid",
|
||||||
|
tags: ["PPID/Dasar Hukum PPID"]
|
||||||
|
})
|
||||||
|
.get("/find-by-id", dasarHukumPPIDFindById)
|
||||||
|
.post("/update", dasarHukumPPIDUpdate, {
|
||||||
|
body: t.Object({
|
||||||
|
id: t.String(),
|
||||||
|
judul: t.String(),
|
||||||
|
content: t.String(),
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
export default DasarHukumPPID
|
||||||
29
src/app/api/[[...slugs]]/_lib/ppid/dasar_hukum/update.ts
Normal file
29
src/app/api/[[...slugs]]/_lib/ppid/dasar_hukum/update.ts
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
import prisma from "@/lib/prisma";
|
||||||
|
import { Prisma } from "@prisma/client";
|
||||||
|
import { Context } from "elysia";
|
||||||
|
|
||||||
|
type FormCreate = Prisma.DasarHukumPPIDGetPayload<{
|
||||||
|
select: {
|
||||||
|
id: true;
|
||||||
|
judul: true;
|
||||||
|
content: true;
|
||||||
|
}
|
||||||
|
}>
|
||||||
|
export default async function dasarHukumPPIDUpdate(context: Context) {
|
||||||
|
const body = context.body as FormCreate;
|
||||||
|
|
||||||
|
await prisma.dasarHukumPPID.update({
|
||||||
|
where: {
|
||||||
|
id: body.id
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
judul: body.judul,
|
||||||
|
content: body.content,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return {
|
||||||
|
success: true,
|
||||||
|
message: "Dasar Hukum PPID Berhasil Dibuat",
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -7,7 +7,9 @@ import GrafikBerdasarkanUmur from "./ikm/grafik_berdasarkan_umur";
|
|||||||
import PermohonanInformasiPublik from "./permohonan_informasi_publik";
|
import PermohonanInformasiPublik from "./permohonan_informasi_publik";
|
||||||
import PermohonanKeberatanInformasiPublik from "./permohonan_keberatan_informasi_publik";
|
import PermohonanKeberatanInformasiPublik from "./permohonan_keberatan_informasi_publik";
|
||||||
import ProfilePPID from "./profile_ppid";
|
import ProfilePPID from "./profile_ppid";
|
||||||
import VisiMisiPPID from "./visi_misi_ppid";
|
import VisiMisiPPID from "./visi_misi_ppid/visi_misi_ppid";
|
||||||
|
import DasarHukumPPID from "./dasar_hukum";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -21,6 +23,7 @@ const PPID = new Elysia({ prefix: "/api/ppid", tags: ["PPID"] })
|
|||||||
.use(PermohonanInformasiPublik)
|
.use(PermohonanInformasiPublik)
|
||||||
.use(PermohonanKeberatanInformasiPublik)
|
.use(PermohonanKeberatanInformasiPublik)
|
||||||
.use(VisiMisiPPID)
|
.use(VisiMisiPPID)
|
||||||
|
.use(DasarHukumPPID)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
61
src/app/api/[[...slugs]]/_lib/ppid/profile_ppid/edit-img.ts
Normal file
61
src/app/api/[[...slugs]]/_lib/ppid/profile_ppid/edit-img.ts
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
import prisma from "@/lib/prisma";
|
||||||
|
import { Context } from "elysia";
|
||||||
|
import { writeFile, unlink } from "fs/promises";
|
||||||
|
import path from "path";
|
||||||
|
import fs from "fs";
|
||||||
|
|
||||||
|
interface ProfilePPIDBody {
|
||||||
|
id: string;
|
||||||
|
file: Blob & { name: string; type: string };
|
||||||
|
}
|
||||||
|
|
||||||
|
export default async function editImageProfilePPID(context: Context<{ body: ProfilePPIDBody }>) {
|
||||||
|
const { id, file } = context.body;
|
||||||
|
|
||||||
|
if (!file || !id) {
|
||||||
|
return {
|
||||||
|
success: false,
|
||||||
|
message: "File atau ID harus disertakan",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validasi ekstensi file
|
||||||
|
const allowedTypes = ["image/jpeg", "image/png", "image/webp"];
|
||||||
|
if (!allowedTypes.includes(file.type)) {
|
||||||
|
return {
|
||||||
|
success: false,
|
||||||
|
message: "Tipe file tidak diizinkan. Hanya JPG, PNG, atau WEBP",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const bytes = await file.arrayBuffer();
|
||||||
|
const buffer = Buffer.from(bytes);
|
||||||
|
const filename = `${id}_${Date.now()}_${file.name}`;
|
||||||
|
const filePath = path.resolve("public", "assets", "images", "ppid", "profile-ppid", filename);
|
||||||
|
|
||||||
|
// Simpan file baru
|
||||||
|
await writeFile(filePath, buffer);
|
||||||
|
|
||||||
|
const imageUrl = `/assets/images/ppid/profile-ppid/${filename}`;
|
||||||
|
|
||||||
|
// Hapus file lama (opsional, kalau mau bersih)
|
||||||
|
const oldData = await prisma.profilePPID.findUnique({ where: { id } });
|
||||||
|
if (oldData?.imageUrl) {
|
||||||
|
const oldPath = path.resolve("public", oldData.imageUrl.replace(/^\//, ""));
|
||||||
|
if (fs.existsSync(oldPath)) {
|
||||||
|
await unlink(oldPath).catch(() => {});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update DB
|
||||||
|
await prisma.profilePPID.update({
|
||||||
|
where: { id },
|
||||||
|
data: { imageUrl },
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
success: true,
|
||||||
|
message: "Gambar berhasil diunggah",
|
||||||
|
url: imageUrl,
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
import prisma from "@/lib/prisma";
|
||||||
|
import { Context } from "elysia";
|
||||||
|
|
||||||
|
export default async function profilePPIDFindById(context: Context) {
|
||||||
|
try {
|
||||||
|
const id = context?.params?.slugs?.[0];
|
||||||
|
|
||||||
|
// If no ID provided, get the first profile
|
||||||
|
if (!id) {
|
||||||
|
const data = await prisma.profilePPID.findFirst();
|
||||||
|
return {
|
||||||
|
success: true,
|
||||||
|
data,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const data = await prisma.profilePPID.findUniqueOrThrow({
|
||||||
|
where: { id },
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
success: true,
|
||||||
|
data,
|
||||||
|
};
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error fetching profilePPID:", error);
|
||||||
|
|
||||||
|
return {
|
||||||
|
success: false,
|
||||||
|
message: error instanceof Error ? error.message : "Unknown error",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
import prisma from "@/lib/prisma";
|
|
||||||
|
|
||||||
export default async function profilePPIDFindMany() {
|
|
||||||
const res = await prisma.profilePPID.findMany();
|
|
||||||
return{
|
|
||||||
data: res
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,14 +1,16 @@
|
|||||||
import Elysia, { t } from "elysia";
|
import Elysia, { t } from "elysia";
|
||||||
import profilePPIDCreate from "./create";
|
import profilePPIDFindById from "./find-by-id";
|
||||||
import profilePPIDFindMany from "./find-many";
|
import profilePPIDUpdate from "./update";
|
||||||
|
import editImageProfilePPID from "./edit-img";
|
||||||
|
|
||||||
const ProfilePPID = new Elysia({
|
const ProfilePPID = new Elysia({
|
||||||
prefix: "/profileppid",
|
prefix: "/profileppid",
|
||||||
tags: ["PPID/Profile PPID"]
|
tags: ["PPID/Profile PPID"]
|
||||||
})
|
})
|
||||||
.get("/find-many", profilePPIDFindMany)
|
.get("/find-by-id", profilePPIDFindById)
|
||||||
.post("/create", profilePPIDCreate, {
|
.post("/update", profilePPIDUpdate, {
|
||||||
body: t.Object({
|
body: t.Object({
|
||||||
|
id: t.String(),
|
||||||
name: t.String(),
|
name: t.String(),
|
||||||
biodata: t.String(),
|
biodata: t.String(),
|
||||||
riwayat: t.String(),
|
riwayat: t.String(),
|
||||||
@@ -16,6 +18,7 @@ const ProfilePPID = new Elysia({
|
|||||||
unggulan: t.String(),
|
unggulan: t.String(),
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
.post("/edit-img", editImageProfilePPID)
|
||||||
|
|
||||||
|
|
||||||
export default ProfilePPID;
|
export default ProfilePPID;
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import { Context } from "elysia";
|
|||||||
|
|
||||||
type FormCreate = Prisma.ProfilePPIDGetPayload<{
|
type FormCreate = Prisma.ProfilePPIDGetPayload<{
|
||||||
select: {
|
select: {
|
||||||
|
id: true;
|
||||||
name: true;
|
name: true;
|
||||||
biodata: true;
|
biodata: true;
|
||||||
riwayat: true;
|
riwayat: true;
|
||||||
@@ -11,10 +12,13 @@ type FormCreate = Prisma.ProfilePPIDGetPayload<{
|
|||||||
unggulan: true;
|
unggulan: true;
|
||||||
}
|
}
|
||||||
}>
|
}>
|
||||||
export default async function profilePPIDCreate(context: Context) {
|
export default async function profilePPIDUpdate(context: Context) {
|
||||||
const body = context.body as FormCreate;
|
const body = context.body as FormCreate;
|
||||||
|
|
||||||
await prisma.profilePPID.create({
|
await prisma.profilePPID.update({
|
||||||
|
where: {
|
||||||
|
id: body.id
|
||||||
|
},
|
||||||
data: {
|
data: {
|
||||||
name: body.name,
|
name: body.name,
|
||||||
biodata: body.biodata,
|
biodata: body.biodata,
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
import Elysia from "elysia";
|
|
||||||
import MisiPPID from "./misi_ppid";
|
|
||||||
|
|
||||||
const VisiMisiPPID = new Elysia({ prefix: "/visimisippid", tags: ["PPID/Visi Misi PPID"] })
|
|
||||||
.use(MisiPPID)
|
|
||||||
|
|
||||||
export default VisiMisiPPID
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
import prisma from "@/lib/prisma";
|
|
||||||
import { Prisma } from "@prisma/client";
|
|
||||||
import { Context } from "elysia";
|
|
||||||
|
|
||||||
type FormCreate = Prisma.MisiPPIDGetPayload<{
|
|
||||||
select: {
|
|
||||||
content: true;
|
|
||||||
}
|
|
||||||
}>
|
|
||||||
|
|
||||||
export default async function misiPPIDCreate(context: Context) {
|
|
||||||
const body = context.body as FormCreate;
|
|
||||||
|
|
||||||
await prisma.misiPPID.create({
|
|
||||||
data: {
|
|
||||||
content: body.content,
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
return {
|
|
||||||
success: true,
|
|
||||||
message: "Misi PPID Berhasil Dibuat",
|
|
||||||
data: {
|
|
||||||
...body,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
import prisma from "@/lib/prisma";
|
|
||||||
import { Context } from "elysia";
|
|
||||||
|
|
||||||
export async function misiPPIDDelete(context: Context) {
|
|
||||||
const id = context.params.id
|
|
||||||
|
|
||||||
await prisma.misiPPID.delete({
|
|
||||||
where: {
|
|
||||||
id: id
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
return {
|
|
||||||
success: true,
|
|
||||||
message: "Misi PPID Berhasil Dihapus",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
import prisma from "@/lib/prisma";
|
|
||||||
|
|
||||||
export async function misiPPIDFindMany() {
|
|
||||||
const res = await prisma.misiPPID.findMany();
|
|
||||||
return {
|
|
||||||
data: res,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
import Elysia, { t } from "elysia";
|
|
||||||
import { misiPPIDFindMany } from "./find-many";
|
|
||||||
import misiPPIDCreate from "./create";
|
|
||||||
import { misiPPIDDelete } from "./delete";
|
|
||||||
import misiPPIDUpdate from "./update";
|
|
||||||
|
|
||||||
const MisiPPID = new Elysia({
|
|
||||||
prefix: "/misippid",
|
|
||||||
tags: ["PPID/Visi Misi PPID/ Misi PPID"],
|
|
||||||
})
|
|
||||||
.get("/find-many", misiPPIDFindMany)
|
|
||||||
.post("/create", misiPPIDCreate, {
|
|
||||||
body: t.Object({
|
|
||||||
content: t.String(),
|
|
||||||
})
|
|
||||||
})
|
|
||||||
.put("/update/:id", misiPPIDUpdate, {
|
|
||||||
body: t.Object({
|
|
||||||
content: t.String(),
|
|
||||||
})
|
|
||||||
})
|
|
||||||
.delete("/delete/:id", misiPPIDDelete)
|
|
||||||
|
|
||||||
export default MisiPPID;
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
import prisma from "@/lib/prisma";
|
|
||||||
import { Prisma } from "@prisma/client";
|
|
||||||
import { Context } from "elysia";
|
|
||||||
|
|
||||||
type FormUpdate = Prisma.MisiPPIDGetPayload<{
|
|
||||||
select: {
|
|
||||||
content: true;
|
|
||||||
}
|
|
||||||
}>
|
|
||||||
|
|
||||||
export default async function misiPPIDUpdate(context: Context) {
|
|
||||||
const id = context.params.id
|
|
||||||
const body = context.body as FormUpdate;
|
|
||||||
|
|
||||||
await prisma.misiPPID.update({
|
|
||||||
where: { id: id },
|
|
||||||
data: {
|
|
||||||
content: body.content,
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
return {
|
|
||||||
success: true,
|
|
||||||
message: "Misi PPID Berhasil Diupdate",
|
|
||||||
data: {
|
|
||||||
...body,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
import prisma from "@/lib/prisma";
|
||||||
|
import { Context } from "elysia";
|
||||||
|
|
||||||
|
export default async function visimisiPPIDFindById(context: Context) {
|
||||||
|
try {
|
||||||
|
const id = context?.params?.slugs?.[0];
|
||||||
|
|
||||||
|
// If no ID provided, get the first profile
|
||||||
|
if (!id) {
|
||||||
|
const data = await prisma.visiMisiPPID.findFirst();
|
||||||
|
return {
|
||||||
|
success: true,
|
||||||
|
data,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const data = await prisma.visiMisiPPID.findUniqueOrThrow({
|
||||||
|
where: { id },
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
success: true,
|
||||||
|
data,
|
||||||
|
};
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error fetching visiPPID:", error);
|
||||||
|
|
||||||
|
return {
|
||||||
|
success: false,
|
||||||
|
message: error instanceof Error ? error.message : "Unknown error",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
import Elysia from "elysia";
|
||||||
|
import visimisiPPIDFindById from "./find-by-id";
|
||||||
|
import visimisiPPIDUpdate from "./update";
|
||||||
|
import { t } from "elysia";
|
||||||
|
|
||||||
|
const VisiMisiPPID = new Elysia({
|
||||||
|
prefix: "/visimisippid",
|
||||||
|
tags: ["PPID/Visi Misi PPID"]
|
||||||
|
})
|
||||||
|
.get("/find-by-id", visimisiPPIDFindById)
|
||||||
|
.post("/update", visimisiPPIDUpdate, {
|
||||||
|
body: t.Object({
|
||||||
|
id: t.String(),
|
||||||
|
misi: t.String(),
|
||||||
|
visi: t.String(),
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
export default VisiMisiPPID
|
||||||
|
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
import prisma from "@/lib/prisma";
|
||||||
|
import { Prisma } from "@prisma/client";
|
||||||
|
import { Context } from "elysia";
|
||||||
|
|
||||||
|
type FormCreate = Prisma.VisiMisiPPIDGetPayload<{
|
||||||
|
select: {
|
||||||
|
id: true;
|
||||||
|
misi: true;
|
||||||
|
visi: true;
|
||||||
|
}
|
||||||
|
}>
|
||||||
|
export default async function visimisiPPIDUpdate(context: Context) {
|
||||||
|
const body = context.body as FormCreate;
|
||||||
|
|
||||||
|
await prisma.visiMisiPPID.update({
|
||||||
|
where: {
|
||||||
|
id: body.id
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
misi: body.misi,
|
||||||
|
visi: body.visi,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return {
|
||||||
|
success: true,
|
||||||
|
message: "Visi PPID Berhasil Diupdate",
|
||||||
|
data: {
|
||||||
|
...body,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,9 +1,37 @@
|
|||||||
|
'use client'
|
||||||
|
import stateProfilePPID from '@/app/admin/(dashboard)/_state/ppid/profile_ppid/profile_PPID';
|
||||||
import colors from '@/con/colors';
|
import colors from '@/con/colors';
|
||||||
import { Stack, Box, Text, Paper, Flex, Image, Divider, Center, SimpleGrid, List, ListItem } from '@mantine/core';
|
import { Box, Center, Divider, Flex, Image, List, Paper, SimpleGrid, Skeleton, Stack, Text } from '@mantine/core';
|
||||||
import React from 'react';
|
import { useShallowEffect } from '@mantine/hooks';
|
||||||
|
import { useProxy } from 'valtio/utils';
|
||||||
import BackButton from '../../desa/layanan/_com/BackButto';
|
import BackButton from '../../desa/layanan/_com/BackButto';
|
||||||
|
|
||||||
function Page() {
|
function Page() {
|
||||||
|
const allList = useProxy(stateProfilePPID)
|
||||||
|
useShallowEffect(() => {
|
||||||
|
allList.findById.load("1") // Assuming "1" is your default ID, adjust as needed
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
if (!allList.findById.data) return <Stack bg={colors.Bg} py={"xl"} gap={"22"}>
|
||||||
|
<Box px={{ base: 'md', md: 100 }}>
|
||||||
|
<Skeleton style={{backgroundColor: colors.Bg}} h={40} />
|
||||||
|
</Box>
|
||||||
|
<Box px={{ base: 'md', md: 100 }}>
|
||||||
|
<Skeleton h={80} />
|
||||||
|
</Box>
|
||||||
|
<Box px={{ base: "md", md: 100 }}>
|
||||||
|
<Paper p={"xl"} bg={colors['white-trans-1']}>
|
||||||
|
{Array.from({ length: 10 }).map((v, k) =>
|
||||||
|
<Skeleton key={k} h={40} />
|
||||||
|
)}
|
||||||
|
</Paper>
|
||||||
|
</Box>
|
||||||
|
</Stack>
|
||||||
|
|
||||||
|
const dataArray = Array.isArray(allList.findById.data)
|
||||||
|
? allList.findById.data
|
||||||
|
: [allList.findById.data];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Stack pos={"relative"} bg={colors.Bg} py={"xl"} gap={"22"}>
|
<Stack pos={"relative"} bg={colors.Bg} py={"xl"} gap={"22"}>
|
||||||
<Box px={{ base: 'md', md: 100 }}>
|
<Box px={{ base: 'md', md: 100 }}>
|
||||||
@@ -14,101 +42,78 @@ function Page() {
|
|||||||
Profil Singkat PPID Desa Darmasaba
|
Profil Singkat PPID Desa Darmasaba
|
||||||
</Text>
|
</Text>
|
||||||
</Box>
|
</Box>
|
||||||
<Box px={{ base: "md", md: 100 }}>
|
{dataArray.map((item) => (
|
||||||
<Paper p={"xl"} bg={colors['white-trans-1']}>
|
<Box key={item.id} px={{ base: "md", md: 100 }}>
|
||||||
<Box px={{ base: "md", md: 100 }}>
|
<Paper p={"xl"} bg={colors['white-trans-1']}>
|
||||||
<Flex align={"center"} gap={50}>
|
<Box px={{ base: "md", md: 100 }}>
|
||||||
<Image src={"/api/img/darmasaba-icon.png"} h={{ base: 80, md: 150 }} alt='' />
|
<Flex align={"center"} gap={50}>
|
||||||
<Text fz={{ base: "1.4rem", md: "2rem", lg: "2.5rem", xl: "3rem" }} fw={'bold'}>PROFIL PIMPINAN BADAN PUBLIK DESA DARMASABA </Text>
|
<Image src={"/api/img/darmasaba-icon.png"} h={{ base: 80, md: 150 }} alt='' />
|
||||||
</Flex>
|
<Text fz={{ base: "1.4rem", md: "2rem", lg: "2.5rem", xl: "3rem" }} fw={'bold'}>PROFIL PIMPINAN BADAN PUBLIK DESA DARMASABA </Text>
|
||||||
</Box>
|
</Flex>
|
||||||
<Divider my={"md"} />
|
</Box>
|
||||||
{/* biodata perbekel */}
|
<Divider my={"md"} />
|
||||||
<Box px={{base: 0, md: 50}} pb={30}>
|
{/* biodata perbekel */}
|
||||||
<SimpleGrid
|
<Box px={{ base: 0, md: 50 }} pb={30}>
|
||||||
cols={{
|
<SimpleGrid
|
||||||
base: 1,
|
cols={{
|
||||||
md: 1,
|
base: 1,
|
||||||
lg: 1,
|
md: 1,
|
||||||
xl: 2,
|
lg: 1,
|
||||||
}}
|
xl: 2,
|
||||||
>
|
}}
|
||||||
<Box px={{ base: 0, md: 50 }}>
|
>
|
||||||
<Paper bg={colors['white-trans-1']} w={{ base: "100%", md: "100%" }}>
|
<Box px={{ base: 0, md: 50 }}>
|
||||||
<Stack gap={0}>
|
<Paper bg={colors['white-trans-1']} w={{ base: "100%", md: "100%" }}>
|
||||||
<Center>
|
<Stack gap={0}>
|
||||||
<Image pt={{ base: 0, md: 90 }} src={"/api/img/perbekel.png"} w={{ base: 250, md: 355 }} alt='' />
|
<Center>
|
||||||
</Center>
|
<Image pt={{ base: 0, md: 90 }} src={item.imageUrl ? `${item.imageUrl}?t=${Date.now()}` : "/api/img/perbekel.png"} w={{ base: 250, md: 355 }} alt='' />
|
||||||
<Paper
|
</Center>
|
||||||
bg={colors['blue-button']}
|
<Paper
|
||||||
py={30}
|
bg={colors['blue-button']}
|
||||||
className="glass3"
|
py={30}
|
||||||
px={{ base: 20, md: 20 }}
|
className="glass3"
|
||||||
|
px={{ base: 20, md: 20 }}
|
||||||
|
|
||||||
>
|
>
|
||||||
<Text ta={"center"} c={colors['white-1']} fw={"bolder"} fz={{ base: "1.5rem", md: "2.125rem", lg: "2.25rem", xl: "1.5rem" }}>
|
<Text ta={"center"} c={colors['white-1']} fw={"bolder"} fz={{ base: "1.5rem", md: "2.125rem", lg: "2.25rem", xl: "1.5rem" }}>
|
||||||
I.B. Surya Prabhawa Manuaba,
|
{item.name}
|
||||||
</Text>
|
</Text>
|
||||||
<Text ta={"center"} c={colors['white-1']} fw={"bolder"} fz={{ base: "1.5rem", md: "2.125rem", lg: "2.25rem", xl: "1.5rem" }}>
|
</Paper>
|
||||||
S.H.,M.H.,NL.P.
|
</Stack>
|
||||||
</Text>
|
</Paper>
|
||||||
</Paper>
|
|
||||||
</Stack>
|
|
||||||
</Paper>
|
|
||||||
</Box>
|
|
||||||
<Box>
|
|
||||||
<Box>
|
|
||||||
<Text fz={{ base: "1.125rem", md: "1.375rem", lg: "1.75rem", xl: "2rem" }} fw={'bold'}>Biodata</Text>
|
|
||||||
<Text fz={{ base: "1rem", md: "1.125rem", lg: "1.25rem", xl: "1.5rem" }} ta={"justify"}>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.</Text>
|
|
||||||
<Text fz={{ base: "1rem", md: "1.125rem", lg: "1.25rem", xl: "1.5rem" }} ta={"justify"}>Dia menempuh pendidikan hukum di Universitas Udayana dan Universitas Mahasaraswati Denpasar, serta memiliki pengalaman luas di berbagai organisasi dan kepemimpinan.</Text>
|
|
||||||
</Box>
|
</Box>
|
||||||
<Box>
|
<Box>
|
||||||
<Text fz={{ base: "1.125rem", md: "1.375rem", lg: "1.75rem", xl: "2rem" }} fw={'bold'}>Riwayat Karir</Text>
|
<Box>
|
||||||
<Text fz={{ base: "1rem", md: "1.125rem", lg: "1.25rem", xl: "1.5rem" }} >2021 - 2027: Perbekel Desa Darmasaba</Text>
|
<Text fz={{ base: "1.125rem", md: "1.375rem", lg: "1.75rem", xl: "2rem" }} fw={'bold'}>Biodata</Text>
|
||||||
<Text fz={{ base: "1rem", md: "1.125rem", lg: "1.25rem", xl: "1.5rem" }} >2015 - Sekarang: Founder & Managing Director Mantra Legal Consultants & Advocates</Text>
|
<Text fz={{ base: "1rem", md: "1.125rem", lg: "1.25rem", xl: "1.5rem" }} ta={"justify"} dangerouslySetInnerHTML={{ __html: item.biodata }} />
|
||||||
<Text fz={{ base: "1rem", md: "1.125rem", lg: "1.25rem", xl: "1.5rem" }} >2020 - Sekarang: Founder Ugawa Record Music Studio</Text>
|
</Box>
|
||||||
<Text fz={{ base: "1rem", md: "1.125rem", lg: "1.25rem", xl: "1.5rem" }} >2010 - 2016: Dosen Fakultas Hukum Universitas Mahasaraswati Denpasar</Text>
|
<Box>
|
||||||
|
<Text fz={{ base: "1.125rem", md: "1.375rem", lg: "1.75rem", xl: "2rem" }} fw={'bold'}>Riwayat Karir</Text>
|
||||||
|
<Text fz={{ base: "1rem", md: "1.125rem", lg: "1.25rem", xl: "1.5rem" }} dangerouslySetInnerHTML={{ __html: item.riwayat }} />
|
||||||
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</SimpleGrid>
|
||||||
</SimpleGrid>
|
</Box>
|
||||||
</Box>
|
<Box pb={30}>
|
||||||
<Box pb={30}>
|
<Text fz={{ base: "1.125rem", md: "1.375rem", lg: "1.75rem", xl: "2rem" }} fw={'bold'}>Pengalaman Organisasi</Text>
|
||||||
<Text fz={{ base: "1.125rem", md: "1.375rem", lg: "1.75rem", xl: "2rem" }} fw={'bold'}>Pengalaman Organisasi</Text>
|
<List>
|
||||||
<List>
|
<Box px={20}>
|
||||||
<Box px={20}>
|
<Text fz={{ base: "1rem", md: "1.125rem", lg: "1.25rem", xl: "1.5rem" }} ta={"justify"} dangerouslySetInnerHTML={{ __html: item.pengalaman }} />
|
||||||
<ListItem fz={{ base: "1rem", md: "1.125rem", lg: "1.25rem", xl: "1.5rem" }} ta={"justify"}>1996 - 1997: Ketua OSIS SMP Negeri 1 Abiansemal</ListItem>
|
</Box>
|
||||||
<ListItem fz={{ base: "1rem", md: "1.125rem", lg: "1.25rem", xl: "1.5rem" }} ta={"justify"}>1999 - 2000: Ketua OSIS SMA Negeri 1 Mengwi</ListItem>
|
</List>
|
||||||
<ListItem fz={{ base: "1rem", md: "1.125rem", lg: "1.25rem", xl: "1.5rem" }} ta={"justify"}>2008 - 2009: Ketua BEM Universitas Mahasaraswati Denpasar</ListItem>
|
</Box>
|
||||||
<ListItem fz={{ base: "1rem", md: "1.125rem", lg: "1.25rem", xl: "1.5rem" }} >2008 - 2010: Ketua Sekaa Taruna Sila Dharma, Banjar Tengah, Desa Adat Tegal, Darmasaba</ListItem>
|
<Box pb={20}>
|
||||||
<ListItem fz={{ base: "1rem", md: "1.125rem", lg: "1.25rem", xl: "1.5rem" }} >2020 - Sekarang: Pengurus Young Lawyer Committee Peradi Denpasar</ListItem>
|
<Text fz={{ base: "1.125rem", md: "1.375rem", lg: "1.75rem", xl: "2rem" }} fw={'bold'}>Program Kerja Unggulan</Text>
|
||||||
<ListItem fz={{ base: "1rem", md: "1.125rem", lg: "1.25rem", xl: "1.5rem" }} >2021 - Sekarang: Dewan Kehormatan Himpunan Pengusaha Muda Indonesia (HIPMI) Badung</ListItem>
|
<List>
|
||||||
<ListItem fz={{ base: "1rem", md: "1.125rem", lg: "1.25rem", xl: "1.5rem" }} >2023 - 2028: Komite Tetap Advokasi - Bidang Hukum dan Regulasi Kamar Dagang dan Industri Badung</ListItem>
|
<Box px={20}>
|
||||||
</Box>
|
<Text fz={{ base: "1rem", md: "1.125rem", lg: "1.25rem", xl: "1.5rem" }} ta={"justify"} dangerouslySetInnerHTML={{ __html: item.unggulan }} />
|
||||||
</List>
|
</Box>
|
||||||
</Box>
|
</List>
|
||||||
<Box pb={20}>
|
</Box>
|
||||||
<Text pb={20} fz={{ base: "1.125rem", md: "1.375rem", lg: "1.75rem", xl: "2rem" }} fw={'bold'}>Program Kerja Unggulan</Text>
|
</Paper>
|
||||||
<Text fz={{ base: "1rem", md: "1.125rem", lg: "1.25rem", xl: "1.5rem" }} fw={'bold'}>Pemberdayaan Ekonomi dan UMKM</Text>
|
</Box>
|
||||||
<List>
|
|
||||||
<Box px={20}>
|
))}
|
||||||
<ListItem fz={{ base: "1rem", md: "1.125rem", lg: "1.25rem", xl: "1.5rem" }} ta={"justify"}>Pelatihan dan pendampingan UMKM lokal</ListItem>
|
|
||||||
<ListItem fz={{ base: "1rem", md: "1.125rem", lg: "1.25rem", xl: "1.5rem" }} ta={"justify"}>Program bantuan modal usaha bagi pelaku usaha kecil</ListItem>
|
|
||||||
<ListItem fz={{ base: "1rem", md: "1.125rem", lg: "1.25rem", xl: "1.5rem" }} ta={"justify"}>Digitalisasi UMKM untuk meningkatkan pemasaran produk lokal</ListItem>
|
|
||||||
</Box>
|
|
||||||
</List>
|
|
||||||
</Box>
|
|
||||||
<Box>
|
|
||||||
<Text fz={{ base: "1rem", md: "1.125rem", lg: "1.25rem", xl: "1.5rem" }} fw={'bold'}>Peningkatan Infrastruktur Desa</Text>
|
|
||||||
<List>
|
|
||||||
<Box px={20}>
|
|
||||||
<ListItem fz={{ base: "1rem", md: "1.125rem", lg: "1.25rem", xl: "1.5rem" }} ta={"justify"}>Pembangunan dan perbaikan jalan desa</ListItem>
|
|
||||||
<ListItem fz={{ base: "1rem", md: "1.125rem", lg: "1.25rem", xl: "1.5rem" }} ta={"justify"}>Penyediaan fasilitas umum dan ruang terbuka hijau</ListItem>
|
|
||||||
<ListItem fz={{ base: "1rem", md: "1.125rem", lg: "1.25rem", xl: "1.5rem" }} ta={"justify"}>Optimalisasi layanan publik berbasis digital</ListItem>
|
|
||||||
</Box>
|
|
||||||
</List>
|
|
||||||
</Box>
|
|
||||||
</Paper>
|
|
||||||
</Box>
|
|
||||||
</Stack>
|
</Stack>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,54 +1,60 @@
|
|||||||
|
'use client'
|
||||||
|
import stateVisiMisiPPID from '@/app/admin/(dashboard)/_state/ppid/visi_misi_ppid/visimisiPPID';
|
||||||
import colors from '@/con/colors';
|
import colors from '@/con/colors';
|
||||||
import { Stack, Box, Paper, Text, Image, Center, ListItem, List } from '@mantine/core';
|
import { Box, Center, Image, Paper, Skeleton, Stack, Text } from '@mantine/core';
|
||||||
import React from 'react';
|
import { useShallowEffect } from '@mantine/hooks';
|
||||||
|
import { useProxy } from 'valtio/utils';
|
||||||
import BackButton from '../../desa/layanan/_com/BackButto';
|
import BackButton from '../../desa/layanan/_com/BackButto';
|
||||||
|
|
||||||
function Page() {
|
function Page() {
|
||||||
|
const allList = useProxy(stateVisiMisiPPID)
|
||||||
|
useShallowEffect(() => {
|
||||||
|
allList.findById.load("1") // Assuming "1" is your default ID, adjust as needed
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
if (!allList.findById.data) return <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 (
|
return (
|
||||||
<Stack pos={"relative"} bg={colors.Bg} py={"xl"} gap={"22"}>
|
<Stack pos={"relative"} bg={colors.Bg} py={"xl"} gap={"22"}>
|
||||||
<Box px={{ base: 'md', md: 100 }}>
|
<Box px={{ base: 'md', md: 100 }}>
|
||||||
<BackButton />
|
<BackButton />
|
||||||
</Box>
|
</Box>
|
||||||
<Box px={{ base: "md", md: 100 }}>
|
{dataArray.map((item) => (
|
||||||
<Stack gap={'lg'}>
|
<Box key={item.id} px={{ base: "md", md: 100 }}>
|
||||||
<Paper p={"xl"} bg={colors['white-trans-1']}>
|
<Stack gap={'lg'}>
|
||||||
<Box pb={30}>
|
<Paper p={"xl"} bg={colors['white-trans-1']}>
|
||||||
<Center>
|
<Box pb={30}>
|
||||||
<Image src={"/api/img/darmasaba-icon.png"} w={{ base: 100, md: 150 }} alt='' />
|
<Center>
|
||||||
</Center>
|
<Image src={"/api/img/darmasaba-icon.png"} w={{ base: 100, md: 150 }} alt='' />
|
||||||
<Text ta={"center"} fz={{ base: "h2", md: "2.5rem" }} fw={"bold"}>
|
</Center>
|
||||||
MOTO PPID DESA DARMASABA
|
<Text ta={"center"} fz={{ base: "h2", md: "2.5rem" }} fw={"bold"}>
|
||||||
</Text>
|
MOTO PPID DESA DARMASABA
|
||||||
<Text ta={"center"} fz={{ base: "h4", md: "h3" }} >
|
</Text>
|
||||||
MEMBERIKAN INFORMASI YANG CEPAT, MUDAH, TEPAT DAN TRANSPARAN
|
<Text ta={"center"} fz={{ base: "h4", md: "h3" }} >
|
||||||
</Text>
|
MEMBERIKAN INFORMASI YANG CEPAT, MUDAH, TEPAT DAN TRANSPARAN
|
||||||
</Box>
|
</Text>
|
||||||
<Box px={{ base: 20, md: 50 }} pb={30}>
|
|
||||||
<Text ta={"center"} fz={{ base: "h3", md: "h2" }} fw={"bold"}>
|
|
||||||
VISI PPID
|
|
||||||
</Text>
|
|
||||||
<Text fz={{ base: "md", md: "h3" }} ta={"justify"}>
|
|
||||||
Memberikan pelayanan informasi yanng transparan dan akuntabel untuk memenuhi hak pemohon informasi
|
|
||||||
sesuai dengan ketentuan peraturan perundang-undangan yang berlaku.
|
|
||||||
</Text>
|
|
||||||
</Box>
|
|
||||||
<Box px={{ base: 20, md: 50 }}>
|
|
||||||
<Text ta={"center"} fz={{ base: "h3", md: "h2" }} fw={"bold"}>
|
|
||||||
MISI PPID
|
|
||||||
</Text>
|
|
||||||
<Box >
|
|
||||||
<List type='ordered'>
|
|
||||||
<ListItem fz={{ base: "md", md: "h3" }} ta={"justify"}>Meningkatkan pengelolaan dan pelayanan informasi yang berkualitas, benar dan bertanggung jawab</ListItem>
|
|
||||||
<ListItem fz={{ base: "md", md: "h3" }} ta={"justify"}>Membangun dan mengembangkan sistem penyediaan dan layanan informasi.</ListItem>
|
|
||||||
<ListItem fz={{ base: "md", md: "h3" }} ta={"justify"}>Meningkatkan dan mengembangkan kompetensi dan kualitas SDM dalam bidang pelayanan informasi.</ListItem>
|
|
||||||
<ListItem fz={{ base: "md", md: "h3" }} >Mewujudkan keterbukaan informasi Pemerintah Desa Punggul dengan proses yang cepat, tepat, mudah
|
|
||||||
dan sederhana.</ListItem>
|
|
||||||
</List>
|
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
<Box px={{ base: 20, md: 50 }} pb={30}>
|
||||||
</Paper>
|
<Text ta={"center"} fz={{ base: "h3", md: "h2" }} fw={"bold"}>
|
||||||
</Stack>
|
VISI PPID
|
||||||
</Box>
|
</Text>
|
||||||
|
<Text fz={{ base: "md", md: "h3" }} ta={"justify"} dangerouslySetInnerHTML={{ __html: item.visi }} />
|
||||||
|
</Box>
|
||||||
|
<Box px={{ base: 20, md: 50 }}>
|
||||||
|
<Text ta={"center"} fz={{ base: "h3", md: "h2" }} fw={"bold"}>
|
||||||
|
MISI PPID
|
||||||
|
</Text>
|
||||||
|
<Text fz={{ base: "md", md: "h3" }} ta={"justify"} dangerouslySetInnerHTML={{ __html: item.misi }} />
|
||||||
|
</Box>
|
||||||
|
</Paper>
|
||||||
|
</Stack>
|
||||||
|
</Box>
|
||||||
|
))}
|
||||||
</Stack>
|
</Stack>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user