diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 7d2f89e2..8b48f326 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -951,13 +951,16 @@ model Kematian { // ========================================= GRAFIK KEPUASAN ========================================= // model GrafikKepuasan { - id String @id @default(cuid()) - label String - jumlah String - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - deletedAt DateTime @default(now()) - isActive Boolean @default(true) + id String @id @default(cuid()) + nama String + tanggal DateTime + jenisKelamin String + alamat String + penyakit String + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + deletedAt DateTime @default(now()) + isActive Boolean @default(true) } // ========================================= ARTIKEL KESEHATAN ========================================= // diff --git a/src/app/admin/(dashboard)/_state/kesehatan/data_kesehatan_warga/fasilitasKesehatan.ts b/src/app/admin/(dashboard)/_state/kesehatan/data_kesehatan_warga/fasilitasKesehatan.ts index 41fed621..3061e4e9 100644 --- a/src/app/admin/(dashboard)/_state/kesehatan/data_kesehatan_warga/fasilitasKesehatan.ts +++ b/src/app/admin/(dashboard)/_state/kesehatan/data_kesehatan_warga/fasilitasKesehatan.ts @@ -5,6 +5,7 @@ import { toast } from "react-toastify"; import { proxy } from "valtio"; import { z } from "zod"; +//fasilitas kesehatan aja // Validasi form const templateForm = z.object({ name: z.string().min(1, "Nama harus diisi"), @@ -61,7 +62,7 @@ const defaultForm = { }, }; -const fasilitasKesehatanState = proxy({ +const fasilitasKesehatan = proxy({ create: { form: { ...defaultForm }, loading: false, @@ -86,7 +87,7 @@ const fasilitasKesehatanState = proxy({ if (res.status === 200) { toast.success("Berhasil menambahkan fasilitas kesehatan"); this.resetForm(); - await fasilitasKesehatanState.findMany.load(); + await fasilitasKesehatan.findMany.load(); return res.data; } } catch (err: any) { @@ -102,7 +103,6 @@ const fasilitasKesehatanState = proxy({ this.form = { ...defaultForm }; }, }, - findMany: { data: null as | Prisma.FasilitasKesehatanGetPayload<{ @@ -156,7 +156,7 @@ const fasilitasKesehatanState = proxy({ const res = await fetch(`/api/kesehatan/fasilitas-kesehatan/${id}`); if (res.ok) { const data = await res.json(); - fasilitasKesehatanState.findUnique.data = data.data ?? null; + fasilitasKesehatan.findUnique.data = data.data ?? null; } else { toast.error("Gagal load data fasilitas kesehatan"); } @@ -176,8 +176,8 @@ const fasilitasKesehatanState = proxy({ const result = await res.json(); const data = result.data; - fasilitasKesehatanState.edit.id = data.id; - fasilitasKesehatanState.edit.form = { + fasilitasKesehatan.edit.id = data.id; + fasilitasKesehatan.edit.form = { name: data.name, informasiUmum: { fasilitas: data.informasiumum.fasilitas, @@ -205,7 +205,7 @@ const fasilitasKesehatanState = proxy({ }; }, async submit() { - const cek = templateForm.safeParse(fasilitasKesehatanState.edit.form); + const cek = templateForm.safeParse(fasilitasKesehatan.edit.form); if (!cek.success) { const errMsg = cek.error.issues .map((v) => `${v.path.join(".")}: ${v.message}`) @@ -215,42 +215,38 @@ const fasilitasKesehatanState = proxy({ } try { - fasilitasKesehatanState.edit.loading = true; + fasilitasKesehatan.edit.loading = true; const payload = { - name: fasilitasKesehatanState.edit.form.name, + name: fasilitasKesehatan.edit.form.name, informasiUmum: { - fasilitas: - fasilitasKesehatanState.edit.form.informasiUmum.fasilitas, - alamat: fasilitasKesehatanState.edit.form.informasiUmum.alamat, + fasilitas: fasilitasKesehatan.edit.form.informasiUmum.fasilitas, + alamat: fasilitasKesehatan.edit.form.informasiUmum.alamat, jamOperasional: - fasilitasKesehatanState.edit.form.informasiUmum.jamOperasional, + fasilitasKesehatan.edit.form.informasiUmum.jamOperasional, }, layananUnggulan: { - content: fasilitasKesehatanState.edit.form.layananUnggulan.content, + content: fasilitasKesehatan.edit.form.layananUnggulan.content, }, dokterdanTenagaMedis: { - name: fasilitasKesehatanState.edit.form.dokterdanTenagaMedis.name, + name: fasilitasKesehatan.edit.form.dokterdanTenagaMedis.name, specialist: - fasilitasKesehatanState.edit.form.dokterdanTenagaMedis.specialist, - jadwal: - fasilitasKesehatanState.edit.form.dokterdanTenagaMedis.jadwal, + fasilitasKesehatan.edit.form.dokterdanTenagaMedis.specialist, + jadwal: fasilitasKesehatan.edit.form.dokterdanTenagaMedis.jadwal, }, fasilitasPendukung: { - content: - fasilitasKesehatanState.edit.form.fasilitasPendukung.content, + content: fasilitasKesehatan.edit.form.fasilitasPendukung.content, }, prosedurPendaftaran: { - content: - fasilitasKesehatanState.edit.form.prosedurPendaftaran.content, + content: fasilitasKesehatan.edit.form.prosedurPendaftaran.content, }, tarifDanLayanan: { - layanan: fasilitasKesehatanState.edit.form.tarifDanLayanan.layanan, - tarif: fasilitasKesehatanState.edit.form.tarifDanLayanan.tarif, + layanan: fasilitasKesehatan.edit.form.tarifDanLayanan.layanan, + tarif: fasilitasKesehatan.edit.form.tarifDanLayanan.tarif, }, }; const res = await fetch( - `/api/kesehatan/fasilitas-kesehatan/${fasilitasKesehatanState.edit.id}`, + `/api/kesehatan/fasilitas-kesehatan/${fasilitasKesehatan.edit.id}`, { method: "PUT", headers: { "Content-Type": "application/json" }, @@ -264,7 +260,7 @@ const fasilitasKesehatanState = proxy({ } toast.success("Berhasil update fasilitas kesehatan"); - await fasilitasKesehatanState.findMany.load(); + await fasilitasKesehatan.findMany.load(); return true; } catch (err) { toast.error( @@ -272,37 +268,297 @@ const fasilitasKesehatanState = proxy({ ); return false; } finally { - fasilitasKesehatanState.edit.loading = false; + fasilitasKesehatan.edit.loading = false; } }, resetForm() { - fasilitasKesehatanState.edit.id = ""; - fasilitasKesehatanState.edit.form = { ...defaultForm }; + fasilitasKesehatan.edit.id = ""; + fasilitasKesehatan.edit.form = { ...defaultForm }; }, }, delete: { loading: false, - async byId(id: string){ + async byId(id: string) { try { - fasilitasKesehatanState.delete.loading = true; - const res = await fetch(`/api/kesehatan/fasilitas-kesehatan/del/${id}`, { - method: "DELETE", - }); + fasilitasKesehatan.delete.loading = true; + const res = await fetch( + `/api/kesehatan/fasilitas-kesehatan/del/${id}`, + { + method: "DELETE", + } + ); const result = await res.json(); if (res.ok && result.success) { toast.success("Fasilitas kesehatan berhasil dihapus"); - await fasilitasKesehatanState.findMany.load(); + await fasilitasKesehatan.findMany.load(); } else { toast.error(result.message || "Gagal menghapus"); } } catch { toast.error("Terjadi kesalahan saat menghapus"); } finally { - fasilitasKesehatanState.delete.loading = false; + fasilitasKesehatan.delete.loading = false; } - } + }, }, }); +//dokter & tenaga medis +const templateDokterForm = z.object({ + name: z.string().min(1, "Nama tidak boleh kosong"), + specialist: z.string().min(1, "Spesialis tidak boleh kosong"), + jadwal: z.string().min(1, "Jadwal tidak boleh kosong"), +}); + +const defaultDokterForm = { + name: "", + specialist: "", + jadwal: "", +}; + +const dokter = proxy({ + create: { + create: { + form: defaultDokterForm, + loading: false, + async create() { + const cek = templateDokterForm.safeParse(dokter.create.create.form); + if (!cek.success) { + const err = `[${cek.error.issues + .map((v) => `${v.path.join(".")}`) + .join("\n")}] required`; + toast.error(err); + return null; + } + try { + dokter.create.create.loading = true; + const res = await ApiFetch.api.kesehatan.doktertenagamedis[ + "create" + ].post(dokter.create.create.form); + + if (res.status === 200) { + const id = res.data?.data; + if (id) { + toast.success("Success create"); + dokter.create.create.form = { ...defaultDokterForm }; + dokter.findMany.load(); + return id; + } + } + toast.error("failed create"); + return null; + } catch (error) { + console.log((error as Error).message); + return null; + } finally { + dokter.create.create.loading = false; + } + }, + }, + }, + findMany: { + data: null as + | Prisma.DokterdanTenagaMedisGetPayload<{ + omit: { + isActive: true; + }; + }>[] + | null, + page: 1, + totalPages: 1, + loading: false, + search: "", + load: async (page = 1, limit = 10, search = "") => { + dokter.findMany.loading = true; // ✅ Akses langsung via nama path + dokter.findMany.page = page; + dokter.findMany.search = search; + + try { + const query: any = { page, limit }; + if (search) query.search = search; + + const res = await ApiFetch.api.kesehatan.doktertenagamedis[ + "findMany" + ].get({ query }); + + if (res.status === 200 && res.data?.success) { + dokter.findMany.data = res.data.data ?? []; + dokter.findMany.totalPages = res.data.totalPages ?? 1; + } else { + dokter.findMany.data = []; + dokter.findMany.totalPages = 1; + } + } catch (err) { + console.error("Gagal fetch dokter tenaga medis paginated:", err); + dokter.findMany.data = []; + dokter.findMany.totalPages = 1; + } finally { + dokter.findMany.loading = false; + } + }, + }, + findUnique: { + data: null as Prisma.DokterdanTenagaMedisGetPayload<{ + omit: { isActive: true }; + }> | null, + async load(id: string) { + try { + const res = await fetch(`/api/kesehatan/doktertenagamedis/${id}`); + if (res.ok) { + const data = await res.json(); + dokter.findUnique.data = data.data ?? null; + } else { + console.error( + "Failed to fetch dokter dan tenaga medis", + res.statusText + ); + dokter.findUnique.data = null; + } + } catch (error) { + console.error("Error fetching dokter dan tenaga medis", error); + dokter.findUnique.data = null; + } + }, + }, + update: { + id: "", + form: { ...defaultDokterForm }, + loading: false, + async load(id: string) { + if (!id) { + toast.warn("ID tidak valid"); + return null; + } + + try { + const response = await fetch(`/api/kesehatan/doktertenagamedis/${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, + specialist: data.specialist, + jadwal: data.jadwal, + }; + return data; // Return the loaded data + } else { + throw new Error(result?.message || "Gagal memuat data"); + } + } catch (error) { + console.error("Error loading dokter dan tenaga medis:", error); + toast.error( + error instanceof Error ? error.message : "Gagal memuat data" + ); + return null; + } + }, + async submit() { + const id = this.id; + if (!id) { + toast.warn("ID tidak valid"); + return null; + } + + const formData = { + name: this.form.name, + specialist: this.form.specialist, + jadwal: this.form.jadwal, + }; + + const cek = templateDokterForm.safeParse(formData); + if (!cek.success) { + const err = `[${cek.error.issues + .map((v) => `${v.path.join(".")}`) + .join("\n")}] required`; + toast.error(err); + return null; + } + + try { + this.loading = true; + const res = await fetch(`/api/kesehatan/doktertenagamedis/${id}`, { + method: "PUT", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify(formData), + }); + + const result = await res.json(); + + if (!res.ok || !result?.success) { + throw new Error(result?.message || "Gagal update data"); + } + + toast.success("Berhasil update data!"); + await dokter.findMany.load(); + return result.data; + } catch (error) { + console.error("Update error:", error); + toast.error("Gagal update data dokter dan tenaga medis"); + throw error; + } finally { + this.loading = false; + } + }, + }, + delete: { + loading: false, + async byId(id: string) { + if (!id) { + return toast.warn("ID tidak valid"); + } + try { + dokter.delete.loading = true; + + const response = await fetch( + `/api/kesehatan/doktertenagamedis/del/${id}`, + { + method: "DELETE", + headers: { + "Content-Type": "application/json", + }, + } + ); + + const result = await response.json(); + + if (response.ok && result?.success) { + toast.success( + result.message || "Dokter dan tenaga medis berhasil dihapus" + ); + await dokter.findMany.load(); // refresh list + } else { + toast.error( + result?.message || "Gagal menghapus dokter dan tenaga medis" + ); + } + } catch (error) { + console.error("Gagal delete:", error); + toast.error("Terjadi kesalahan saat menghapus dokter dan tenaga medis"); + } finally { + dokter.delete.loading = false; + } + }, + }, +}); + +const fasilitasKesehatanState = proxy({ + fasilitasKesehatan, + dokter +}); + export default fasilitasKesehatanState; diff --git a/src/app/admin/(dashboard)/_state/kesehatan/data_kesehatan_warga/grafikKepuasan.ts b/src/app/admin/(dashboard)/_state/kesehatan/data_kesehatan_warga/grafikKepuasan.ts index 2244b3ab..19f7e80a 100644 --- a/src/app/admin/(dashboard)/_state/kesehatan/data_kesehatan_warga/grafikKepuasan.ts +++ b/src/app/admin/(dashboard)/_state/kesehatan/data_kesehatan_warga/grafikKepuasan.ts @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ import ApiFetch from "@/lib/api-fetch"; import { Prisma } from "@prisma/client"; import { toast } from "react-toastify"; @@ -5,20 +6,19 @@ import { proxy } from "valtio"; import { z } from "zod"; const templateGrafikKepuasan = z.object({ - label: z.string().min(2, "Label harus diisi"), - jumlah: z.string().min(1, "Jumlah harus diisi"), + nama: z.string().min(2, "Nama harus diisi"), + tanggal: z.string().min(1, "Tanggal harus diisi"), + jenisKelamin: z.string().min(1, "Jenis kelamin harus diisi"), + alamat: z.string().min(1, "Alamat harus diisi"), + penyakit: z.string().min(1, "Penyakit harus diisi"), }); -type GrafikKepuasan = Prisma.GrafikKepuasanGetPayload<{ - select: { - label: true; - jumlah: true; - }; -}>; - -const defaultForm: GrafikKepuasan = { - label: "", - jumlah: "" +const defaultForm = { + nama: "", + tanggal: "", + jenisKelamin: "", + alamat: "", + penyakit: "", }; const grafikkepuasan = proxy({ @@ -36,16 +36,15 @@ const grafikkepuasan = proxy({ } try { grafikkepuasan.create.loading = true; - const res = await ApiFetch.api.kesehatan.grafikkepuasan["create"].post(grafikkepuasan.create.form); - + const res = await ApiFetch.api.kesehatan.grafikkepuasan["create"].post( + grafikkepuasan.create.form + ); + if (res.status === 200) { - const id = res.data?.data?.id; + const id = res.data?.data; if (id) { toast.success("Success create"); - grafikkepuasan.create.form = { - label: "", - jumlah: "", - }; + grafikkepuasan.create.form = { ...defaultForm }; grafikkepuasan.findMany.load(); return id; } @@ -62,21 +61,49 @@ const grafikkepuasan = proxy({ }, findMany: { data: null as - | Prisma.GrafikKepuasanGetPayload<{ omit: { isActive: true } }>[] + | Prisma.GrafikKepuasanGetPayload<{ + omit: { + isActive: true; + }; + }>[] | null, - async load() { - const res = await ApiFetch.api.kesehatan.grafikkepuasan[ - "find-many" - ].get(); - if (res.status === 200) { - grafikkepuasan.findMany.data = res.data?.data ?? []; + page: 1, + totalPages: 1, + loading: false, + search: "", + load: async (page = 1, limit = 10, search = "") => { + grafikkepuasan.findMany.loading = true; // ✅ Akses langsung via nama path + grafikkepuasan.findMany.page = page; + grafikkepuasan.findMany.search = search; + + try { + const query: any = { page, limit }; + if (search) query.search = search; + + const res = await ApiFetch.api.kesehatan.grafikkepuasan[ + "find-many" + ].get({ query }); + + if (res.status === 200 && res.data?.success) { + grafikkepuasan.findMany.data = res.data.data ?? []; + grafikkepuasan.findMany.totalPages = res.data.totalPages ?? 1; + } else { + grafikkepuasan.findMany.data = []; + grafikkepuasan.findMany.totalPages = 1; + } + } catch (err) { + console.error("Gagal fetch berita paginated:", err); + grafikkepuasan.findMany.data = []; + grafikkepuasan.findMany.totalPages = 1; + } finally { + grafikkepuasan.findMany.loading = false; } }, }, findUnique: { data: null as Prisma.GrafikKepuasanGetPayload<{ - omit: { isActive: true } - }> | null, + omit: { isActive: true }; + }> | null, async load(id: string) { try { const res = await fetch(`/api/kesehatan/grafikkepuasan/${id}`); @@ -95,88 +122,137 @@ const grafikkepuasan = proxy({ }, update: { id: "", - form: {...defaultForm}, + form: { ...defaultForm }, loading: false, - async byId() { - }, - async submit() { - const id = this.id; - if (!id) { - toast.warn("ID tidak valid"); - return null; - } - const cek = templateGrafikKepuasan.safeParse(grafikkepuasan.update.form); - if (!cek.success) { - const err = `[${cek.error.issues - .map((v) => `${v.path.join(".")}`) - .join("\n")}] required`; - return toast.error(err); - } - try { - this.loading = true; - const response = await fetch(`/api/kesehatan/grafikkepuasan/${id}`, { - method: "PUT", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify(this.form), - }); - const result = await response.json(); - - if (!response.ok || !result?.success) { - throw new Error(result?.message || "Gagal update data"); + async load(id: string) { + if (!id) { + toast.warn("ID tidak valid"); + return null; } - toast.success("Berhasil update data!"); + try { + const response = await fetch(`/api/kesehatan/grafikkepuasan/${id}`, { + method: "GET", + headers: { + "Content-Type": "application/json", + }, + }); - // ✅ Optional: refresh list kalau kamu langsung ke halaman list - await grafikkepuasan.findMany.load(); + if (!response.ok) { + throw new Error(`HTTP error! status: ${response.status}`); + } - return result.data; - } catch (error) { - console.error("Error update data:", error); - toast.error("Gagal update data grafik kepuasan"); - } finally { - this.loading = false; - } - }, -}, -delete: { - loading: false, - async byId(id: string) { - if (!id) { - return toast.warn("ID tidak valid"); - } - try { - grafikkepuasan.delete.loading = true; + const result = await response.json(); - const response = await fetch(`/api/kesehatan/grafikkepuasan/del/${id}`, { - method: "DELETE", - headers: { - "Content-Type": "application/json", - }, - }); - - const result = await response.json(); - - if (response.ok && result?.success) { - toast.success( - result.message || "Grafik kepuasan berhasil dihapus" - ); - await grafikkepuasan.findMany.load(); // refresh list - } else { + if (result?.success) { + const data = result.data; + this.id = data.id; + this.form = { + nama: data.nama, + tanggal: data.tanggal, + jenisKelamin: data.jenisKelamin, + alamat: data.alamat, + penyakit: data.penyakit, + }; + return data; // Return the loaded data + } else { + throw new Error(result?.message || "Gagal memuat data"); + } + } catch (error) { + console.error("Error loading grafik kepuasan:", error); toast.error( - result?.message || "Gagal menghapus grafik kepuasan" + error instanceof Error ? error.message : "Gagal memuat data" ); + return null; } - } catch (error) { - console.error("Gagal delete:", error); - toast.error("Terjadi kesalahan saat menghapus grafik kepuasan"); - } finally { - grafikkepuasan.delete.loading = false; - } - } -} + }, + async submit() { + const id = this.id; + if (!id) { + toast.warn("ID tidak valid"); + return null; + } + + const formData = { + nama: this.form.nama, + tanggal: this.form.tanggal, + jenisKelamin: this.form.jenisKelamin, + alamat: this.form.alamat, + penyakit: this.form.penyakit, + }; + + const cek = templateGrafikKepuasan.safeParse(formData); + if (!cek.success) { + const err = `[${cek.error.issues + .map((v) => `${v.path.join(".")}`) + .join("\n")}] required`; + toast.error(err); + return null; + } + + try { + this.loading = true; + const res = await fetch(`/api/kesehatan/grafikkepuasan/${id}`, { + method: "PUT", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify(formData), + }); + + const result = await res.json(); + + if (!res.ok || !result?.success) { + throw new Error(result?.message || "Gagal update data"); + } + + toast.success("Berhasil update data!"); + await grafikkepuasan.findMany.load(); + return result.data; + } catch (error) { + console.error("Update error:", error); + toast.error("Gagal update data grafik kepuasan"); + throw error; + } finally { + this.loading = false; + } + }, + }, + delete: { + loading: false, + async byId(id: string) { + if (!id) { + return toast.warn("ID tidak valid"); + } + try { + grafikkepuasan.delete.loading = true; + + const response = await fetch( + `/api/kesehatan/grafikkepuasan/del/${id}`, + { + method: "DELETE", + headers: { + "Content-Type": "application/json", + }, + } + ); + + const result = await response.json(); + + if (response.ok && result?.success) { + toast.success(result.message || "Grafik kepuasan berhasil dihapus"); + await grafikkepuasan.findMany.load(); // refresh list + } else { + toast.error(result?.message || "Gagal menghapus grafik kepuasan"); + } + } catch (error) { + console.error("Gagal delete:", error); + toast.error("Terjadi kesalahan saat menghapus grafik kepuasan"); + } finally { + grafikkepuasan.delete.loading = false; + } + }, + }, }); export default grafikkepuasan; diff --git a/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/fasilitas_kesehatan/[id]/edit/page.tsx b/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/fasilitas_kesehatan/[id]/edit/page.tsx index ff3e5321..37f37421 100644 --- a/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/fasilitas_kesehatan/[id]/edit/page.tsx +++ b/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/fasilitas_kesehatan/[id]/edit/page.tsx @@ -39,7 +39,7 @@ interface FasilitasKesehatanFormBase { } function EditFasilitasKesehatan() { - const stateFasilitasKesehatan = useProxy(fasilitasKesehatanState); + const stateFasilitasKesehatan = useProxy(fasilitasKesehatanState.fasilitasKesehatan); const router = useRouter(); const params = useParams(); diff --git a/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/fasilitas_kesehatan/[id]/page.tsx b/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/fasilitas_kesehatan/[id]/page.tsx index 8b115483..7858b60e 100644 --- a/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/fasilitas_kesehatan/[id]/page.tsx +++ b/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/fasilitas_kesehatan/[id]/page.tsx @@ -2,7 +2,7 @@ import { ModalKonfirmasiHapus } from '@/app/admin/(dashboard)/_com/modalKonfirmasiHapus'; import fasilitasKesehatanState from '@/app/admin/(dashboard)/_state/kesehatan/data_kesehatan_warga/fasilitasKesehatan'; import colors from '@/con/colors'; -import { Box, Button, Flex, Paper, Skeleton, Stack, Text } from '@mantine/core'; +import { Box, Button, Flex, Grid, GridCol, 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'; @@ -12,7 +12,7 @@ import { useProxy } from 'valtio/utils'; function DetailFasilitasKesehatan() { const params = useParams() const router = useRouter(); - const stateFasilitasKesehatan = useProxy(fasilitasKesehatanState) + const stateFasilitasKesehatan = useProxy(fasilitasKesehatanState.fasilitasKesehatan) const [modalHapus, setModalHapus] = useState(false); const [selectedId, setSelectedId] = useState(null) @@ -45,9 +45,23 @@ function DetailFasilitasKesehatan() { - + - Detail Fasilitas Kesehatan + + + Detail Fasilitas Kesehatan + + + + + + + + {stateFasilitasKesehatan.findUnique.data ? ( @@ -68,6 +82,14 @@ function DetailFasilitasKesehatan() { Layanan Unggulan + + Fasilitas Pendukung + + + + Prosedur Pendaftaran + + Dokter dan Tenaga Medis Nama Dokter @@ -77,14 +99,6 @@ function DetailFasilitasKesehatan() { Jadwal {stateFasilitasKesehatan.findUnique.data.dokterdantenagamedis.jadwal} - - Fasilitas Pendukung - - - - Prosedur Pendaftaran - - Tarif dan Layanan Layanan @@ -111,6 +125,7 @@ function DetailFasilitasKesehatan() { ) : null} + {/* Modal Hapus */} diff --git a/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/fasilitas_kesehatan/create/page.tsx b/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/fasilitas_kesehatan/create/page.tsx index 2b5122b2..e620d99f 100644 --- a/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/fasilitas_kesehatan/create/page.tsx +++ b/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/fasilitas_kesehatan/create/page.tsx @@ -10,7 +10,7 @@ import { useProxy } from 'valtio/utils'; function CreateFasilitasKesehatan() { - const stateFasilitasKesehatan = useProxy(fasilitasKesehatanState) + const stateFasilitasKesehatan = useProxy(fasilitasKesehatanState.fasilitasKesehatan) const router = useRouter(); diff --git a/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/fasilitas_kesehatan/dokter-tenaga-medis/[id]/edit/page.tsx b/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/fasilitas_kesehatan/dokter-tenaga-medis/[id]/edit/page.tsx new file mode 100644 index 00000000..69da2f21 --- /dev/null +++ b/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/fasilitas_kesehatan/dokter-tenaga-medis/[id]/edit/page.tsx @@ -0,0 +1,11 @@ +import React from 'react'; + +function Page() { + return ( +
+ Page +
+ ); +} + +export default Page; diff --git a/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/fasilitas_kesehatan/dokter-tenaga-medis/[id]/page.tsx b/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/fasilitas_kesehatan/dokter-tenaga-medis/[id]/page.tsx new file mode 100644 index 00000000..69da2f21 --- /dev/null +++ b/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/fasilitas_kesehatan/dokter-tenaga-medis/[id]/page.tsx @@ -0,0 +1,11 @@ +import React from 'react'; + +function Page() { + return ( +
+ Page +
+ ); +} + +export default Page; diff --git a/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/fasilitas_kesehatan/dokter-tenaga-medis/create/page.tsx b/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/fasilitas_kesehatan/dokter-tenaga-medis/create/page.tsx new file mode 100644 index 00000000..3e33d305 --- /dev/null +++ b/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/fasilitas_kesehatan/dokter-tenaga-medis/create/page.tsx @@ -0,0 +1,75 @@ +'use client' +import CreateEditor from '@/app/admin/(dashboard)/_com/createEditor'; +import fasilitasKesehatanState from '@/app/admin/(dashboard)/_state/kesehatan/data_kesehatan_warga/fasilitasKesehatan'; +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 { useProxy } from 'valtio/utils'; + + +function CreateDokter() { + const params = useParams() + const createState = useProxy(fasilitasKesehatanState.dokter) + const router = useRouter(); + + const resetForm = () => { + createState.create.create.form = { + name: "", + specialist: "", + jadwal: "", + }; + }; + + const handleSubmit = async () => { + await createState.create.create.create(); + resetForm(); + router.push(`/admin/kesehatan/fasilitas-kesehatan/${params?.id}/dokter-tenaga-medis`) + }; + return ( + + + + + + + + Create Dokter + Nama Dokter} + placeholder="masukkan nama dokter" + value={createState.create.create.form.name} + onChange={(e) => { + createState.create.create.form.name = e.target.value; + }} + /> + Specialist + Specialist} + placeholder="masukkan specialist" + value={createState.create.create.form.specialist} + onChange={(e) => { + createState.create.create.form.specialist = e.target.value; + }} + /> + + Jadwal + { + createState.create.create.form.jadwal = htmlContent; + }} + /> + + + + + + ); +} + +export default CreateDokter; diff --git a/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/fasilitas_kesehatan/dokter-tenaga-medis/page.tsx b/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/fasilitas_kesehatan/dokter-tenaga-medis/page.tsx new file mode 100644 index 00000000..94a1ad90 --- /dev/null +++ b/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/fasilitas_kesehatan/dokter-tenaga-medis/page.tsx @@ -0,0 +1,112 @@ +'use client' +import colors from '@/con/colors'; +import { Box, Button, Center, Pagination, Paper, Skeleton, Stack, Table, TableTbody, TableTd, TableTh, TableThead, TableTr, Text } from '@mantine/core'; +import { useShallowEffect } from '@mantine/hooks'; +import { IconArrowBack, IconDeviceImacCog, IconSearch } from '@tabler/icons-react'; +import { useRouter } from 'next/navigation'; +import { useProxy } from 'valtio/utils'; + +import HeaderSearch from '@/app/admin/(dashboard)/_com/header'; +import JudulList from '@/app/admin/(dashboard)/_com/judulList'; +import fasilitasKesehatanState from '@/app/admin/(dashboard)/_state/kesehatan/data_kesehatan_warga/fasilitasKesehatan'; +import { useState } from 'react'; + + +function DokterTenagaMedis() { + const [search, setSearch] = useState(""); + const router = useRouter(); + return ( + + + + + } + value={search} + onChange={(e) => setSearch(e.currentTarget.value)} + /> + + + ); +} + +function ListDokterTenagaMedis({ search }: { search: string }) { + const stateFasilitasKesehatan = useProxy(fasilitasKesehatanState.dokter) + const router = useRouter(); + const { + data, + loading, + load, + page, + totalPages + } = stateFasilitasKesehatan.findMany + + useShallowEffect(() => { + load(page, 10, search) + }, [page, search]) + + const filteredData = data || [] + + if (loading || !data) { + return ( + + + + ) + } + return ( + + + + + + + + + Fasilitas Kesehatan + Alamat + Jam Operasional + Detail + + + + {filteredData.map((item) => ( + + {item.name} + {item.specialist} + + + + + + + + ))} + +
+
+
+
+
+ load(newPage)} // ini penting! + total={totalPages} + mt="md" + mb="md" + /> +
+
+ ) +} + +export default DokterTenagaMedis; diff --git a/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/fasilitas_kesehatan/page.tsx b/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/fasilitas_kesehatan/page.tsx index 45042834..d6f5f429 100644 --- a/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/fasilitas_kesehatan/page.tsx +++ b/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/fasilitas_kesehatan/page.tsx @@ -1,8 +1,8 @@ 'use client' import colors from '@/con/colors'; -import { Box, Button, Paper, Skeleton, Stack, Table, TableTbody, TableTd, TableTh, TableThead, TableTr } from '@mantine/core'; +import { Box, Button, Flex, Grid, GridCol, Paper, Skeleton, Stack, Table, TableTbody, TableTd, TableTh, TableThead, TableTr } from '@mantine/core'; import { useShallowEffect } from '@mantine/hooks'; -import { IconDeviceImacCog, IconSearch } from '@tabler/icons-react'; +import { IconDeviceImacCog, IconList, IconSearch } from '@tabler/icons-react'; import { useRouter } from 'next/navigation'; import { useProxy } from 'valtio/utils'; import fasilitasKesehatanState from '../../../_state/kesehatan/data_kesehatan_warga/fasilitasKesehatan'; @@ -13,22 +13,37 @@ import { useState } from 'react'; function FasilitasKesehatan() { const [search, setSearch] = useState(""); + const router = useRouter(); return ( - } - value={search} - onChange={(e) => setSearch(e.currentTarget.value)} - /> - + + + } + value={search} + onChange={(e) => setSearch(e.currentTarget.value)} + /> + + + + + + + + + ); } function ListFasilitasKesehatan({ search }: { search: string }) { - const stateFasilitasKesehatan = useProxy(fasilitasKesehatanState) + const stateFasilitasKesehatan = useProxy(fasilitasKesehatanState.fasilitasKesehatan) const router = useRouter(); useShallowEffect(() => { @@ -47,47 +62,47 @@ function ListFasilitasKesehatan({ search }: { search: string }) { if (!stateFasilitasKesehatan.findMany.data) { return ( - + ) } return ( - - - - - - - - Fasilitas Kesehatan - Alamat - Jam Operasional - Detail - - - - {filteredData.map((item) => ( - - {item.name} - {item.informasiumum.alamat} - {item.informasiumum.jamOperasional} - - - + + + + +
+ + + Fasilitas Kesehatan + Dokter + Layanan + Detail - ))} - -
-
-
-
-
+ + + {filteredData.map((item) => ( + + {item.name} + {item.dokterdantenagamedis.name} + {item.tarifdanlayanan.layanan} + + + + + ))} + + + + +
+ ) } diff --git a/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/fasilitas_kesehatan/tarif-layanan/page.tsx b/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/fasilitas_kesehatan/tarif-layanan/page.tsx new file mode 100644 index 00000000..69da2f21 --- /dev/null +++ b/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/fasilitas_kesehatan/tarif-layanan/page.tsx @@ -0,0 +1,11 @@ +import React from 'react'; + +function Page() { + return ( +
+ Page +
+ ); +} + +export default Page; diff --git a/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/grafik_hasil_kepuasan/[id]/edit/page.tsx b/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/grafik_hasil_kepuasan/[id]/edit/page.tsx new file mode 100644 index 00000000..ab91485c --- /dev/null +++ b/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/grafik_hasil_kepuasan/[id]/edit/page.tsx @@ -0,0 +1,116 @@ +/* eslint-disable react-hooks/exhaustive-deps */ +'use client' +import grafikkepuasan from '@/app/admin/(dashboard)/_state/kesehatan/data_kesehatan_warga/grafikKepuasan'; +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 EditGrafikHasilKepuasan() { + const editState = useProxy(grafikkepuasan) + const router = useRouter(); + const params = useParams(); + const [formData, setFormData] = useState({ + nama: editState.update.form.nama || '', + tanggal: editState.update.form.tanggal || '', + jenisKelamin: editState.update.form.jenisKelamin || '', + alamat: editState.update.form.alamat || '', + penyakit: editState.update.form.penyakit || '', + }); + + useEffect(() => { + const loadKelahiran = 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({ + nama: data.nama || '', + tanggal: data.tanggal || '', + jenisKelamin: data.jenisKelamin || '', + alamat: data.alamat || '', + penyakit: data.penyakit || '', + }); + } + } catch (error) { + console.error("Error loading grafik hasil kepuasan:", error); + toast.error("Gagal memuat data grafik hasil kepuasan"); + } + }; + + loadKelahiran(); + }, [params?.id]); + + const handleSubmit = async () => { + try { + editState.update.form = { + ...editState.update.form, + nama: formData.nama, + tanggal: formData.tanggal, + jenisKelamin: formData.jenisKelamin, + alamat: formData.alamat, + penyakit: formData.penyakit, + }; + await editState.update.submit(); + toast.success('grafik hasil kepuasan berhasil diperbarui!'); + router.push('/admin/kesehatan/data-kesehatan-warga/grafik_hasil_kepuasan'); + } catch (error) { + console.error('Error updating grafik hasil kepuasan:', error); + toast.error('Terjadi kesalahan saat memperbarui grafik hasil kepuasan'); + } + }; + + return ( + + + + + + + Edit grafik hasil kepuasan + setFormData({ ...formData, nama: e.target.value })} + label={Nama} + placeholder="masukkan nama" + /> + setFormData({ ...formData, tanggal: e.target.value })} + label={Tanggal} + placeholder="masukkan tanggal" + /> + setFormData({ ...formData, jenisKelamin: e.target.value })} + label={Jenis Kelamin} + placeholder="masukkan jenis kelamin" + /> + setFormData({ ...formData, alamat: e.target.value })} + label={Alamat} + placeholder="masukkan alamat" + /> + setFormData({ ...formData, penyakit: e.target.value })} + label={Penyakit} + placeholder="masukkan penyakit" + /> + + + + + ); +} + +export default EditGrafikHasilKepuasan; diff --git a/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/grafik_hasil_kepuasan/[id]/page.tsx b/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/grafik_hasil_kepuasan/[id]/page.tsx index 034478cc..c6cdf12e 100644 --- a/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/grafik_hasil_kepuasan/[id]/page.tsx +++ b/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/grafik_hasil_kepuasan/[id]/page.tsx @@ -1,80 +1,125 @@ -/* eslint-disable react-hooks/exhaustive-deps */ 'use client' - -import grafikkepuasan from '@/app/admin/(dashboard)/_state/kesehatan/data_kesehatan_warga/grafikKepuasan'; -import colors from '@/con/colors'; -import { Box, Button, Paper, Stack, TextInput, Title } from '@mantine/core'; -import { IconArrowBack } from '@tabler/icons-react'; -import { useParams, useRouter } from 'next/navigation'; -import { useEffect } from 'react'; import { useProxy } from 'valtio/utils'; -function EditGrafikHasilKepuasan() { +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 { ModalKonfirmasiHapus } from '@/app/admin/(dashboard)/_com/modalKonfirmasiHapus'; +import grafikkepuasan from '@/app/admin/(dashboard)/_state/kesehatan/data_kesehatan_warga/grafikKepuasan'; +import colors from '@/con/colors'; + + +function DetailGrafikHasilKepuasan() { + const state = useProxy(grafikkepuasan) + const [modalHapus, setModalHapus] = useState(false) + const [selectedId, setSelectedId] = useState(null) + const params = useParams() const router = useRouter() - const params = useParams() as { id: string } - const stateGrafikKepuasan = useProxy(grafikkepuasan) - const id = params.id + useShallowEffect(() => { + state.findUnique.load(params?.id as string) + }, []) - // Load data saat komponen mount - useEffect(() => { - if (id) { - stateGrafikKepuasan.findUnique.load(id).then(() => { - const data = stateGrafikKepuasan.findUnique.data - if (data) { - stateGrafikKepuasan.update.form = { - label: data.label || '', - jumlah: data.jumlah || '', - } - } - }) + + const handleHapus = () => { + if (selectedId) { + state.delete.byId(selectedId) + setModalHapus(false) + setSelectedId(null) + router.push("/admin/kesehatan/data-kesehatan-warga/grafik_hasil_kepuasan") } - }, [id]) - - const handleSubmit = async () => { - // Set the ID before submitting - stateGrafikKepuasan.update.id = id; - await stateGrafikKepuasan.update.submit(); - router.push('/admin/kesehatan/data-kesehatan-warga/grafik_hasil_kepuasan') } -return ( + + if (!state.findUnique.data) { + return ( + + + + ) + } + + return ( - + - Edit Grafik Hasil Kepuasan - { - stateGrafikKepuasan.update.form.label = val.currentTarget.value; - }} - /> - { - stateGrafikKepuasan.update.form.jumlah = val.currentTarget.value; - }} - /> - + Detail Data Grafik Hasil Kepuasan + {state.findUnique.data ? ( + + + + Nama + {state.findUnique.data?.nama} + + + Tanggal + + {new Date(state.findUnique.data?.tanggal).toLocaleDateString('id-ID', { + day: '2-digit', + month: 'long', + year: 'numeric' + })} + + + + Jenis Kelamin + {state.findUnique.data?.jenisKelamin} + + + Alamat + {state.findUnique.data?.alamat} + + + Penyakit + {state.findUnique.data?.penyakit} + + + + + + + + ) : null} + + {/* Modal Konfirmasi Hapus */} + setModalHapus(false)} + onConfirm={handleHapus} + text='Apakah anda yakin ingin menghapus data ini?' + /> - ) + ); } -export default EditGrafikHasilKepuasan; +export default DetailGrafikHasilKepuasan; \ No newline at end of file diff --git a/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/grafik_hasil_kepuasan/create/page.tsx b/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/grafik_hasil_kepuasan/create/page.tsx index 497f62ba..b3bb8b7f 100644 --- a/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/grafik_hasil_kepuasan/create/page.tsx +++ b/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/grafik_hasil_kepuasan/create/page.tsx @@ -16,20 +16,16 @@ function CreateGrafikHasilKepuasanMasyarakat() { const resetForm = () => { stateGrafikKepuasan.create.form = { - label: "", - jumlah: "", + nama: "", + tanggal: "", + jenisKelamin: "", + alamat: "", + penyakit: "", } } const handleSubmit = async () => { - const id = await stateGrafikKepuasan.create.create(); - if (id) { - const idStr = String(id); - await stateGrafikKepuasan.findUnique.load(idStr); - if (stateGrafikKepuasan.findUnique.data) { - setChartData([stateGrafikKepuasan.findUnique.data]); - } - } + await stateGrafikKepuasan.create.create(); resetForm(); router.push("/admin/kesehatan/data-kesehatan-warga/grafik_hasil_kepuasan"); } @@ -45,21 +41,48 @@ function CreateGrafikHasilKepuasanMasyarakat() { Tambah Grafik Hasil Kepuasan Masyarakat { - stateGrafikKepuasan.create.form.label = val.currentTarget.value; + stateGrafikKepuasan.create.form.nama = val.currentTarget.value; }} /> { - stateGrafikKepuasan.create.form.jumlah = val.currentTarget.value; + stateGrafikKepuasan.create.form.tanggal = val.currentTarget.value; + }} + /> + { + stateGrafikKepuasan.create.form.jenisKelamin = val.currentTarget.value; + }} + /> + { + stateGrafikKepuasan.create.form.alamat = val.currentTarget.value; + }} + /> + { + stateGrafikKepuasan.create.form.penyakit = val.currentTarget.value; }} /> diff --git a/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/grafik_hasil_kepuasan/page.tsx b/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/grafik_hasil_kepuasan/page.tsx index df46a08c..ec639413 100644 --- a/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/grafik_hasil_kepuasan/page.tsx +++ b/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/grafik_hasil_kepuasan/page.tsx @@ -1,16 +1,16 @@ +/* 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, Title } from '@mantine/core'; +import { Box, Button, Center, Pagination, Paper, Skeleton, Stack, Table, TableTbody, TableTd, TableTh, TableThead, TableTr, Text, Title } from '@mantine/core'; import { useMediaQuery, useShallowEffect } from '@mantine/hooks'; -import { IconEdit, IconSearch, IconTrash } from '@tabler/icons-react'; +import { IconDeviceImacCog, IconSearch } from '@tabler/icons-react'; import { useRouter } from 'next/navigation'; import { useEffect, useState } from 'react'; import { Bar, BarChart, Legend, Tooltip, XAxis, YAxis } from 'recharts'; import { useProxy } from 'valtio/utils'; -import JudulListTab from '../../../_com/judulListTab'; -import { ModalKonfirmasiHapus } from '../../../_com/modalKonfirmasiHapus'; -import grafikkepuasan from '../../../_state/kesehatan/data_kesehatan_warga/grafikKepuasan'; import HeaderSearch from '../../../_com/header'; +import JudulList from '../../../_com/judulList'; +import grafikkepuasan from '../../../_state/kesehatan/data_kesehatan_warga/grafikKepuasan'; function GrafikHasilKepuasanMasyarakat() { const [search, setSearch] = useState(""); @@ -30,53 +30,79 @@ function GrafikHasilKepuasanMasyarakat() { function ListGrafikHasilKepuasanMasyarakat({ search }: { search: string }) { type PDKMGrafik = { id: string; - label: string; - jumlah: number; + nama: string; + tanggal: string | Date; // Allow both string and Date types + jenisKelamin: string; + alamat: string; + penyakit: string; + createdAt?: Date; // Add optional fields that might come from the API + updatedAt?: Date; + deletedAt?: Date | null; } const stateGrafikKepuasan = useProxy(grafikkepuasan); const [chartData, setChartData] = useState([]); const [mounted, setMounted] = useState(false); // untuk memastikan DOM sudah ready const isTablet = useMediaQuery('(max-width: 1024px)') const isMobile = useMediaQuery('(max-width: 768px)') - const [modalHapus, setModalHapus] = useState(false) - const [selectedId, setSelectedId] = useState(null) const router = useRouter(); - const handleDelete = () => { - if (selectedId) { - stateGrafikKepuasan.delete.byId(selectedId) - setModalHapus(false) - setSelectedId(null) - - stateGrafikKepuasan.findMany.load() - } - } + const { + data, + page, + totalPages, + loading, + load + } = stateGrafikKepuasan.findMany; useShallowEffect(() => { setMounted(true) - stateGrafikKepuasan.findMany.load() - }, []) + load(page, 10, search) + }, [page, search]) useEffect(() => { setMounted(true); - if (stateGrafikKepuasan.findMany.data) { - setChartData(stateGrafikKepuasan.findMany.data.map((item) => ({ + if (data) { + setChartData(data.map((item) => ({ id: item.id, - label: item.label, - jumlah: Number(item.jumlah), + nama: item.nama, + tanggal: item.tanggal instanceof Date ? item.tanggal.toISOString() : item.tanggal, + jenisKelamin: item.jenisKelamin, + alamat: item.alamat, + penyakit: item.penyakit, }))); } - }, [stateGrafikKepuasan.findMany.data]); + }, [data]); - const filteredData = (stateGrafikKepuasan.findMany.data || []).filter(item => { - const keyword = search.toLowerCase(); - return ( - item.label.toLowerCase().includes(keyword) || - item.jumlah.toString().toLowerCase().includes(keyword) - ); - }); + // Add this function to process the data + const processDiseaseData = (data: PDKMGrafik[]) => { + const diseaseCount: Record = {}; - if (!stateGrafikKepuasan.findMany.data) { + data.forEach(item => { + const penyakit = item.penyakit.trim(); + if (penyakit) { + diseaseCount[penyakit] = (diseaseCount[penyakit] || 0) + 1; + } + }); + + return Object.entries(diseaseCount).map(([name, count]) => ({ + name, + count + })); + }; + + // Add this state to store the processed chart data + const [diseaseChartData, setDiseaseChartData] = useState<{ name: string, count: number }[]>([]); + + // Update the chart data when data changes + useEffect(() => { + if (data && data.length > 0) { + setDiseaseChartData(processDiseaseData(data)); + } + }, [data]); + + const filteredData = data || []; + + if (loading || !data) { return ( @@ -89,40 +115,36 @@ function ListGrafikHasilKepuasanMasyarakat({ search }: { search: string }) { {/* Form Input */} - } /> - Label - Jumlah - Edit - Delete + Nama + Tanggal + Jenis Kelamin + Penyakit + Detail {filteredData.map((item) => ( - {item.label} - {item.jumlah} + {item.nama} + + {new Date(item.tanggal).toLocaleDateString('id-ID', { + day: '2-digit', + month: 'long', + year: 'numeric' + })} + + {item.jenisKelamin} + {item.penyakit} - - - @@ -130,6 +152,15 @@ function ListGrafikHasilKepuasanMasyarakat({ search }: { search: string }) {
+
+ load(newPage)} // ini penting! + total={totalPages} + mt="md" + mb="md" + /> +
{/* Chart */} @@ -141,30 +172,29 @@ function ListGrafikHasilKepuasanMasyarakat({ search }: { search: string }) { ) : ( - + Grafik Hasil Kepuasan Masyarakat - {mounted && chartData.length > 0 && ( - - + {mounted && diseaseChartData.length > 0 && ( + + - + )} )}
- - {/* Modal Konfirmasi Hapus */} - setModalHapus(false)} - onConfirm={handleDelete} - text='Apakah anda yakin ingin menghapus grafik hasil kepuasan masyarakat ini?' - /> ); } diff --git a/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/persentase_data_kelahiran_kematian/kelahiran/page.tsx b/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/persentase_data_kelahiran_kematian/kelahiran/page.tsx index 1b64d1f7..e55a02ae 100644 --- a/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/persentase_data_kelahiran_kematian/kelahiran/page.tsx +++ b/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/persentase_data_kelahiran_kematian/kelahiran/page.tsx @@ -5,7 +5,7 @@ import persentasekelahiran from '@/app/admin/(dashboard)/_state/kesehatan/data_k import colors from '@/con/colors'; import { Box, Button, Center, Pagination, Paper, Skeleton, Stack, Table, TableTbody, TableTd, TableTh, TableThead, TableTr } from '@mantine/core'; import { useShallowEffect } from '@mantine/hooks'; -import { IconArrowBack, IconEdit, IconSearch } from '@tabler/icons-react'; +import { IconArrowBack, IconDeviceImacCog, IconSearch } from '@tabler/icons-react'; import { useRouter } from 'next/navigation'; import { useState } from 'react'; import { useProxy } from 'valtio/utils'; @@ -47,7 +47,7 @@ function ListKelahiran({ search }: { search: string }) { useShallowEffect(() => { load(page, 10, search) - }, [search]) + }, [page, search]) const filteredData = data || [] @@ -93,7 +93,7 @@ function ListKelahiran({ search }: { search: string }) { {item.alamat} diff --git a/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/persentase_data_kelahiran_kematian/page.tsx b/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/persentase_data_kelahiran_kematian/page.tsx index a5a07128..830c4caa 100644 --- a/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/persentase_data_kelahiran_kematian/page.tsx +++ b/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/persentase_data_kelahiran_kematian/page.tsx @@ -2,7 +2,7 @@ 'use client' import persentasekelahiran from '@/app/admin/(dashboard)/_state/kesehatan/data_kesehatan_warga/persentaseKelahiran'; import colors from '@/con/colors'; -import { ActionIcon, Box, Button, Center, Flex, Paper, Skeleton, Stack, Table, Text, Title } from '@mantine/core'; +import { ActionIcon, Box, Center, Flex, Paper, Select, Skeleton, Stack, Table, Text, Title } from '@mantine/core'; import { useMediaQuery, useShallowEffect } from '@mantine/hooks'; import { IconBabyCarriage, IconGrave2 } from '@tabler/icons-react'; import { useRouter } from 'next/navigation'; @@ -157,20 +157,18 @@ function GrafikPersentaseKelahiranKematian() { ) : ( <> {/* Year Selector */} - - Pilih Tahun: -
- {chartData.map(({ tahun }) => ( - - ))} -
+ +