From a67c192c834223c0e2ce08ce1e7cfbbfdaaf4696 Mon Sep 17 00:00:00 2001 From: nico Date: Sat, 30 May 2026 11:08:58 +0800 Subject: [PATCH] feat(kesehatan): tambah relasi banjar ke penderita penyakit dan CRUD banjar admin - Tambah field banjarId (optional) ke GrafikKepuasan + migration - API CRUD banjar baru di /api/desa/banjar/* - Update API grafik_kepuasan: create, find-many (filter by banjar), findUnique, updt - semua include banjar - State: tambah banjarId ke form, banjarList proxy, filter by banjarId - UI list: kolom Banjar di tabel desktop, kartu mobile, Select filter by banjar - UI create/edit: Select banjar (opsional), load banjarList on mount - UI detail: tampilkan field Banjar - Admin banjar: halaman list, create, detail - Sidebar: menu Banjar di domain Desa Co-Authored-By: Claude Sonnet 4.6 --- ...jar-grafik-kepuasan-integration-summary.md | 66 ++++++ .../migration.sql | 5 + prisma/schema.prisma | 15 +- .../admin/(dashboard)/_state/desa/banjar.ts | 160 +++++++++++++ .../data_kesehatan_warga/grafikKepuasan.ts | 33 ++- .../(dashboard)/desa/banjar/[id]/page.tsx | 123 ++++++++++ .../(dashboard)/desa/banjar/create/page.tsx | 103 +++++++++ .../admin/(dashboard)/desa/banjar/page.tsx | 211 ++++++++++++++++++ .../penderita_penyakit/[id]/edit/page.tsx | 27 ++- .../penderita_penyakit/[id]/page.tsx | 5 + .../penderita_penyakit/create/page.tsx | 16 ++ .../penderita_penyakit/page.tsx | 51 ++++- src/app/admin/_com/list_PageAdmin.tsx | 15 ++ .../[[...slugs]]/_lib/desa/banjar/create.ts | 24 ++ .../api/[[...slugs]]/_lib/desa/banjar/del.ts | 42 ++++ .../[[...slugs]]/_lib/desa/banjar/findMany.ts | 43 ++++ .../_lib/desa/banjar/findUnique.ts | 21 ++ .../[[...slugs]]/_lib/desa/banjar/index.ts | 22 ++ .../api/[[...slugs]]/_lib/desa/banjar/updt.ts | 26 +++ src/app/api/[[...slugs]]/_lib/desa/index.ts | 2 + .../grafik_kepuasan/create.ts | 10 +- .../grafik_kepuasan/find-many.ts | 7 + .../grafik_kepuasan/findUnique.ts | 1 + .../grafik_kepuasan/index.ts | 2 + .../grafik_kepuasan/updt.ts | 3 + 25 files changed, 1002 insertions(+), 31 deletions(-) create mode 100644 MIND/SUMMARY/banjar-grafik-kepuasan-integration-summary.md create mode 100644 prisma/migrations/20260530025023_add_banjar_to_grafik_kepuasan/migration.sql create mode 100644 src/app/admin/(dashboard)/_state/desa/banjar.ts create mode 100644 src/app/admin/(dashboard)/desa/banjar/[id]/page.tsx create mode 100644 src/app/admin/(dashboard)/desa/banjar/create/page.tsx create mode 100644 src/app/admin/(dashboard)/desa/banjar/page.tsx create mode 100644 src/app/api/[[...slugs]]/_lib/desa/banjar/create.ts create mode 100644 src/app/api/[[...slugs]]/_lib/desa/banjar/del.ts create mode 100644 src/app/api/[[...slugs]]/_lib/desa/banjar/findMany.ts create mode 100644 src/app/api/[[...slugs]]/_lib/desa/banjar/findUnique.ts create mode 100644 src/app/api/[[...slugs]]/_lib/desa/banjar/index.ts create mode 100644 src/app/api/[[...slugs]]/_lib/desa/banjar/updt.ts diff --git a/MIND/SUMMARY/banjar-grafik-kepuasan-integration-summary.md b/MIND/SUMMARY/banjar-grafik-kepuasan-integration-summary.md new file mode 100644 index 00000000..81219c87 --- /dev/null +++ b/MIND/SUMMARY/banjar-grafik-kepuasan-integration-summary.md @@ -0,0 +1,66 @@ +# Summary: Banjar Integration untuk Penderita Penyakit (GrafikKepuasan) + +**Tanggal:** 2026-05-30 +**Branch:** `tasks/kesehatan/banjar-penderita-penyakit/20260530` + +--- + +## Apa yang Dikerjakan + +Menambahkan relasi **Banjar** ke modul Penderita Penyakit (model `GrafikKepuasan`) secara end-to-end: dari schema database, API, state management, hingga UI admin. + +--- + +## Perubahan per Layer + +### 1. Database — `prisma/schema.prisma` + Migration +- Tambah field `banjarId String?` (optional) ke model `GrafikKepuasan` +- Tambah relasi ke model `Banjar` dengan `onDelete: SetNull` +- Migration: `20260530025023_add_banjar_to_grafik_kepuasan` + +### 2. API Banjar (baru) — `src/app/api/[[...slugs]]/_lib/desa/banjar/` +- CRUD lengkap: `create.ts`, `findMany.ts`, `findUnique.ts`, `updt.ts`, `del.ts`, `index.ts` +- Didaftarkan di `src/app/api/[[...slugs]]/_lib/desa/index.ts` +- Endpoint: `/api/desa/banjar/*` + +### 3. API GrafikKepuasan (update) +- `create.ts` — terima `banjarId` opsional, include `banjar` di response +- `find-many.ts` — filter by `banjarId` via query param, include `banjar` +- `findUnique.ts` — include `banjar` di response +- `updt.ts` — terima dan simpan `banjarId`, include `banjar` +- `index.ts` — daftarkan route yang diperlukan + +### 4. State — `grafikKepuasan.ts` +- Tambah `banjarId` ke `defaultForm`, schema Zod, `create.form`, `update.form` +- Tambah `banjarList` proxy: fetch dari `/api/desa/banjar/findMany?limit=100` +- `findMany.load()` terima parameter `banjarId` untuk filter +- Type `findMany.data` update ke include `banjar: { id, name }` + +### 5. State Banjar (baru) — `src/app/admin/(dashboard)/_state/desa/banjar.ts` +- Proxy Valtio untuk CRUD Banjar (create, findMany, findUnique, update, delete) + +### 6. Admin UI Banjar (baru) — `src/app/admin/(dashboard)/desa/banjar/` +- `page.tsx` — tabel list banjar + kartu mobile + pagination +- `create/page.tsx` — form tambah banjar +- `[id]/page.tsx` — detail + hapus + edit + +### 7. Admin UI Penderita Penyakit (update) +- `page.tsx` (list) — tambah kolom Banjar di tabel desktop, field Banjar di kartu mobile, filter Select by banjar +- `create/page.tsx` — tambah `Select` banjar (opsional), load `banjarList` on mount +- `[id]/page.tsx` (detail) — tambah baris Banjar +- `[id]/edit/page.tsx` — tambah `banjarId` ke `formData`, load `banjarList`, tambah `Select` banjar + +### 8. Sidebar Admin — `list_PageAdmin.tsx` +- Tambah menu "Banjar" di bawah domain Desa + +--- + +## Keputusan Desain +- `banjarId` dibuat **opsional** agar data lama tidak terpengaruh +- Filter banjar di list page menggunakan Select + clear, tidak memerlukan halaman terpisah +- `banjarList` di-load sekali on mount, bukan di-refetch tiap render + +--- + +## Verifikasi +- `bun run build` ✅ sukses tanpa error TypeScript diff --git a/prisma/migrations/20260530025023_add_banjar_to_grafik_kepuasan/migration.sql b/prisma/migrations/20260530025023_add_banjar_to_grafik_kepuasan/migration.sql new file mode 100644 index 00000000..8c39c73e --- /dev/null +++ b/prisma/migrations/20260530025023_add_banjar_to_grafik_kepuasan/migration.sql @@ -0,0 +1,5 @@ +-- AlterTable +ALTER TABLE "GrafikKepuasan" ADD COLUMN "banjarId" TEXT; + +-- AddForeignKey +ALTER TABLE "GrafikKepuasan" ADD CONSTRAINT "GrafikKepuasan_banjarId_fkey" FOREIGN KEY ("banjarId") REFERENCES "Banjar"("id") ON DELETE SET NULL ON UPDATE CASCADE; diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 3f5157f6..86d09a6d 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -1050,6 +1050,8 @@ model GrafikKepuasan { jenisKelamin String alamat String penyakit String + banjar Banjar? @relation(fields: [banjarId], references: [id]) + banjarId String? createdAt DateTime @default(now()) updatedAt DateTime @updatedAt deletedAt DateTime @default(now()) @@ -1152,12 +1154,13 @@ model DoctorSign { // ========================================= BANJAR ========================================= // model Banjar { - id String @id @default(cuid()) - name String - isActive Boolean @default(true) - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - posyandus Posyandu[] + id String @id @default(cuid()) + name String + isActive Boolean @default(true) + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + posyandus Posyandu[] + grafikKepuasans GrafikKepuasan[] } // ========================================= POSYANDU ========================================= // diff --git a/src/app/admin/(dashboard)/_state/desa/banjar.ts b/src/app/admin/(dashboard)/_state/desa/banjar.ts new file mode 100644 index 00000000..dc5cfb7f --- /dev/null +++ b/src/app/admin/(dashboard)/_state/desa/banjar.ts @@ -0,0 +1,160 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ +import { Prisma } from "@prisma/client"; +import { toast } from "react-toastify"; +import { proxy } from "valtio"; +import { z } from "zod"; + +const templateBanjar = z.object({ + name: z.string().min(1, "Nama banjar wajib diisi"), +}); + +const defaultBanjar = { name: "" }; + +const banjar = proxy({ + create: { + form: { ...defaultBanjar }, + loading: false, + async create() { + const cek = templateBanjar.safeParse(banjar.create.form); + if (!cek.success) { + const err = `[${cek.error.issues.map((v) => v.path.join(".")).join("\n")}] required`; + return toast.error(err); + } + + try { + banjar.create.loading = true; + const res = await fetch("/api/desa/banjar/create", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify(banjar.create.form), + }); + const result = await res.json(); + if (res.ok && result?.success) { + banjar.findMany.load(); + return toast.success("Banjar berhasil dibuat"); + } + return toast.error(result?.message || "Gagal membuat banjar"); + } catch (error) { + console.error(error); + return toast.error("Gagal membuat banjar"); + } finally { + banjar.create.loading = false; + } + }, + }, + + findMany: { + data: [] as Prisma.BanjarGetPayload[], + page: 1, + totalPages: 1, + loading: false, + search: "", + load: async (page = 1, limit = 10, search = "") => { + banjar.findMany.loading = true; + banjar.findMany.page = page; + banjar.findMany.search = search; + + try { + const params = new URLSearchParams({ page: String(page), limit: String(limit) }); + if (search) params.set("search", search); + + const res = await fetch(`/api/desa/banjar/findMany?${params.toString()}`); + const result = await res.json(); + + if (res.ok && result?.success) { + banjar.findMany.data = result.data ?? []; + banjar.findMany.totalPages = result.totalPages ?? 1; + } else { + banjar.findMany.data = []; + banjar.findMany.totalPages = 1; + } + } catch (err) { + console.error("Gagal fetch banjar:", err); + banjar.findMany.data = []; + banjar.findMany.totalPages = 1; + } finally { + banjar.findMany.loading = false; + } + }, + }, + + delete: { + loading: false, + async delete(id: string) { + if (!id) return toast.warn("ID tidak valid"); + + try { + banjar.delete.loading = true; + const res = await fetch(`/api/desa/banjar/del/${id}`, { method: "DELETE" }); + const result = await res.json(); + + if (res.ok && result?.success) { + toast.success(result.message || "Banjar berhasil dihapus"); + await banjar.findMany.load(); + } else { + toast.error(result?.message || "Gagal menghapus banjar"); + } + } catch (error) { + console.error("Gagal delete banjar:", error); + toast.error("Terjadi kesalahan saat menghapus banjar"); + } finally { + banjar.delete.loading = false; + } + }, + }, + + update: { + id: "", + form: { ...defaultBanjar }, + loading: false, + async load(id: string) { + if (!id) { toast.warn("ID tidak valid"); return null; } + + try { + const res = await fetch(`/api/desa/banjar/${id}`); + if (!res.ok) throw new Error(`HTTP error! status: ${res.status}`); + + const result = await res.json(); + if (result?.success) { + banjar.update.id = result.data.id; + banjar.update.form = { name: result.data.name }; + return result.data; + } + throw new Error(result?.message || "Gagal memuat data"); + } catch (error) { + console.error("Error loading banjar:", error); + toast.error(error instanceof Error ? error.message : "Gagal memuat data"); + return null; + } + }, + async update() { + const cek = templateBanjar.safeParse(banjar.update.form); + if (!cek.success) { + const err = `[${cek.error.issues.map((v) => v.path.join(".")).join("\n")}] required`; + return toast.error(err); + } + + try { + banjar.update.loading = true; + const res = await fetch(`/api/desa/banjar/${banjar.update.id}`, { + method: "PUT", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify(banjar.update.form), + }); + const result = await res.json(); + + if (res.ok && result?.success) { + return toast.success("Banjar berhasil diperbarui"); + } + return toast.error(result?.message || "Gagal mengupdate banjar"); + } catch (error) { + console.error("Error updating banjar:", error); + toast.error("Gagal mengupdate banjar"); + } finally { + banjar.update.loading = false; + } + }, + }, +}); + +export default banjar; 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 15b7b4b8..ccf893c8 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 @@ -11,6 +11,7 @@ const templateGrafikKepuasan = z.object({ 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"), + banjarId: z.string().optional(), }); const defaultForm = { @@ -19,6 +20,7 @@ const defaultForm = { jenisKelamin: "", alamat: "", penyakit: "", + banjarId: "", }; const grafikkepuasan = proxy({ @@ -62,23 +64,24 @@ const grafikkepuasan = proxy({ findMany: { data: null as | Prisma.GrafikKepuasanGetPayload<{ - omit: { - isActive: true; - }; + include: { banjar: { select: { id: true; name: true } } }; }>[] | null, page: 1, totalPages: 1, loading: false, search: "", - load: async (page = 1, limit = 10, search = "") => { - grafikkepuasan.findMany.loading = true; // ✅ Akses langsung via nama path + banjarId: "", + load: async (page = 1, limit = 10, search = "", banjarId = "") => { + grafikkepuasan.findMany.loading = true; grafikkepuasan.findMany.page = page; grafikkepuasan.findMany.search = search; + grafikkepuasan.findMany.banjarId = banjarId; try { const query: any = { page, limit }; if (search) query.search = search; + if (banjarId) query.banjarId = banjarId; const res = await ApiFetch.api.kesehatan.grafikkepuasan[ "find-many" @@ -153,6 +156,7 @@ const grafikkepuasan = proxy({ jenisKelamin: data.jenisKelamin, alamat: data.alamat, penyakit: data.penyakit, + banjarId: data.banjarId || "", }; return data; // Return the loaded data } else { @@ -179,6 +183,7 @@ const grafikkepuasan = proxy({ jenisKelamin: this.form.jenisKelamin, alamat: this.form.alamat, penyakit: this.form.penyakit, + banjarId: this.form.banjarId || undefined, }; const cek = templateGrafikKepuasan.safeParse(formData); @@ -253,6 +258,24 @@ const grafikkepuasan = proxy({ } }, }, + banjarList: { + data: [] as { id: string; name: string }[], + loading: false, + async load() { + try { + grafikkepuasan.banjarList.loading = true; + const res = await fetch("/api/desa/banjar/findMany?limit=100"); + const result = await res.json(); + if (res.ok && result?.success) { + grafikkepuasan.banjarList.data = result.data ?? []; + } + } catch (err) { + console.error("Gagal fetch banjar list:", err); + } finally { + grafikkepuasan.banjarList.loading = false; + } + }, + }, }); export default grafikkepuasan; diff --git a/src/app/admin/(dashboard)/desa/banjar/[id]/page.tsx b/src/app/admin/(dashboard)/desa/banjar/[id]/page.tsx new file mode 100644 index 00000000..2b1e6d70 --- /dev/null +++ b/src/app/admin/(dashboard)/desa/banjar/[id]/page.tsx @@ -0,0 +1,123 @@ +/* eslint-disable react-hooks/exhaustive-deps */ +'use client'; +import stateBanjar from '@/app/admin/(dashboard)/_state/desa/banjar'; +import colors from '@/con/colors'; +import { + Box, + Button, + Group, + Loader, + Paper, + Stack, + 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 EditBanjar() { + const state = useProxy(stateBanjar); + const router = useRouter(); + const params = useParams(); + const [isSubmitting, setIsSubmitting] = useState(false); + const [originalName, setOriginalName] = useState(''); + const [formData, setFormData] = useState({ name: '' }); + + const isFormValid = () => formData.name?.trim() !== ''; + + useEffect(() => { + const id = params?.id as string; + if (!id) return; + + state.update.load(id).then((data) => { + if (data) { + setFormData({ name: data.name }); + setOriginalName(data.name); + } else { + toast.error('Gagal memuat data banjar'); + } + }); + }, [params?.id]); + + const handleResetForm = () => { + setFormData({ name: originalName }); + toast.info('Form dikembalikan ke data awal'); + }; + + const handleSubmit = async () => { + if (!formData.name?.trim()) { + toast.error('Nama banjar wajib diisi'); + return; + } + + try { + setIsSubmitting(true); + state.update.form = { name: formData.name }; + await state.update.update(); + router.push('/admin/desa/banjar'); + } catch (error) { + console.error('Error updating banjar:', error); + toast.error('Terjadi kesalahan saat memperbarui banjar'); + } finally { + setIsSubmitting(false); + } + }; + + return ( + + + + Edit Banjar + + + + + setFormData({ name: e.target.value })} + required + /> + + + + + + + + + ); +} + +export default EditBanjar; diff --git a/src/app/admin/(dashboard)/desa/banjar/create/page.tsx b/src/app/admin/(dashboard)/desa/banjar/create/page.tsx new file mode 100644 index 00000000..0cb4a6b5 --- /dev/null +++ b/src/app/admin/(dashboard)/desa/banjar/create/page.tsx @@ -0,0 +1,103 @@ +'use client'; +import stateBanjar from '@/app/admin/(dashboard)/_state/desa/banjar'; +import colors from '@/con/colors'; +import { + Box, + Button, + Group, + Loader, + Paper, + Stack, + TextInput, + Title, +} from '@mantine/core'; +import { IconArrowBack } from '@tabler/icons-react'; +import { useRouter } from 'next/navigation'; +import { useState } from 'react'; +import { toast } from 'react-toastify'; +import { useProxy } from 'valtio/utils'; + +function CreateBanjar() { + const state = useProxy(stateBanjar); + const router = useRouter(); + const [isSubmitting, setIsSubmitting] = useState(false); + + const isFormValid = () => state.create.form.name?.trim() !== ''; + + const resetForm = () => { + state.create.form = { name: '' }; + }; + + const handleSubmit = async () => { + if (!state.create.form.name?.trim()) { + toast.error('Nama banjar wajib diisi'); + return; + } + + setIsSubmitting(true); + try { + await state.create.create(); + resetForm(); + router.push('/admin/desa/banjar'); + } catch (error) { + console.error('Error creating banjar:', error); + toast.error('Gagal menambahkan banjar'); + } finally { + setIsSubmitting(false); + } + }; + + return ( + + + + Tambah Banjar + + + + + (state.create.form.name = e.target.value)} + required + /> + + + + + + + + + ); +} + +export default CreateBanjar; diff --git a/src/app/admin/(dashboard)/desa/banjar/page.tsx b/src/app/admin/(dashboard)/desa/banjar/page.tsx new file mode 100644 index 00000000..bf88f22f --- /dev/null +++ b/src/app/admin/(dashboard)/desa/banjar/page.tsx @@ -0,0 +1,211 @@ +/* eslint-disable react-hooks/exhaustive-deps */ +'use client' +import colors from '@/con/colors'; +import { + Box, + Button, + Center, + Group, + Pagination, + Paper, + Skeleton, + Stack, + Table, + TableTbody, + TableTd, + TableTh, + TableThead, + TableTr, + Text, + Title, +} from '@mantine/core'; +import { useDebouncedValue } from '@mantine/hooks'; +import { IconEdit, IconPlus, 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 { ModalKonfirmasiHapus } from '../../_com/modalKonfirmasiHapus'; +import stateBanjar from '../../_state/desa/banjar'; + +function Banjar() { + const [search, setSearch] = useState(''); + return ( + + } + value={search} + onChange={(e) => setSearch(e.currentTarget.value)} + /> + + + ); +} + +function ListBanjar({ search }: { search: string }) { + const state = useProxy(stateBanjar); + const router = useRouter(); + const [modalHapus, setModalHapus] = useState(false); + const [selectedId, setSelectedId] = useState(null); + const [debouncedSearch] = useDebouncedValue(search, 1000); + + const { data, loading, load, page, totalPages } = state.findMany; + + useEffect(() => { + load(page, 10, debouncedSearch); + }, [page, debouncedSearch]); + + const handleDelete = () => { + if (selectedId) { + state.delete.delete(selectedId); + setModalHapus(false); + setSelectedId(null); + } + }; + + if (loading || !data) { + return ( + + + + ); + } + + return ( + + + + Daftar Banjar + + + + {/* Desktop Table */} + + + + + + Nama Banjar + + + Edit + + + Hapus + + + + + {data.length > 0 ? ( + data.map((item) => ( + + + {item.name} + + + + + + + + + )) + ) : ( + + +
+ Tidak ada data banjar +
+
+
+ )} +
+
+
+ + {/* Mobile Cards */} + + {data.length > 0 ? ( + data.map((item) => ( + + + Nama Banjar + {item.name} + + + + + + + )) + ) : ( +
+ Tidak ada data banjar +
+ )} +
+
+ +
+ { + load(newPage, 10, search); + window.scrollTo({ top: 0, behavior: 'smooth' }); + }} + total={totalPages} + color="blue" + radius="md" + /> +
+ + setModalHapus(false)} + onConfirm={handleDelete} + text="Apakah anda yakin ingin menghapus banjar ini? Banjar yang masih digunakan posyandu tidak bisa dihapus." + /> +
+ ); +} + +export default Banjar; diff --git a/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/penderita_penyakit/[id]/edit/page.tsx b/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/penderita_penyakit/[id]/edit/page.tsx index ef9e30b4..c91667d7 100644 --- a/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/penderita_penyakit/[id]/edit/page.tsx +++ b/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/penderita_penyakit/[id]/edit/page.tsx @@ -9,10 +9,12 @@ import { Group, Loader, Paper, + Select, Stack, TextInput, Title } from '@mantine/core'; +import { useShallowEffect } from '@mantine/hooks'; import { IconArrowBack } from '@tabler/icons-react'; import { useParams, useRouter } from 'next/navigation'; import { useEffect, useState } from 'react'; @@ -43,6 +45,7 @@ function EditGrafikHasilKepuasan() { jenisKelamin: '', alamat: '', penyakit: '', + banjarId: '', }); const [originalData, setOriginalData] = useState({ @@ -51,8 +54,13 @@ function EditGrafikHasilKepuasan() { jenisKelamin: '', alamat: '', penyakit: '', + banjarId: '', }); + useShallowEffect(() => { + editState.banjarList.load(); + }, []); + // Load data once useEffect(() => { const loadData = async () => { @@ -70,6 +78,7 @@ function EditGrafikHasilKepuasan() { jenisKelamin: data.jenisKelamin || '', alamat: data.alamat || '', penyakit: data.penyakit || '', + banjarId: data.banjarId || '', }); setOriginalData({ @@ -78,6 +87,7 @@ function EditGrafikHasilKepuasan() { jenisKelamin: data.jenisKelamin || '', alamat: data.alamat || '', penyakit: data.penyakit || '', + banjarId: data.banjarId || '', }); } } catch (err) { @@ -95,13 +105,7 @@ function EditGrafikHasilKepuasan() { }; const handleResetForm = () => { - setFormData({ - nama: originalData.nama, - tanggal: originalData.tanggal, - jenisKelamin: originalData.jenisKelamin, - alamat: originalData.alamat, - penyakit: originalData.penyakit, - }); + setFormData({ ...originalData }); toast.info("Form dikembalikan ke data awal"); }; @@ -183,6 +187,15 @@ function EditGrafikHasilKepuasan() { required /> ))} + ({ value: b.id, label: b.name }))} + value={stateGrafikKepuasan.create.form.banjarId || null} + onChange={(val) => (stateGrafikKepuasan.create.form.banjarId = val ?? '')} + clearable + searchable + /> + {/* Filter Banjar */} + +