From 0ac9fa1f5390aea0d4613dccb4529a78e62bbc7b Mon Sep 17 00:00:00 2001 From: nico Date: Thu, 7 Aug 2025 10:53:56 +0800 Subject: [PATCH] Sinkronisasi UI & API Admin - User Submenu Berita --- prisma/schema.prisma | 87 +- .../admin/(dashboard)/_state/desa/berita.ts | 245 +++- .../indeks-kepuasan-masyarakat.ts | 1180 ----------------- .../_lib => desa/berita/_com}/layoutTabs.tsx | 24 +- .../desa/berita/kategori-berita/[id]/page.tsx | 80 ++ .../berita/kategori-berita/create/page.tsx | 55 + .../desa/berita/kategori-berita/page.tsx | 128 ++ .../admin/(dashboard)/desa/berita/layout.tsx | 13 + .../{ => list-berita}/[id]/edit/page.tsx | 98 +- .../berita/{ => list-berita}/[id]/page.tsx | 6 +- .../berita/{ => list-berita}/create/page.tsx | 95 +- .../desa/berita/{ => list-berita}/page.tsx | 9 +- .../indeks-kepuasan-masyarakat/layout.tsx | 12 - .../list-bulanan/[id]/edit/page.tsx | 128 -- .../list-bulanan/[id]/page.tsx | 109 -- .../list-bulanan/create/page.tsx | 84 -- .../list-bulanan/page.tsx | 98 -- .../list-gender-stat/[id]/edit/page.tsx | 186 --- .../list-gender-stat/[id]/page.tsx | 113 -- .../list-gender-stat/create/page.tsx | 103 -- .../list-gender-stat/page.tsx | 106 -- .../list-survey/[id]/edit/page.tsx | 122 -- .../list-survey/[id]/page.tsx | 109 -- .../list-survey/create/page.tsx | 78 -- .../list-survey/page.tsx | 103 -- src/app/admin/_com/list_PageAdmin.tsx | 2 +- .../[[...slugs]]/_lib/desa/berita/category.ts | 9 - .../[[...slugs]]/_lib/desa/berita/index.ts | 2 - .../desa/berita/kategori-berita/create.ts | 26 + .../_lib/desa/berita/kategori-berita/del.ts | 16 + .../desa/berita/kategori-berita/findMany.ts | 11 + .../desa/berita/kategori-berita/findUnique.ts | 46 + .../_lib/desa/berita/kategori-berita/index.ts | 33 + .../_lib/desa/berita/kategori-berita/updt.ts | 28 + src/app/api/[[...slugs]]/_lib/desa/index.ts | 2 + .../indeks-kepuasan-masyarakat/age/create.ts | 33 - .../indeks-kepuasan-masyarakat/age/del.ts | 24 - .../age/findMany.ts | 26 - .../age/findUnique.ts | 34 - .../indeks-kepuasan-masyarakat/age/index.ts | 31 - .../indeks-kepuasan-masyarakat/age/updt.ts | 35 - .../gender/create.ts | 40 - .../indeks-kepuasan-masyarakat/gender/del.ts | 24 - .../gender/findMany.ts | 26 - .../gender/findUnique.ts | 34 - .../gender/index.ts | 37 - .../indeks-kepuasan-masyarakat/gender/updt.ts | 42 - .../indeks-kepuasan-masyarakat/index.ts | 20 - .../monthly-stat/create.ts | 33 - .../monthly-stat/del.ts | 26 - .../monthly-stat/findMany.ts | 26 - .../monthly-stat/findUnique.ts | 35 - .../monthly-stat/index.ts | 31 - .../monthly-stat/updt.ts | 34 - .../response/create.ts | 33 - .../response/del.ts | 24 - .../response/findMany.ts | 26 - .../response/findUnique.ts | 34 - .../response/index.ts | 31 - .../response/updt.ts | 35 - .../survey/create.ts | 42 - .../indeks-kepuasan-masyarakat/survey/del.ts | 24 - .../survey/findMany.ts | 28 - .../survey/findUnique.ts | 34 - .../survey/index.ts | 30 - .../indeks-kepuasan-masyarakat/survey/updt.ts | 49 - .../[[...slugs]]/_lib/landing_page/index.ts | 2 - .../(pages)/desa/berita/_lib/layoutTabs.tsx | 133 ++ .../{(tabs)/budaya.tsx => budaya/page.tsx} | 0 .../{(tabs)/ekonomi.tsx => ekonomi/page.tsx} | 0 .../darmasaba/(pages)/desa/berita/layout.tsx | 12 + .../darmasaba/(pages)/desa/berita/page.tsx | 102 -- .../darmasaba/(pages)/desa/berita/page2.txt | 128 ++ .../pembangunan.tsx => pembangunan/page.tsx} | 0 .../page.tsx} | 0 .../{(tabs)/semua.tsx => semua/page.tsx} | 0 .../{(tabs)/sosial.tsx => sosial/page.tsx} | 0 .../teknologi.tsx => teknologi/page.tsx} | 0 .../(pages)/desa/profile/ui/lambangDesa.tsx | 2 +- .../(pages)/desa/profile/ui/maskotDesa.tsx | 10 +- .../(pages)/desa/profile/ui/sejarahDesa.tsx | 2 +- .../(pages)/desa/profile/ui/visimisiDesa.tsx | 2 +- .../page.tsx | 2 +- .../(pages)/ppid/struktur-ppid/page.tsx | 119 +- src/con/navbar-list-menu.ts | 2 +- 85 files changed, 1135 insertions(+), 3908 deletions(-) delete mode 100644 src/app/admin/(dashboard)/_state/landing-page/indeks-kepuasan-masyarakat.ts rename src/app/admin/(dashboard)/{landing-page/indeks-kepuasan-masyarakat/_lib => desa/berita/_com}/layoutTabs.tsx (72%) create mode 100644 src/app/admin/(dashboard)/desa/berita/kategori-berita/[id]/page.tsx create mode 100644 src/app/admin/(dashboard)/desa/berita/kategori-berita/create/page.tsx create mode 100644 src/app/admin/(dashboard)/desa/berita/kategori-berita/page.tsx create mode 100644 src/app/admin/(dashboard)/desa/berita/layout.tsx rename src/app/admin/(dashboard)/desa/berita/{ => list-berita}/[id]/edit/page.tsx (72%) rename src/app/admin/(dashboard)/desa/berita/{ => list-berita}/[id]/page.tsx (94%) rename src/app/admin/(dashboard)/desa/berita/{ => list-berita}/create/page.tsx (67%) rename src/app/admin/(dashboard)/desa/berita/{ => list-berita}/page.tsx (93%) delete mode 100644 src/app/admin/(dashboard)/landing-page/indeks-kepuasan-masyarakat/layout.tsx delete mode 100644 src/app/admin/(dashboard)/landing-page/indeks-kepuasan-masyarakat/list-bulanan/[id]/edit/page.tsx delete mode 100644 src/app/admin/(dashboard)/landing-page/indeks-kepuasan-masyarakat/list-bulanan/[id]/page.tsx delete mode 100644 src/app/admin/(dashboard)/landing-page/indeks-kepuasan-masyarakat/list-bulanan/create/page.tsx delete mode 100644 src/app/admin/(dashboard)/landing-page/indeks-kepuasan-masyarakat/list-bulanan/page.tsx delete mode 100644 src/app/admin/(dashboard)/landing-page/indeks-kepuasan-masyarakat/list-gender-stat/[id]/edit/page.tsx delete mode 100644 src/app/admin/(dashboard)/landing-page/indeks-kepuasan-masyarakat/list-gender-stat/[id]/page.tsx delete mode 100644 src/app/admin/(dashboard)/landing-page/indeks-kepuasan-masyarakat/list-gender-stat/create/page.tsx delete mode 100644 src/app/admin/(dashboard)/landing-page/indeks-kepuasan-masyarakat/list-gender-stat/page.tsx delete mode 100644 src/app/admin/(dashboard)/landing-page/indeks-kepuasan-masyarakat/list-survey/[id]/edit/page.tsx delete mode 100644 src/app/admin/(dashboard)/landing-page/indeks-kepuasan-masyarakat/list-survey/[id]/page.tsx delete mode 100644 src/app/admin/(dashboard)/landing-page/indeks-kepuasan-masyarakat/list-survey/create/page.tsx delete mode 100644 src/app/admin/(dashboard)/landing-page/indeks-kepuasan-masyarakat/list-survey/page.tsx delete mode 100644 src/app/api/[[...slugs]]/_lib/desa/berita/category.ts create mode 100644 src/app/api/[[...slugs]]/_lib/desa/berita/kategori-berita/create.ts create mode 100644 src/app/api/[[...slugs]]/_lib/desa/berita/kategori-berita/del.ts create mode 100644 src/app/api/[[...slugs]]/_lib/desa/berita/kategori-berita/findMany.ts create mode 100644 src/app/api/[[...slugs]]/_lib/desa/berita/kategori-berita/findUnique.ts create mode 100644 src/app/api/[[...slugs]]/_lib/desa/berita/kategori-berita/index.ts create mode 100644 src/app/api/[[...slugs]]/_lib/desa/berita/kategori-berita/updt.ts delete mode 100644 src/app/api/[[...slugs]]/_lib/landing_page/indeks-kepuasan-masyarakat/age/create.ts delete mode 100644 src/app/api/[[...slugs]]/_lib/landing_page/indeks-kepuasan-masyarakat/age/del.ts delete mode 100644 src/app/api/[[...slugs]]/_lib/landing_page/indeks-kepuasan-masyarakat/age/findMany.ts delete mode 100644 src/app/api/[[...slugs]]/_lib/landing_page/indeks-kepuasan-masyarakat/age/findUnique.ts delete mode 100644 src/app/api/[[...slugs]]/_lib/landing_page/indeks-kepuasan-masyarakat/age/index.ts delete mode 100644 src/app/api/[[...slugs]]/_lib/landing_page/indeks-kepuasan-masyarakat/age/updt.ts delete mode 100644 src/app/api/[[...slugs]]/_lib/landing_page/indeks-kepuasan-masyarakat/gender/create.ts delete mode 100644 src/app/api/[[...slugs]]/_lib/landing_page/indeks-kepuasan-masyarakat/gender/del.ts delete mode 100644 src/app/api/[[...slugs]]/_lib/landing_page/indeks-kepuasan-masyarakat/gender/findMany.ts delete mode 100644 src/app/api/[[...slugs]]/_lib/landing_page/indeks-kepuasan-masyarakat/gender/findUnique.ts delete mode 100644 src/app/api/[[...slugs]]/_lib/landing_page/indeks-kepuasan-masyarakat/gender/index.ts delete mode 100644 src/app/api/[[...slugs]]/_lib/landing_page/indeks-kepuasan-masyarakat/gender/updt.ts delete mode 100644 src/app/api/[[...slugs]]/_lib/landing_page/indeks-kepuasan-masyarakat/index.ts delete mode 100644 src/app/api/[[...slugs]]/_lib/landing_page/indeks-kepuasan-masyarakat/monthly-stat/create.ts delete mode 100644 src/app/api/[[...slugs]]/_lib/landing_page/indeks-kepuasan-masyarakat/monthly-stat/del.ts delete mode 100644 src/app/api/[[...slugs]]/_lib/landing_page/indeks-kepuasan-masyarakat/monthly-stat/findMany.ts delete mode 100644 src/app/api/[[...slugs]]/_lib/landing_page/indeks-kepuasan-masyarakat/monthly-stat/findUnique.ts delete mode 100644 src/app/api/[[...slugs]]/_lib/landing_page/indeks-kepuasan-masyarakat/monthly-stat/index.ts delete mode 100644 src/app/api/[[...slugs]]/_lib/landing_page/indeks-kepuasan-masyarakat/monthly-stat/updt.ts delete mode 100644 src/app/api/[[...slugs]]/_lib/landing_page/indeks-kepuasan-masyarakat/response/create.ts delete mode 100644 src/app/api/[[...slugs]]/_lib/landing_page/indeks-kepuasan-masyarakat/response/del.ts delete mode 100644 src/app/api/[[...slugs]]/_lib/landing_page/indeks-kepuasan-masyarakat/response/findMany.ts delete mode 100644 src/app/api/[[...slugs]]/_lib/landing_page/indeks-kepuasan-masyarakat/response/findUnique.ts delete mode 100644 src/app/api/[[...slugs]]/_lib/landing_page/indeks-kepuasan-masyarakat/response/index.ts delete mode 100644 src/app/api/[[...slugs]]/_lib/landing_page/indeks-kepuasan-masyarakat/response/updt.ts delete mode 100644 src/app/api/[[...slugs]]/_lib/landing_page/indeks-kepuasan-masyarakat/survey/create.ts delete mode 100644 src/app/api/[[...slugs]]/_lib/landing_page/indeks-kepuasan-masyarakat/survey/del.ts delete mode 100644 src/app/api/[[...slugs]]/_lib/landing_page/indeks-kepuasan-masyarakat/survey/findMany.ts delete mode 100644 src/app/api/[[...slugs]]/_lib/landing_page/indeks-kepuasan-masyarakat/survey/findUnique.ts delete mode 100644 src/app/api/[[...slugs]]/_lib/landing_page/indeks-kepuasan-masyarakat/survey/index.ts delete mode 100644 src/app/api/[[...slugs]]/_lib/landing_page/indeks-kepuasan-masyarakat/survey/updt.ts create mode 100644 src/app/darmasaba/(pages)/desa/berita/_lib/layoutTabs.tsx rename src/app/darmasaba/(pages)/desa/berita/{(tabs)/budaya.tsx => budaya/page.tsx} (100%) rename src/app/darmasaba/(pages)/desa/berita/{(tabs)/ekonomi.tsx => ekonomi/page.tsx} (100%) create mode 100644 src/app/darmasaba/(pages)/desa/berita/layout.tsx delete mode 100644 src/app/darmasaba/(pages)/desa/berita/page.tsx create mode 100644 src/app/darmasaba/(pages)/desa/berita/page2.txt rename src/app/darmasaba/(pages)/desa/berita/{(tabs)/pembangunan.tsx => pembangunan/page.tsx} (100%) rename src/app/darmasaba/(pages)/desa/berita/{(tabs)/pemerintahan.tsx => pemerintahan/page.tsx} (100%) rename src/app/darmasaba/(pages)/desa/berita/{(tabs)/semua.tsx => semua/page.tsx} (100%) rename src/app/darmasaba/(pages)/desa/berita/{(tabs)/sosial.tsx => sosial/page.tsx} (100%) rename src/app/darmasaba/(pages)/desa/berita/{(tabs)/teknologi.tsx => teknologi/page.tsx} (100%) diff --git a/prisma/schema.prisma b/prisma/schema.prisma index e2e06a91..fbbe82dd 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -221,81 +221,6 @@ model KategoriPrestasiDesa { PrestasiDesa PrestasiDesa[] } -//========================================= INDEKS KEPUASAN MASYARAKAT ========================================= // -// Entitas Survey -model Survey { - id String @id @default(cuid()) - title String // Judul survei - totalRespondents Int // Total jumlah responden - averageScore Float // Rata-rata skor - monthlyStats MonthlyStat[] - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - deletedAt DateTime @default(now()) - isActive Boolean @default(true) -} - -// Entitas Statistik Bulanan -model MonthlyStat { - id String @id @default(cuid()) - month String // Nama bulan (e.g., "Januari", "Februari") - respondentsCount Int // Jumlah responden per bulan - surveyId String @unique(map: "monthly_stat_survey_id_month_key") - survey Survey @relation(fields: [surveyId], references: [id]) - AgeStat AgeStat[] - ResponseStat ResponseStat[] - genderStat genderStat[] - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - deletedAt DateTime @default(now()) - isActive Boolean @default(true) -} - -// Entitas Gender - -model genderStat { - id String @id @default(cuid()) - laki Int - perempuan Int - percentLaki Float - percentPerempuan Float - total Int - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - deletedAt DateTime @default(now()) - isActive Boolean @default(true) - MonthlyStat MonthlyStat? @relation(fields: [monthlyStatId], references: [id]) - monthlyStatId String? -} - -// Entitas Age - -model AgeStat { - id String @id @default(cuid()) - group String // "18-44", "45+" dll - count Int - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - deletedAt DateTime @default(now()) - isActive Boolean @default(true) - MonthlyStat MonthlyStat? @relation(fields: [monthlyStatId], references: [id]) - monthlyStatId String? -} - -// Entitas Response - -model ResponseStat { - id String @id @default(cuid()) - label String // BAIK / BURUK - count Int - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - deletedAt DateTime @default(now()) - isActive Boolean @default(true) - MonthlyStat MonthlyStat? @relation(fields: [monthlyStatId], references: [id]) - monthlyStatId String? -} - //========================================= MENU PPID ========================================= // //========================================= STRUKTUR PPID ========================================= // @@ -732,16 +657,16 @@ model PelayananPendudukNonPermanen { // ========================================= PENGHARGAAN ========================================= // model Penghargaan { - id String @id @default(cuid()) + id String @id @default(cuid()) name String juara String - deskripsi String @db.Text + deskripsi String @db.Text image FileStorage? @relation(fields: [imageId], references: [id]) imageId String? - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - deletedAt DateTime @default(now()) - isActive Boolean @default(true) + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + deletedAt DateTime @default(now()) + isActive Boolean @default(true) } // ========================================= MENU KESEHATAN ========================================= // diff --git a/src/app/admin/(dashboard)/_state/desa/berita.ts b/src/app/admin/(dashboard)/_state/desa/berita.ts index d49562b4..829243bb 100644 --- a/src/app/admin/(dashboard)/_state/desa/berita.ts +++ b/src/app/admin/(dashboard)/_state/desa/berita.ts @@ -22,19 +22,6 @@ const defaultForm = { kategoriBeritaId: "", }; -// 3. Kategori proxy -const category = proxy({ - findMany: { - data: [] as Prisma.KategoriBeritaGetPayload<{ omit: { isActive: true } }>[], - async load() { - const res = await ApiFetch.api.desa.berita.category["find-many"].get(); - if (res.status === 200) { - category.findMany.data = res.data?.data ?? []; - } - }, - }, -}); - // 4. Berita proxy const berita = proxy({ create: { @@ -314,14 +301,238 @@ const berita = proxy({ } }, } - - - }); +//=============== Kategori Berita =============== + +const templateKategoriBerita = z.object({ + name: z.string().min(1, "Nama harus diisi"), +}); + +const defaultKategoriBerita = { + name: "", +}; + +const kategoriBerita = proxy({ + create: { + form: { ...defaultKategoriBerita }, + loading: false, + async create() { + const cek = templateKategoriBerita.safeParse(kategoriBerita.create.form); + if (!cek.success) { + const err = `[${cek.error.issues + .map((v) => `${v.path.join(".")}`) + .join("\n")}] required`; + return toast.error(err); + } + + try { + kategoriBerita.create.loading = true; + const res = + await ApiFetch.api.desa.kategoriberita[ + "create" + ].post(kategoriBerita.create.form); + if (res.status === 200) { + kategoriBerita.findMany.load(); + return toast.success("Data Kategori Berita Berhasil Dibuat"); + } + console.log(res); + return toast.error("failed create"); + } catch (error) { + console.log(error); + return toast.error("failed create"); + } finally { + kategoriBerita.create.loading = false; + } + }, + }, + findMany: { + data: [] as Prisma.KategoriBeritaGetPayload<{ + omit: { + isActive: true; + }; + }>[], + loading: false, + async load() { + const res = + await ApiFetch.api.desa.kategoriberita[ + "findMany" + ].get(); + if (res.status === 200) { + kategoriBerita.findMany.data = res.data?.data ?? []; + } + }, + }, + findUnique: { + data: null as Prisma.KategoriBeritaGetPayload<{ + omit: { + isActive: true; + }; + }> | null, + loading: false, + async load(id: string) { + try { + const res = await fetch( + `/api/desa/kategoriberita/${id}` + ); + if (res.ok) { + const data = await res.json(); + kategoriBerita.findUnique.data = data.data ?? null; + } else { + console.error("Failed to fetch data", res.status, res.statusText); + kategoriBerita.findUnique.data = null; + } + } catch (error) { + console.error("Error fetching data:", error); + kategoriBerita.findUnique.data = null; + } + }, + }, + delete: { + loading: false, + async delete(id: string) { + if (!id) return toast.warn("ID tidak valid"); + + try { + kategoriBerita.delete.loading = true; + + const response = await fetch( + `/api/desa/kategoriberita/del/${id}`, + { + method: "DELETE", + headers: { + "Content-Type": "application/json", + }, + } + ); + + const result = await response.json(); + + if (response.ok && result?.success) { + toast.success( + result.message || "Data Kategori Berita berhasil dihapus" + ); + await kategoriBerita.findMany.load(); // refresh list + } else { + toast.error(result?.message || "Gagal menghapus Data Kategori Berita"); + } + } catch (error) { + console.error("Gagal delete:", error); + toast.error("Terjadi kesalahan saat menghapus Data Kategori Berita"); + } finally { + kategoriBerita.delete.loading = false; + } + }, + }, + update: { + id: "", + form: { ...defaultKategoriBerita }, + loading: false, + async load(id: string) { + if (!id) { + toast.warn("ID tidak valid"); + return null; + } + + try { + const response = await fetch( + `/api/desa/kategoriberita/${id}`, + { + method: "GET", + headers: { + "Content-Type": "application/json", + }, + } + ); + if (!response.ok) { + throw new Error(`HTTP error! status: ${response.status}`); + } + + const result = await response.json(); + + if (result?.success) { + const data = result.data; + this.id = data.id; + this.form = { + name: data.name, + }; + return data; // Return the loaded data + } else { + throw new Error(result?.message || "Gagal memuat data"); + } + } catch (error) { + console.error("Error loading kategori berita:", error); + toast.error( + error instanceof Error ? error.message : "Gagal memuat data" + ); + return null; + } + }, + async update() { + const cek = templateKategoriBerita.safeParse(kategoriBerita.update.form); + if (!cek.success) { + const err = `[${cek.error.issues + .map((v) => `${v.path.join(".")}`) + .join("\n")}] required`; + toast.error(err); + return false; + } + + try { + kategoriBerita.update.loading = true; + + const response = await fetch( + `/api/desa/kategoriberita/${this.id}`, + { + method: "PUT", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + name: this.form.name, + }), + } + ); + + if (!response.ok) { + const errorData = await response.json().catch(() => ({})); + throw new Error( + errorData.message || `HTTP error! status: ${response.status}` + ); + } + + const result = await response.json(); + + if (result.success) { + toast.success("Berhasil update data kategori berita"); + await kategoriBerita.findMany.load(); // refresh list + return true; + } else { + throw new Error(result.message || "Gagal update data kategori berita"); + } + } catch (error) { + console.error("Error updating data kategori berita:", error); + toast.error( + error instanceof Error + ? error.message + : "Terjadi kesalahan saat update data kategori berita" + ); + return false; + } finally { + kategoriBerita.update.loading = false; + } + }, + reset() { + kategoriBerita.update.id = ""; + kategoriBerita.update.form = { ...defaultKategoriBerita }; + }, + }, +}); + + // 5. State global const stateDashboardBerita = proxy({ - category, + kategoriBerita, berita, }); diff --git a/src/app/admin/(dashboard)/_state/landing-page/indeks-kepuasan-masyarakat.ts b/src/app/admin/(dashboard)/_state/landing-page/indeks-kepuasan-masyarakat.ts deleted file mode 100644 index f181ad2d..00000000 --- a/src/app/admin/(dashboard)/_state/landing-page/indeks-kepuasan-masyarakat.ts +++ /dev/null @@ -1,1180 +0,0 @@ -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 templateSurveyForm = z.object({ - title: z.string().min(1, "Judul wajib diisi"), - totalRespondents: z.number().min(0), - averageScore: z.number().min(0), -}); - -const defaultSurveyForm = { - title: "", - totalRespondents: 0, - averageScore: 0, -}; - -const surveyState = proxy({ - create: { - form: { ...defaultSurveyForm }, - loading: false, - async create() { - const cek = templateSurveyForm.safeParse(surveyState.create.form); - if (!cek.success) return toast.error(cek.error.errors[0].message); - - try { - surveyState.create.loading = true; - const res = - await ApiFetch.api.landingpage.indekskepuasanmasyarakat.survey.create.post( - { ...surveyState.create.form } - ); - - if (res.status === 200) { - toast.success("Data survey berhasil ditambahkan"); - surveyState.findMany.load(); - } else { - toast.error("Gagal menambahkan data survey"); - } - } catch (error) { - toast.error("Terjadi kesalahan saat membuat survey"); - console.error(error); - } finally { - surveyState.create.loading = false; - } - }, - }, - - findMany: { - data: null as - | Prisma.SurveyGetPayload<{ - include: { monthlyStats: true }; - }>[] - | null, - loading: false, - async load() { - try { - surveyState.findMany.loading = true; - const res = - await ApiFetch.api.landingpage.indekskepuasanmasyarakat.survey.findMany.get(); - if (res.status === 200) { - surveyState.findMany.data = res.data?.data ?? []; - } - } catch (error) { - toast.error("Gagal mengambil data survey"); - console.error(error); - } finally { - surveyState.findMany.loading = false; - } - }, - }, - - findUnique: { - data: null as Prisma.SurveyGetPayload<{ - include: { monthlyStats: true }; - }> | null, - async load(id: string) { - try { - const res = await fetch( - `/api/landingpage/indekskepuasanmasyarakat/survey/${id}` - ); - if (res.ok) { - const data = await res.json(); - surveyState.findUnique.data = data.data ?? null; - } else { - console.error("Failed to fetch data", res.status, res.statusText); - surveyState.findUnique.data = null; - } - } catch (error) { - console.error("Error fetching data:", error); - surveyState.findUnique.data = null; - } - }, - }, - - edit: { - id: "", - form: { ...defaultSurveyForm }, - loading: false, - - async load(id: string) { - if (!id) { - toast.warn("ID tidak valid"); - return null; - } - - try { - surveyState.edit.loading = true; - - const response = await fetch( - `/api/landingpage/indekskepuasanmasyarakat/survey/${id}`, - { - method: "GET", - headers: { - "Content-Type": "application/json", - }, - } - ); - if (!response.ok) { - throw new Error(`HTTP error! status: ${response.status}`); - } - const result = await response.json(); - if (result?.success) { - const data = result.data; - this.id = data.id; - this.form = { - title: data.title, - totalRespondents: data.totalRespondents, - averageScore: data.averageScore, - }; - return data; - } else { - throw new Error(result?.message || "Gagal memuat data"); - } - } catch (error) { - console.error("Error loading survey:", error); - toast.error( - error instanceof Error ? error.message : "Gagal memuat data" - ); - return null; - } finally { - surveyState.edit.loading = false; - } - }, - - async update() { - const cek = templateSurveyForm.safeParse(surveyState.edit.form); - if (!cek.success) { - const err = `[${cek.error.issues - .map((v) => `${v.path.join(".")}`) - .join("\n")}] required`; - return toast.error(err); - } - - try { - surveyState.edit.loading = true; - const response = await fetch( - `/api/landingpage/indekskepuasanmasyarakat/survey/${this.id}`, - { - method: "PUT", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - title: this.form.title, - totalRespondents: this.form.totalRespondents, - averageScore: this.form.averageScore, - }), - } - ); - if (!response.ok) { - const errorData = await response.json().catch(() => ({})); - throw new Error( - errorData.message || `HTTP error! status: ${response.status}` - ); - } - const result = await response.json(); - if (result.success) { - toast.success("Berhasil update survey"); - await surveyState.findMany.load(); // refresh list - return true; - } else { - throw new Error(result.message || "Gagal mengupdate survey"); - } - } catch (error) { - console.error("Error updating survey:", error); - toast.error( - error instanceof Error ? error.message : "Gagal mengupdate survey" - ); - return false; - } finally { - surveyState.edit.loading = false; - } - }, - reset() { - surveyState.edit.id = ""; - surveyState.edit.form = { ...defaultSurveyForm }; - }, - }, - - delete: { - loading: false, - async byId(id: string) { - if (!id) return toast.warn("ID tidak valid"); - - try { - surveyState.delete.loading = true; - - const response = await fetch( - `/api/landingpage/indekskepuasanmasyarakat/survey/del/${id}`, - { - method: "DELETE", - headers: { - "Content-Type": "application/json", - }, - } - ); - - const result = await response.json(); - - if (response.ok && result?.success) { - toast.success(result.message || "survey berhasil dihapus"); - await surveyState.findMany.load(); // refresh list - } else { - toast.error(result?.message || "Gagal menghapus survey"); - } - } catch (error) { - console.error("Gagal delete:", error); - toast.error("Terjadi kesalahan saat menghapus survey"); - } finally { - surveyState.delete.loading = false; - } - }, - }, -}); - -//========================================= MONTHLY STAT ========================================= // - -const templateMonthlyForm = z.object({ - month: z.string().min(1, "Bulan wajib diisi"), - respondentsCount: z.number().min(0, "Jumlah responden minimal 0"), - surveyId: z.string().min(1, "Survey ID wajib diisi"), -}); - -const defaultMonthlyForm = { - month: "", - respondentsCount: 0, - surveyId: "", -}; - -const monthlyStatState = proxy({ - create: { - form: { ...defaultMonthlyForm }, - loading: false, - async create() { - const cek = templateMonthlyForm.safeParse(monthlyStatState.create.form); - if (!cek.success) { - toast.error(cek.error.errors[0].message); - return; - } - - try { - monthlyStatState.create.loading = true; - const res = - await ApiFetch.api.landingpage.indekskepuasanmasyarakat.monthlystat.create.post( - { - ...monthlyStatState.create.form, - } - ); - - if (res.status === 200) { - toast.success("Data statistik bulanan berhasil ditambahkan"); - monthlyStatState.findMany.load(); - } else { - toast.error("Gagal menambahkan data statistik bulanan"); - } - } catch (error) { - console.error(error); - toast.error("Terjadi kesalahan saat membuat data bulanan"); - } finally { - monthlyStatState.create.loading = false; - } - }, - }, - - findMany: { - data: null as - | Prisma.MonthlyStatGetPayload<{ include: { survey: true } }>[] - | null, - loading: false, - async load() { - try { - monthlyStatState.findMany.loading = true; - const res = - await ApiFetch.api.landingpage.indekskepuasanmasyarakat.monthlystat.findMany.get(); - if (res.status === 200) { - monthlyStatState.findMany.data = res.data?.data ?? []; - } - } catch (error) { - console.error(error); - toast.error("Gagal mengambil data statistik bulanan"); - } finally { - monthlyStatState.findMany.loading = false; - } - }, - }, - - findUnique: { - data: null as Prisma.MonthlyStatGetPayload<{ - include: { survey: true }; - }> | null, - async load(id: string) { - try { - const res = await fetch( - `/api/landingpage/indekskepuasanmasyarakat/monthlystat/${id}` - ); - if (res.ok) { - const data = await res.json(); - monthlyStatState.findUnique.data = data.data ?? null; - } else { - console.error("Failed to fetch monthlyStat", res.status); - } - } catch (error) { - console.error("Error fetching monthlyStat:", error); - } - }, - }, - - edit: { - id: "", - form: { ...defaultMonthlyForm }, - loading: false, - - async load(id: string) { - if (!id) { - toast.warn("ID tidak valid"); - return null; - } - - try { - monthlyStatState.edit.loading = true; - - const response = await fetch( - `/api/landingpage/indekskepuasanmasyarakat/monthlystat/${id}`, - { - method: "GET", - headers: { - "Content-Type": "application/json", - }, - } - ); - if (!response.ok) { - throw new Error(`HTTP error! status: ${response.status}`); - } - const result = await response.json(); - if (result?.success) { - const data = result.data; - this.id = data.id; - this.form = { - month: data.month, - respondentsCount: data.respondentsCount, - surveyId: data.surveyId, - }; - return data; - } else { - throw new Error(result?.message || "Gagal memuat data"); - } - } catch (error) { - console.error("Error loading survey:", error); - toast.error( - error instanceof Error ? error.message : "Gagal memuat data" - ); - return null; - } finally { - monthlyStatState.edit.loading = false; - } - }, - - async update() { - const cek = templateMonthlyForm.safeParse(monthlyStatState.edit.form); - if (!cek.success) { - const err = `[${cek.error.issues - .map((v) => `${v.path.join(".")}`) - .join("\n")}] required`; - return toast.error(err); - } - - try { - monthlyStatState.edit.loading = true; - const response = await fetch( - `/api/landingpage/indekskepuasanmasyarakat/monthlystat/${this.id}`, - { - method: "PUT", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - month: this.form.month, - respondentsCount: this.form.respondentsCount, - surveyId: this.form.surveyId, - }), - } - ); - if (!response.ok) { - const errorData = await response.json().catch(() => ({})); - throw new Error( - errorData.message || `HTTP error! status: ${response.status}` - ); - } - const result = await response.json(); - if (result.success) { - toast.success("Berhasil update survey"); - await monthlyStatState.findMany.load(); // refresh list - return true; - } else { - throw new Error(result.message || "Gagal mengupdate survey"); - } - } catch (error) { - console.error("Error updating survey:", error); - toast.error( - error instanceof Error ? error.message : "Gagal mengupdate survey" - ); - return false; - } finally { - monthlyStatState.edit.loading = false; - } - }, - reset() { - monthlyStatState.edit.id = ""; - monthlyStatState.edit.form = { ...defaultMonthlyForm }; - }, - }, - - delete: { - loading: false, - async byId(id: string) { - if (!id) return toast.warn("ID tidak valid"); - - try { - monthlyStatState.delete.loading = true; - const res = await fetch( - `/api/landingpage/indekskepuasanmasyarakat/monthlystat/del/${id}`, - { - method: "DELETE", - headers: { "Content-Type": "application/json" }, - } - ); - - const result = await res.json(); - if (res.ok && result?.success) { - toast.success("Data berhasil dihapus"); - monthlyStatState.findMany.load(); - } else { - toast.error(result.message || "Gagal menghapus data"); - } - } catch (error) { - console.error("Delete error:", error); - toast.error("Terjadi kesalahan saat delete"); - } finally { - monthlyStatState.delete.loading = false; - } - }, - }, -}); - -//========================================= AGE STAT ========================================= // - -const templateAgeStatForm = z.object({ - group: z.string().min(1, "Group wajib diisi"), - count: z.number().min(0, "Jumlah wajib diisi"), - monthlyStatId: z.string().min(1, "Monthly Stat ID wajib diisi"), -}); - -const defaultAgeStatForm = { - group: "", - count: 0, - monthlyStatId: "", -}; - -const ageStatState = proxy({ - create: { - form: { ...defaultAgeStatForm }, - loading: false, - async create() { - const cek = templateAgeStatForm.safeParse(ageStatState.create.form); - if (!cek.success) { - const err = `[${cek.error.issues - .map((v) => `${v.path.join(".")}`) - .join("\n")}] required`; - return toast.error(err); - } - try { - ageStatState.create.loading = true; - const res = await ApiFetch.api.landingpage.indekskepuasanmasyarakat.age[ - "create" - ].post({ - ...ageStatState.create.form, - }); - - if (res.status === 200) { - ageStatState.findMany.load(); - return toast.success("Data berhasil ditambahkan"); - } - return toast.error("Gagal menambahkan data"); - } catch (error) { - console.log(error); - toast.error("Gagal menambahkan data"); - } finally { - ageStatState.create.loading = false; - } - }, - }, - findMany: { - data: null as Array< - Prisma.AgeStatGetPayload<{ - include: { - MonthlyStat: true; - }; - }> - > | null, - async load() { - const res = await ApiFetch.api.landingpage.indekskepuasanmasyarakat.age[ - "findMany" - ].get(); - if (res.status === 200) { - ageStatState.findMany.data = res.data?.data ?? []; - } - }, - }, - findUnique: { - data: null as Prisma.AgeStatGetPayload<{ - include: { - MonthlyStat: true; - }; - }> | null, - async load(id: string) { - try { - const res = await fetch( - `/api/landingpage/indekskepuasanmasyarakat/age/${id}` - ); - if (res.ok) { - const data = await res.json(); - ageStatState.findUnique.data = data.data ?? null; - } else { - console.error("Failed to fetch data", res.status, res.statusText); - ageStatState.findUnique.data = null; - } - } catch (error) { - console.error("Error fetching data:", error); - ageStatState.findUnique.data = null; - } - }, - }, - delete: { - loading: false, - async byId(id: string) { - if (!id) return toast.warn("ID tidak valid"); - - try { - ageStatState.delete.loading = true; - - const response = await fetch( - `/api/landingpage/indekskepuasanmasyarakat/age/del/${id}`, - { - method: "DELETE", - headers: { - "Content-Type": "application/json", - }, - } - ); - - const result = await response.json(); - - if (response.ok && result?.success) { - toast.success(result.message || "age berhasil dihapus"); - await ageStatState.findMany.load(); // refresh list - } else { - toast.error(result?.message || "Gagal menghapus age"); - } - } catch (error) { - console.error("Gagal delete:", error); - toast.error("Terjadi kesalahan saat menghapus age"); - } finally { - ageStatState.delete.loading = false; - } - }, - }, - edit: { - id: "", - form: { ...defaultAgeStatForm }, - loading: false, - - async load(id: string) { - if (!id) { - toast.warn("ID tidak valid"); - return null; - } - - try { - ageStatState.edit.loading = true; - - const response = await fetch( - `/api/landingpage/indekskepuasanmasyarakat/age/${id}`, - { - method: "GET", - headers: { - "Content-Type": "application/json", - }, - } - ); - if (!response.ok) { - throw new Error(`HTTP error! status: ${response.status}`); - } - const result = await response.json(); - if (result?.success) { - const data = result.data; - this.id = data.id; - this.form = { - group: data.group, - count: data.count, - monthlyStatId: data.monthlyStatId, - }; - return data; - } else { - throw new Error(result?.message || "Gagal memuat data"); - } - } catch (error) { - console.error("Error loading ages :", error); - toast.error( - error instanceof Error ? error.message : "Gagal memuat data" - ); - return null; - } finally { - ageStatState.edit.loading = false; - } - }, - - async update() { - const cek = templateAgeStatForm.safeParse(ageStatState.edit.form); - if (!cek.success) { - const err = `[${cek.error.issues - .map((v) => `${v.path.join(".")}`) - .join("\n")}] required`; - return toast.error(err); - } - - try { - ageStatState.edit.loading = true; - const response = await fetch( - `/api/landingpage/indekskepuasanmasyarakat/age/${this.id}`, - { - method: "PUT", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - group: this.form.group, - count: this.form.count, - monthlyStatId: this.form.monthlyStatId, - }), - } - ); - if (!response.ok) { - const errorData = await response.json().catch(() => ({})); - throw new Error( - errorData.message || `HTTP error! status: ${response.status}` - ); - } - const result = await response.json(); - if (result.success) { - toast.success("Berhasil update age"); - await ageStatState.findMany.load(); // refresh list - return true; - } else { - throw new Error(result.message || "Gagal mengupdate age"); - } - } catch (error) { - console.error("Error updating age:", error); - toast.error( - error instanceof Error ? error.message : "Gagal mengupdate age" - ); - return false; - } finally { - ageStatState.edit.loading = false; - } - }, - reset() { - ageStatState.edit.id = ""; - ageStatState.edit.form = { ...defaultAgeStatForm }; - }, - }, -}); - -//========================================= GENDER STAT ========================================= // - -const templateGenderStatForm = z.object({ - laki: z.number().min(0, "Jumlah wajib diisi"), - perempuan: z.number().min(0, "Jumlah wajib diisi"), - monthlyStatId: z.string().min(1, "Monthly Stat ID wajib diisi"), - total: z.number().min(0, "Jumlah wajib diisi"), - percentLaki: z.number().min(0, "Jumlah wajib diisi"), - percentPerempuan: z.number().min(0, "Jumlah wajib diisi"), -}); - -const defaultGenderStatForm = { - laki: 0, - perempuan: 0, - total: 0, - percentLaki: 0, - percentPerempuan: 0, - monthlyStatId: "", -}; - -const genderStatState = proxy({ - create: { - form: { ...defaultGenderStatForm }, - loading: false, - async create() { - const cek = templateGenderStatForm.safeParse(genderStatState.create.form); - if (!cek.success) { - const err = `[${cek.error.issues - .map((v) => `${v.path.join(".")}`) - .join("\n")}] required`; - return toast.error(err); - } - - const { laki, perempuan } = genderStatState.create.form; - const total = laki + perempuan; - const percentLaki = total > 0 ? Number(((laki / total) * 100).toFixed(2)) : 0; - const percentPerempuan = total > 0 ? Number(((perempuan / total) * 100).toFixed(2)) : 0; - - try { - genderStatState.create.loading = true; - const res = await fetch('/api/landingpage/indekskepuasanmasyarakat/gender/create', { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ - ...genderStatState.create.form, - total, - percentLaki, - percentPerempuan, - }), - }); - - const result = await res.json(); - if (result.success) { - toast.success("Data berhasil ditambahkan"); - genderStatState.findMany.load(); // refresh list - } else { - toast.error(result.message); - } - } catch (err) { - toast.error("Gagal tambah data"); - console.error(err); - } finally { - genderStatState.create.loading = false; - } - }, - }, - findMany: { - data: null as Array< - Prisma.genderStatGetPayload<{ - include: { - MonthlyStat: true; - }; - }> - > | null, - async load() { - const res = - await ApiFetch.api.landingpage.indekskepuasanmasyarakat.gender[ - "findMany" - ].get(); - if (res.status === 200) { - genderStatState.findMany.data = res.data?.data ?? []; - } - }, - }, - findUnique: { - data: null as Prisma.genderStatGetPayload<{ - include: { - MonthlyStat: true; - }; - }> | null, - async load(id: string) { - try { - const res = await fetch( - `/api/landingpage/indekskepuasanmasyarakat/gender/${id}` - ); - if (res.ok) { - const data = await res.json(); - genderStatState.findUnique.data = data.data ?? null; - } else { - console.error("Failed to fetch data", res.status, res.statusText); - genderStatState.findUnique.data = null; - } - } catch (error) { - console.error("Error fetching data:", error); - genderStatState.findUnique.data = null; - } - }, - }, - delete: { - loading: false, - async byId(id: string) { - if (!id) return toast.warn("ID tidak valid"); - - try { - genderStatState.delete.loading = true; - - const response = await fetch( - `/api/landingpage/indekskepuasanmasyarakat/gender/del/${id}`, - { - method: "DELETE", - headers: { - "Content-Type": "application/json", - }, - } - ); - - const result = await response.json(); - - if (response.ok && result?.success) { - toast.success(result.message || "gender berhasil dihapus"); - await genderStatState.findMany.load(); // refresh list - } else { - toast.error(result?.message || "Gagal menghapus gender"); - } - } catch (error) { - console.error("Gagal delete:", error); - toast.error("Terjadi kesalahan saat menghapus gender"); - } finally { - genderStatState.delete.loading = false; - } - }, - }, - edit: { - id: "", - form: { ...defaultGenderStatForm }, - loading: false, - - async load(id: string) { - if (!id) { - toast.warn("ID tidak valid"); - return null; - } - - try { - genderStatState.edit.loading = true; - - const response = await fetch( - `/api/landingpage/indekskepuasanmasyarakat/gender/${id}`, - { - method: "GET", - headers: { - "Content-Type": "application/json", - }, - } - ); - if (!response.ok) { - throw new Error(`HTTP error! status: ${response.status}`); - } - const result = await response.json(); - if (result?.success) { - const data = result.data; - this.id = data.id; - this.form = { - laki: data.laki, - perempuan: data.perempuan, - monthlyStatId: data.monthlyStatId, - total: data.total, - percentLaki: Number(data.percentLaki), - percentPerempuan: Number(data.percentPerempuan), - }; - return data; - } else { - throw new Error(result?.message || "Gagal memuat data"); - } - } catch (error) { - console.error("Error loading ages :", error); - toast.error( - error instanceof Error ? error.message : "Gagal memuat data" - ); - return null; - } finally { - genderStatState.edit.loading = false; - } - }, - - async update() { - const { laki, perempuan } = genderStatState.edit.form; - const total = laki + perempuan; - const percentLaki = total > 0 ? Number(((laki / total) * 100).toFixed(2)) : 0; - const percentPerempuan = total > 0 ? Number(((perempuan / total) * 100).toFixed(2)) : 0; - - try { - genderStatState.edit.loading = true; - const res = await fetch(`/api/landingpage/indekskepuasanmasyarakat/gender/${genderStatState.edit.id}`, { - method: 'PUT', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ - ...genderStatState.edit.form, - total, - percentLaki: Number(percentLaki), - percentPerempuan: Number(percentPerempuan), - }), - }); - if (!res.ok) { - const errorData = await res.json().catch(() => ({})); - throw new Error( - errorData.message || `HTTP error! status: ${res.status}` - ); - } - const result = await res.json(); - if (result.success) { - toast.success("Berhasil update gender"); - await genderStatState.findMany.load(); // refresh list - return true; - } else { - throw new Error(result.message || "Gagal mengupdate gender"); - } - } catch (error) { - console.error("Error updating gender:", error); - toast.error( - error instanceof Error ? error.message : "Gagal mengupdate gender" - ); - return false; - } finally { - genderStatState.edit.loading = false; - } - }, - reset() { - genderStatState.edit.id = ""; - genderStatState.edit.form = { ...defaultGenderStatForm }; - }, - }, -}); - -//========================================= RESPONSE STAT ========================================= // - -const templateResponseStatForm = z.object({ - label: z.string().min(1, "Label wajib diisi"), - count: z.number().min(0, "Jumlah wajib diisi"), - monthlyStatId: z.string().min(1, "Monthly Stat ID wajib diisi"), -}); - -const defaultResponseStatForm = { - label: "", - count: 0, - monthlyStatId: "", -}; - -const responseStatState = proxy({ - create: { - form: { ...defaultResponseStatForm }, - loading: false, - async create() { - const cek = templateResponseStatForm.safeParse( - responseStatState.create.form - ); - if (!cek.success) { - const err = `[${cek.error.issues - .map((v) => `${v.path.join(".")}`) - .join("\n")}] required`; - return toast.error(err); - } - try { - responseStatState.create.loading = true; - const res = - await ApiFetch.api.landingpage.indekskepuasanmasyarakat.response[ - "create" - ].post({ - ...responseStatState.create.form, - }); - - if (res.status === 200) { - responseStatState.findMany.load(); - return toast.success("Data berhasil ditambahkan"); - } - return toast.error("Gagal menambahkan data"); - } catch (error) { - console.log(error); - toast.error("Gagal menambahkan data"); - } finally { - responseStatState.create.loading = false; - } - }, - }, - findMany: { - data: null as Array< - Prisma.ResponseStatGetPayload<{ - include: { - MonthlyStat: true; - }; - }> - > | null, - async load() { - const res = - await ApiFetch.api.landingpage.indekskepuasanmasyarakat.response[ - "findMany" - ].get(); - if (res.status === 200) { - responseStatState.findMany.data = res.data?.data ?? []; - } - }, - }, - findUnique: { - data: null as Prisma.ResponseStatGetPayload<{ - include: { - MonthlyStat: true; - }; - }> | null, - async load(id: string) { - try { - const res = await fetch( - `/api/landingpage/indekskepuasanmasyarakat/response/${id}` - ); - if (res.ok) { - const data = await res.json(); - responseStatState.findUnique.data = data.data ?? null; - } else { - console.error("Failed to fetch data", res.status, res.statusText); - responseStatState.findUnique.data = null; - } - } catch (error) { - console.error("Error fetching data:", error); - responseStatState.findUnique.data = null; - } - }, - }, - delete: { - loading: false, - async byId(id: string) { - if (!id) return toast.warn("ID tidak valid"); - - try { - responseStatState.delete.loading = true; - - const response = await fetch( - `/api/landingpage/indekskepuasanmasyarakat/response/del/${id}`, - { - method: "DELETE", - headers: { - "Content-Type": "application/json", - }, - } - ); - - const result = await response.json(); - - if (response.ok && result?.success) { - toast.success(result.message || "response berhasil dihapus"); - await responseStatState.findMany.load(); // refresh list - } else { - toast.error(result?.message || "Gagal menghapus response"); - } - } catch (error) { - console.error("Gagal delete:", error); - toast.error("Terjadi kesalahan saat menghapus response"); - } finally { - responseStatState.delete.loading = false; - } - }, - }, - edit: { - id: "", - form: { ...defaultResponseStatForm }, - loading: false, - - async load(id: string) { - if (!id) { - toast.warn("ID tidak valid"); - return null; - } - - try { - responseStatState.edit.loading = true; - - const response = await fetch( - `/api/landingpage/indekskepuasanmasyarakat/response/${id}`, - { - method: "GET", - headers: { - "Content-Type": "application/json", - }, - } - ); - if (!response.ok) { - throw new Error(`HTTP error! status: ${response.status}`); - } - const result = await response.json(); - if (result?.success) { - const data = result.data; - this.id = data.id; - this.form = { - label: data.label, - count: data.count, - monthlyStatId: data.monthlyStatId, - }; - return data; - } else { - throw new Error(result?.message || "Gagal memuat data"); - } - } catch (error) { - console.error("Error loading ages :", error); - toast.error( - error instanceof Error ? error.message : "Gagal memuat data" - ); - return null; - } finally { - responseStatState.edit.loading = false; - } - }, - - async update() { - const cek = templateResponseStatForm.safeParse( - responseStatState.edit.form - ); - if (!cek.success) { - const err = `[${cek.error.issues - .map((v) => `${v.path.join(".")}`) - .join("\n")}] required`; - return toast.error(err); - } - - try { - responseStatState.edit.loading = true; - const response = await fetch( - `/api/landingpage/indekskepuasanmasyarakat/response/${this.id}`, - { - method: "PUT", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - label: this.form.label, - count: this.form.count, - monthlyStatId: this.form.monthlyStatId, - }), - } - ); - if (!response.ok) { - const errorData = await response.json().catch(() => ({})); - throw new Error( - errorData.message || `HTTP error! status: ${response.status}` - ); - } - const result = await response.json(); - if (result.success) { - toast.success("Berhasil update response"); - await responseStatState.findMany.load(); // refresh list - return true; - } else { - throw new Error(result.message || "Gagal mengupdate response"); - } - } catch (error) { - console.error("Error updating response:", error); - toast.error( - error instanceof Error ? error.message : "Gagal mengupdate response" - ); - return false; - } finally { - responseStatState.edit.loading = false; - } - }, - reset() { - responseStatState.edit.id = ""; - responseStatState.edit.form = { ...defaultResponseStatForm }; - }, - }, -}); - -const indeksKepuasanState = proxy({ - surveyState, - monthlyStatState, - ageStatState, - genderStatState, - responseStatState, -}); - -export default indeksKepuasanState; diff --git a/src/app/admin/(dashboard)/landing-page/indeks-kepuasan-masyarakat/_lib/layoutTabs.tsx b/src/app/admin/(dashboard)/desa/berita/_com/layoutTabs.tsx similarity index 72% rename from src/app/admin/(dashboard)/landing-page/indeks-kepuasan-masyarakat/_lib/layoutTabs.tsx rename to src/app/admin/(dashboard)/desa/berita/_com/layoutTabs.tsx index 7168a9c4..605fedc8 100644 --- a/src/app/admin/(dashboard)/landing-page/indeks-kepuasan-masyarakat/_lib/layoutTabs.tsx +++ b/src/app/admin/(dashboard)/desa/berita/_com/layoutTabs.tsx @@ -5,25 +5,21 @@ import { Stack, Tabs, TabsList, TabsPanel, TabsTab, Title } from '@mantine/core' import { usePathname, useRouter } from 'next/navigation'; import React, { useEffect, useState } from 'react'; -function LayoutTabs({ children }: { children: React.ReactNode }) { +function LayoutTabsBerita({ children }: { children: React.ReactNode }) { const router = useRouter() const pathname = usePathname() const tabs = [ { - label: "List Survey", - value: "listSurvey", - href: "/admin/landing-page/indeks-kepuasan-masyarakat/list-survey" + label: "List Berita", + value: "list_berita", + href: "/admin/desa/berita/list-berita" }, { - label: "List Bulanan", - value: "listBulanan", - href: "/admin/landing-page/indeks-kepuasan-masyarakat/list-bulanan" + label: "Kategori Berita", + value: "kategori_berita", + href: "/admin/desa/berita/kategori-berita" }, - { - label: "List Gender Stat", - value: "listGenderStat", - href: "/admin/landing-page/indeks-kepuasan-masyarakat/list-gender-stat" - } + ]; const curentTab = tabs.find(tab => tab.href === pathname) const [activeTab, setActiveTab] = useState(curentTab?.value || tabs[0].value); @@ -45,7 +41,7 @@ function LayoutTabs({ children }: { children: React.ReactNode }) { return ( - Indeks Kepuasan Masyarakat + Gallery {tabs.map((e, i) => ( @@ -64,4 +60,4 @@ function LayoutTabs({ children }: { children: React.ReactNode }) { ); } -export default LayoutTabs; \ No newline at end of file +export default LayoutTabsBerita; \ No newline at end of file diff --git a/src/app/admin/(dashboard)/desa/berita/kategori-berita/[id]/page.tsx b/src/app/admin/(dashboard)/desa/berita/kategori-berita/[id]/page.tsx new file mode 100644 index 00000000..13361e24 --- /dev/null +++ b/src/app/admin/(dashboard)/desa/berita/kategori-berita/[id]/page.tsx @@ -0,0 +1,80 @@ +/* eslint-disable react-hooks/exhaustive-deps */ +'use client' +import stateDashboardBerita from '@/app/admin/(dashboard)/_state/desa/berita'; +import colors from '@/con/colors'; +import { Box, Button, Paper, Stack, Text, TextInput, Title } from '@mantine/core'; +import { IconArrowBack } from '@tabler/icons-react'; +import { useParams, useRouter } from 'next/navigation'; +import { useEffect, useState } from 'react'; +import { toast } from 'react-toastify'; +import { useProxy } from 'valtio/utils'; + +function EditKategoriBerita() { + const editState = useProxy(stateDashboardBerita.kategoriBerita) + const router = useRouter(); + const params = useParams(); + const [formData, setFormData] = useState({ + name: editState.update.form.name || '', + }); + + useEffect(() => { + const loadKategori = async () => { + const id = params?.id as string; + if (!id) return; + + try { + const data = await editState.update.load(id); // akses langsung, bukan dari proxy + if (data) { + setFormData({ + name: data.name || '', + }); + } + } catch (error) { + console.error("Error loading kategori Berita:", error); + toast.error("Gagal memuat data kategori Berita"); + } + }; + + loadKategori(); + }, [params?.id]); + + const handleSubmit = async () => { + try { + editState.update.form = { + ...editState.update.form, + name: formData.name, + }; + await editState.update.update(); + toast.success('Kategori Berita berhasil diperbarui!'); + router.push('/admin/desa/berita/kategori-berita'); + } catch (error) { + console.error('Error updating kategori Berita:', error); + toast.error('Terjadi kesalahan saat memperbarui kategori Berita'); + } + }; + + return ( + + + + + + + Edit Kategori Berita + setFormData({ ...formData, name: e.target.value })} + label={Nama Kategori Berita} + placeholder="masukkan nama kategori Berita" + /> + + + + + + ); +} + +export default EditKategoriBerita; diff --git a/src/app/admin/(dashboard)/desa/berita/kategori-berita/create/page.tsx b/src/app/admin/(dashboard)/desa/berita/kategori-berita/create/page.tsx new file mode 100644 index 00000000..526891f1 --- /dev/null +++ b/src/app/admin/(dashboard)/desa/berita/kategori-berita/create/page.tsx @@ -0,0 +1,55 @@ +'use client' +import stateDashboardBerita from '@/app/admin/(dashboard)/_state/desa/berita'; +import colors from '@/con/colors'; +import { Box, Button, Group, Paper, Stack, Text, TextInput, Title } from '@mantine/core'; +import { IconArrowBack } from '@tabler/icons-react'; +import { useRouter } from 'next/navigation'; +import { useProxy } from 'valtio/utils'; + + + +function CreateKategoriBerita() { + const createState = useProxy(stateDashboardBerita.kategoriBerita) + const router = useRouter(); + + const resetForm = () => { + createState.create.form = { + name: "", + }; + }; + + const handleSubmit = async () => { + await createState.create.create(); + resetForm(); + router.push("/admin/desa/berita/kategori-berita") + }; + + return ( + + + + + + + + Create Kategori Berita + Nama Kategori Berita} + placeholder='Masukkan nama kategori Berita' + value={createState.create.form.name} + onChange={(val) => { + createState.create.form.name = val.target.value; + }} + /> + + + + + + + ); +} + +export default CreateKategoriBerita; diff --git a/src/app/admin/(dashboard)/desa/berita/kategori-berita/page.tsx b/src/app/admin/(dashboard)/desa/berita/kategori-berita/page.tsx new file mode 100644 index 00000000..e4a3005a --- /dev/null +++ b/src/app/admin/(dashboard)/desa/berita/kategori-berita/page.tsx @@ -0,0 +1,128 @@ +/* eslint-disable react-hooks/exhaustive-deps */ +'use client' +import colors from '@/con/colors'; +import { Box, Button, Paper, Skeleton, Stack, Table, TableTbody, TableTd, TableTh, TableThead, TableTr, Text } from '@mantine/core'; +import { IconEdit, IconSearch, IconTrash } from '@tabler/icons-react'; +import { useRouter } from 'next/navigation'; +import { useEffect, useState } from 'react'; +import { useProxy } from 'valtio/utils'; +import HeaderSearch from '../../../_com/header'; +import JudulList from '../../../_com/judulList'; +import { ModalKonfirmasiHapus } from '../../../_com/modalKonfirmasiHapus'; +import stateDashboardBerita from '../../../_state/desa/berita'; + + + +function KategoriBerita() { + const [search, setSearch] = useState(''); + return ( + + } + value={search} + onChange={(e) => setSearch(e.currentTarget.value)} + /> + + + ); +} + +function ListKategoriBerita({ search }: { search: string }) { + const listDataState = useProxy(stateDashboardBerita.kategoriBerita) + const router = useRouter(); + const [modalHapus, setModalHapus] = useState(false) + const [selectedId, setSelectedId] = useState(null) + + useEffect(() => { + listDataState.findMany.load() + }, []) + + const handleDelete = () => { + if (selectedId) { + listDataState.delete.delete(selectedId) + setModalHapus(false) + setSelectedId(null) + + listDataState.findMany.load() + } + } + + const filteredData = (listDataState.findMany.data || []).filter(item => { + const keyword = search.toLowerCase(); + return ( + item.name.toLowerCase().includes(keyword) + ); + }); + + if (!listDataState.findMany.data) { + return ( + + + + ) + } + return ( + + + + + + + + + No + Nama + Edit + Hapus + + + + {filteredData.map((item, index) => ( + + + + {index + 1} + + + {item.name} + + + + + + + + ))} + +
+
+
+
+ + {/* Modal Konfirmasi Hapus */} + setModalHapus(false)} + onConfirm={handleDelete} + text='Apakah anda yakin ingin menghapus kategori Berita ini?' + /> +
+ ) +} + +export default KategoriBerita; diff --git a/src/app/admin/(dashboard)/desa/berita/layout.tsx b/src/app/admin/(dashboard)/desa/berita/layout.tsx new file mode 100644 index 00000000..4c8e4901 --- /dev/null +++ b/src/app/admin/(dashboard)/desa/berita/layout.tsx @@ -0,0 +1,13 @@ +'use client' +import React from 'react'; +import LayoutTabsBerita from './_com/layoutTabs'; + +function Layout({ children }: { children: React.ReactNode }) { + return ( + + {children} + + ); +} + +export default Layout; diff --git a/src/app/admin/(dashboard)/desa/berita/[id]/edit/page.tsx b/src/app/admin/(dashboard)/desa/berita/list-berita/[id]/edit/page.tsx similarity index 72% rename from src/app/admin/(dashboard)/desa/berita/[id]/edit/page.tsx rename to src/app/admin/(dashboard)/desa/berita/list-berita/[id]/edit/page.tsx index eaf05ddb..1e99645c 100644 --- a/src/app/admin/(dashboard)/desa/berita/[id]/edit/page.tsx +++ b/src/app/admin/(dashboard)/desa/berita/list-berita/[id]/edit/page.tsx @@ -1,3 +1,4 @@ +/* eslint-disable react-hooks/exhaustive-deps */ "use client"; import { @@ -7,7 +8,6 @@ import { Image, Paper, Select, - Skeleton, Stack, Text, TextInput, @@ -22,9 +22,8 @@ import EditEditor from "@/app/admin/(dashboard)/_com/editEditor"; import colors from "@/con/colors"; import ApiFetch from "@/lib/api-fetch"; import { FileInput } from "@mantine/core"; -import { useShallowEffect } from "@mantine/hooks"; -import { Prisma } from "@prisma/client"; -import stateDashboardBerita from "../../../../_state/desa/berita"; +import stateDashboardBerita from "@/app/admin/(dashboard)/_state/desa/berita"; + function EditBerita() { const beritaState = useProxy(stateDashboardBerita); @@ -43,6 +42,7 @@ function EditBerita() { // Load berita by id saat pertama kali useEffect(() => { + beritaState.kategoriBerita.findMany.load() const loadBerita = async () => { const id = params?.id as string; if (!id) return; @@ -99,7 +99,7 @@ function EditBerita() { await beritaState.berita.edit.update(); toast.success("Berita berhasil diperbarui!"); - router.push("/admin/desa/berita"); + router.push("/admin/desa/berita/list-berita"); } catch (error) { console.error("Error updating berita:", error); toast.error("Terjadi kesalahan saat memperbarui berita"); @@ -154,22 +154,29 @@ function EditBerita() { Konten { - setFormData((prev) => ({ ...prev, content: htmlContent })); - beritaState.berita.edit.form.content = htmlContent; - }} + value={formData.content} + onChange={(htmlContent) => { + setFormData((prev) => ({ ...prev, content: htmlContent })); + beritaState.berita.edit.form.content = htmlContent; + }} /> - { - setFormData({ - ...formData, - kategoriBeritaId: val?.id || '' - }); - }} + onChange={(val) => setFormData({ ...formData, kategoriBeritaId: val || "" })} + label={Kategori} + placeholder='Pilih kategori' + data={ + beritaState.kategoriBerita.findMany.data?.map((v) => ({ + value: v.id, + label: v.name + })) || [] + } + clearable + searchable + required + error={!formData.kategoriBeritaId ? "Pilih kategori" : undefined} /> @@ -179,61 +186,4 @@ function EditBerita() { ); } -interface SelectCategoryProps { - onChange: (value: Prisma.KategoriBeritaGetPayload<{ - select: { - name: true; - id: true; - }; - }> | null) => void; - value?: string | null; - defaultValue?: string | null; -} - -function SelectCategory({ - onChange, - value, - defaultValue, -}: SelectCategoryProps) { - const categoryState = useProxy(stateDashboardBerita.category); - - useShallowEffect(() => { - categoryState.findMany.load().then(() => { - console.log("Kategori berhasil dimuat:", categoryState.findMany.data); - }); - }, []); - - if (!categoryState.findMany.data) { - return ; - } - - - const selectedValue = value || defaultValue; - - return ( - Kategori} + placeholder="Pilih kategori" + data={beritaState.kategoriBerita.findMany.data.map((item) => ({ + label: item.name, + value: item.id, + }))} + value={beritaState.berita.create.form.kategoriBeritaId || null} + onChange={(val: string | null) => { + if (val) { + const selected = beritaState.kategoriBerita.findMany.data?.find((item) => item.id === val); + if (selected) { + beritaState.berita.create.form.kategoriBeritaId = selected.id; + } + } else { + beritaState.berita.create.form.kategoriBeritaId = ""; + } }} + searchable + clearable + nothingFoundMessage="Tidak ditemukan" /> ); - - interface SelectCategoryProps { - onChange: (value: Prisma.KategoriBeritaGetPayload<{ - select: { - name: true; - id: true; - }; - }> | null) => void; - value?: string | null; - defaultValue?: string | null; - } - - function SelectCategory({ - onChange, - value, - defaultValue, - }: SelectCategoryProps) { - const categoryState = useProxy(stateDashboardBerita.category); - - useShallowEffect(() => { - categoryState.findMany.load().then(() => { - console.log("Kategori berhasil dimuat:", categoryState.findMany.data); - }); - }, []); - - if (!categoryState.findMany.data) { - return ; - } - - - const selectedValue = value || defaultValue; - - return ( - Pilih Survey} - placeholder="Pilih survey" - value={formData.surveyId} - onChange={(value) => { - if (value) setFormData({ - ...formData, - surveyId: value - }) - }} - data={ - indeksKepuasanState.surveyState.findMany.data?.map((survey) => ({ - value: survey.id, - label: `${survey.title} (${survey.totalRespondents} responden)`, - })) || [] - } - /> - - - -
- - - - - ); -} - -export default EditListBulanan; diff --git a/src/app/admin/(dashboard)/landing-page/indeks-kepuasan-masyarakat/list-bulanan/[id]/page.tsx b/src/app/admin/(dashboard)/landing-page/indeks-kepuasan-masyarakat/list-bulanan/[id]/page.tsx deleted file mode 100644 index d129d592..00000000 --- a/src/app/admin/(dashboard)/landing-page/indeks-kepuasan-masyarakat/list-bulanan/[id]/page.tsx +++ /dev/null @@ -1,109 +0,0 @@ -'use client' -import { ModalKonfirmasiHapus } from '@/app/admin/(dashboard)/_com/modalKonfirmasiHapus'; -import indeksKepuasanState from '@/app/admin/(dashboard)/_state/landing-page/indeks-kepuasan-masyarakat'; -import colors from '@/con/colors'; -import { Box, Button, Flex, Paper, Skeleton, Stack, Text } from '@mantine/core'; -import { useShallowEffect } from '@mantine/hooks'; -import { IconArrowBack, IconEdit, IconX } from '@tabler/icons-react'; -import { useParams, useRouter } from 'next/navigation'; -import { useState } from 'react'; -import { useProxy } from 'valtio/utils'; - - -function DetailListBulanan() { - const detailState = useProxy(indeksKepuasanState.monthlyStatState) - const [modalHapus, setModalHapus] = useState(false) - const [selectedId, setSelectedId] = useState(null) - const params = useParams() - const router = useRouter() - - useShallowEffect(() => { - detailState.findUnique.load(params?.id as string) - }, []) - - - const handleHapus = () => { - if (selectedId) { - detailState.delete.byId(selectedId) - setModalHapus(false) - setSelectedId(null) - router.push("/admin/landing-page/indeks-kepuasan-masyarakat/list-bulanan") - } - } - - if (!detailState.findUnique.data) { - return ( - - - - ) - } - - return ( - - - - - - - Detail List Survey - {detailState.findUnique.data ? ( - - - - Bulan - {detailState.findUnique.data?.month} - - - Total Responden - {detailState.findUnique.data?.respondentsCount} - - - Survey - {detailState.findUnique.data?.survey.title } - - - - - - - - ) : null} - - - - {/* Modal Konfirmasi Hapus */} - setModalHapus(false)} - onConfirm={handleHapus} - text='Apakah anda yakin ingin menghapus list bulanan ini?' - /> - - ); -} - -export default DetailListBulanan; \ No newline at end of file diff --git a/src/app/admin/(dashboard)/landing-page/indeks-kepuasan-masyarakat/list-bulanan/create/page.tsx b/src/app/admin/(dashboard)/landing-page/indeks-kepuasan-masyarakat/list-bulanan/create/page.tsx deleted file mode 100644 index 4738c045..00000000 --- a/src/app/admin/(dashboard)/landing-page/indeks-kepuasan-masyarakat/list-bulanan/create/page.tsx +++ /dev/null @@ -1,84 +0,0 @@ -/* eslint-disable react-hooks/exhaustive-deps */ -'use client' -import indeksKepuasanState from '@/app/admin/(dashboard)/_state/landing-page/indeks-kepuasan-masyarakat'; -import colors from '@/con/colors'; -import { Box, Button, Group, Paper, Select, Stack, Text, TextInput, Title } from '@mantine/core'; -import { IconArrowBack } from '@tabler/icons-react'; -import { useRouter } from 'next/navigation'; -import { useEffect } from 'react'; -import { useProxy } from 'valtio/utils'; - - -function CreateListBulanan() { - const router = useRouter(); - const stateCreate = useProxy(indeksKepuasanState.monthlyStatState) - - - useEffect(() => { - stateCreate.findMany.load(); - indeksKepuasanState.surveyState.findMany.load(); - }, []); - - const resetForm = () => { - stateCreate.create.form = { - month: "", - respondentsCount: 0, - surveyId: "", - }; - }; - const handleSubmit = async () => { - await stateCreate.create.create(); - resetForm(); - router.push("/admin/landing-page/indeks-kepuasan-masyarakat/list-bulanan") - } - return ( - - - - - - - - Create List Bulanan - { - stateCreate.create.form.month = val.target.value; - }} - label={Bulan} - placeholder='Masukkan bulan' - /> - { - stateCreate.create.form.respondentsCount = Number(val.target.value); - }} - label={Total Responden} - placeholder='Masukkan total responden' - /> - { - setFormData(prev => ({ - ...prev, - monthlyStatId: value || '' - })); - }} - data={ - indeksKepuasanState.monthlyStatState.findMany.data?.map((monthlyStat) => ({ - value: monthlyStat.id, - label: `${monthlyStat.month} (${monthlyStat.respondentsCount} responden)`, - })) || [] - } - required - error={!formData.monthlyStatId ? 'Bulan harus dipilih' : undefined} - /> - - - - - - - - - ); -} - -export default EditListSurvey; diff --git a/src/app/admin/(dashboard)/landing-page/indeks-kepuasan-masyarakat/list-gender-stat/[id]/page.tsx b/src/app/admin/(dashboard)/landing-page/indeks-kepuasan-masyarakat/list-gender-stat/[id]/page.tsx deleted file mode 100644 index 152aadd9..00000000 --- a/src/app/admin/(dashboard)/landing-page/indeks-kepuasan-masyarakat/list-gender-stat/[id]/page.tsx +++ /dev/null @@ -1,113 +0,0 @@ -'use client' -import { ModalKonfirmasiHapus } from '@/app/admin/(dashboard)/_com/modalKonfirmasiHapus'; -import indeksKepuasanState from '@/app/admin/(dashboard)/_state/landing-page/indeks-kepuasan-masyarakat'; -import colors from '@/con/colors'; -import { Box, Button, Flex, Paper, Skeleton, Stack, Text } from '@mantine/core'; -import { useShallowEffect } from '@mantine/hooks'; -import { IconArrowBack, IconEdit, IconX } from '@tabler/icons-react'; -import { useParams, useRouter } from 'next/navigation'; -import { useState } from 'react'; -import { useProxy } from 'valtio/utils'; - - -function DetailGenderStat() { - const detailState = useProxy(indeksKepuasanState.genderStatState) - const [modalHapus, setModalHapus] = useState(false) - const [selectedId, setSelectedId] = useState(null) - const params = useParams() - const router = useRouter() - - useShallowEffect(() => { - detailState.findUnique.load(params?.id as string) - }, []) - - - const handleHapus = () => { - if (selectedId) { - detailState.delete.byId(selectedId) - setModalHapus(false) - setSelectedId(null) - router.push("/admin/landing-page/indeks-kepuasan-masyarakat/list-gender-stat") - } - } - - if (!detailState.findUnique.data) { - return ( - - - - ) - } - - return ( - - - - - - - Detail List Survey - {detailState.findUnique.data ? ( - - - - Laki Laki - {detailState.findUnique.data?.laki} - - - Perempuan - {detailState.findUnique.data?.perempuan} - - - Persentase Laki Laki - {detailState.findUnique.data?.percentLaki} - - - Persentase Perempuan - {detailState.findUnique.data?.percentPerempuan} - - - - - - - - ) : null} - - - - {/* Modal Konfirmasi Hapus */} - setModalHapus(false)} - onConfirm={handleHapus} - text='Apakah anda yakin ingin menghapus list gender stat ini?' - /> - - ); -} - -export default DetailGenderStat; \ No newline at end of file diff --git a/src/app/admin/(dashboard)/landing-page/indeks-kepuasan-masyarakat/list-gender-stat/create/page.tsx b/src/app/admin/(dashboard)/landing-page/indeks-kepuasan-masyarakat/list-gender-stat/create/page.tsx deleted file mode 100644 index a53d9366..00000000 --- a/src/app/admin/(dashboard)/landing-page/indeks-kepuasan-masyarakat/list-gender-stat/create/page.tsx +++ /dev/null @@ -1,103 +0,0 @@ -/* eslint-disable react-hooks/exhaustive-deps */ -'use client' -import indeksKepuasanState from '@/app/admin/(dashboard)/_state/landing-page/indeks-kepuasan-masyarakat'; -import colors from '@/con/colors'; -import { Box, Button, Group, Paper, Select, Stack, Text, TextInput, Title } from '@mantine/core'; -import { IconArrowBack } from '@tabler/icons-react'; -import { useRouter } from 'next/navigation'; -import { useEffect } from 'react'; -import { useProxy } from 'valtio/utils'; - - - -function CreateListGenderStat() { - const router = useRouter(); - const stateCreate = useProxy(indeksKepuasanState.genderStatState) - - - useEffect(() => { - stateCreate.findMany.load(); - indeksKepuasanState.monthlyStatState.findMany.load(); - }, []); - - const resetForm = () => { - stateCreate.create.form = { - laki: 0, - perempuan: 0, - monthlyStatId: "", - total: 0, - percentLaki: 0, - percentPerempuan: 0, - }; - }; - const handleSubmit = async () => { - await stateCreate.create.create(); - resetForm(); - router.push("/admin/landing-page/indeks-kepuasan-masyarakat/list-gender-stat") - } - return ( - - - - - - - - Create List Gender Stat - { - stateCreate.create.form.laki = Number(val.target.value); - }} - label={Laki Laki} - placeholder='Masukkan laki laki' - /> - { - stateCreate.create.form.perempuan = Number(val.target.value); - }} - label={Perempuan} - placeholder='Masukkan perempuan' - /> - Total} - disabled - /> - Persentase Laki Laki} - disabled - /> - Persentase Perempuan} - disabled - /> -