fix(kesehatan): solve valtio mutation error and sync db

- Fix 'Cannot assign to read only property' by mutating original Valtio proxy in create/edit pages for IbuHamil and Balita
- Sync database schema with 'prisma db push' to create IbuHamil and Balita tables
- Verify build success
This commit is contained in:
2026-05-04 17:04:44 +08:00
parent dccba1f82b
commit afe0d9d04b
4 changed files with 54 additions and 54 deletions

View File

@@ -27,9 +27,9 @@ export default function BalitaCreatePage() {
const form = state.create.form;
const handleSubmit = async () => {
const ok = await state.create.submit();
const ok = await balitaState.create.submit();
if (ok) {
state.create.reset();
balitaState.create.reset();
router.push('/admin/kesehatan/balita');
}
};
@@ -51,14 +51,14 @@ export default function BalitaCreatePage() {
required
placeholder="Nama balita"
value={form.nama}
onChange={(e) => { form.nama = e.currentTarget.value; }}
onChange={(e) => { balitaState.create.form.nama = e.currentTarget.value; }}
radius="md"
/>
<TextInput
label="NIK"
placeholder="Nomor Induk Kependudukan"
value={form.nik}
onChange={(e) => { form.nik = e.currentTarget.value; }}
onChange={(e) => { balitaState.create.form.nik = e.currentTarget.value; }}
radius="md"
/>
<TextInput
@@ -66,7 +66,7 @@ export default function BalitaCreatePage() {
required
type="date"
value={form.tanggalLahir}
onChange={(e) => { form.tanggalLahir = e.currentTarget.value; }}
onChange={(e) => { balitaState.create.form.tanggalLahir = e.currentTarget.value; }}
radius="md"
/>
<Select
@@ -77,7 +77,7 @@ export default function BalitaCreatePage() {
{ value: 'P', label: 'Perempuan' },
]}
value={form.jenisKelamin}
onChange={(v) => { if (v) form.jenisKelamin = v as typeof form.jenisKelamin; }}
onChange={(v) => { if (v) balitaState.create.form.jenisKelamin = v as typeof form.jenisKelamin; }}
radius="md"
/>
<NumberInput
@@ -86,7 +86,7 @@ export default function BalitaCreatePage() {
min={0}
decimalScale={1}
value={form.beratBadanKg ?? ''}
onChange={(v) => { form.beratBadanKg = v === '' ? undefined : Number(v); }}
onChange={(v) => { balitaState.create.form.beratBadanKg = v === '' ? undefined : Number(v); }}
radius="md"
/>
<NumberInput
@@ -95,21 +95,21 @@ export default function BalitaCreatePage() {
min={0}
decimalScale={1}
value={form.tinggiBadanCm ?? ''}
onChange={(v) => { form.tinggiBadanCm = v === '' ? undefined : Number(v); }}
onChange={(v) => { balitaState.create.form.tinggiBadanCm = v === '' ? undefined : Number(v); }}
radius="md"
/>
<TextInput
label="Nama Orang Tua"
placeholder="Nama ayah/ibu"
value={form.namaOrtu}
onChange={(e) => { form.namaOrtu = e.currentTarget.value; }}
onChange={(e) => { balitaState.create.form.namaOrtu = e.currentTarget.value; }}
radius="md"
/>
<TextInput
label="No. HP Orang Tua"
placeholder="08xx-xxxx-xxxx"
value={form.noHpOrtu}
onChange={(e) => { form.noHpOrtu = e.currentTarget.value; }}
onChange={(e) => { balitaState.create.form.noHpOrtu = e.currentTarget.value; }}
radius="md"
/>
<Select
@@ -121,7 +121,7 @@ export default function BalitaCreatePage() {
{ value: 'STUNTING', label: 'Stunting' },
]}
value={form.statusStunting}
onChange={(v) => { if (v) form.statusStunting = v as typeof form.statusStunting; }}
onChange={(v) => { if (v) balitaState.create.form.statusStunting = v as typeof form.statusStunting; }}
radius="md"
/>
</SimpleGrid>
@@ -130,7 +130,7 @@ export default function BalitaCreatePage() {
label="Alamat"
placeholder="Alamat lengkap"
value={form.alamat}
onChange={(e) => { form.alamat = e.currentTarget.value; }}
onChange={(e) => { balitaState.create.form.alamat = e.currentTarget.value; }}
radius="md"
/>
@@ -138,17 +138,17 @@ export default function BalitaCreatePage() {
<Checkbox
label="Imunisasi Lengkap"
checked={form.imunisasiLengkap}
onChange={(e) => { form.imunisasiLengkap = e.currentTarget.checked; }}
onChange={(e) => { balitaState.create.form.imunisasiLengkap = e.currentTarget.checked; }}
/>
<Checkbox
label="Gizi Baik"
checked={form.giziBaik}
onChange={(e) => { form.giziBaik = e.currentTarget.checked; }}
onChange={(e) => { balitaState.create.form.giziBaik = e.currentTarget.checked; }}
/>
<Checkbox
label="Pemeriksaan Rutin"
checked={form.pemeriksaanRutin}
onChange={(e) => { form.pemeriksaanRutin = e.currentTarget.checked; }}
onChange={(e) => { balitaState.create.form.pemeriksaanRutin = e.currentTarget.checked; }}
/>
</Group>
@@ -156,7 +156,7 @@ export default function BalitaCreatePage() {
label="Catatan"
placeholder="Catatan tambahan"
value={form.catatan}
onChange={(e) => { form.catatan = e.currentTarget.value; }}
onChange={(e) => { balitaState.create.form.catatan = e.currentTarget.value; }}
radius="md"
rows={3}
/>

View File

@@ -30,11 +30,11 @@ export default function BalitaEditPage() {
const form = state.edit.form;
useEffect(() => {
if (id) state.edit.load(id);
if (id) balitaState.edit.load(id);
}, [id]); // eslint-disable-line react-hooks/exhaustive-deps
const handleSubmit = async () => {
const ok = await state.edit.update();
const ok = await balitaState.edit.update();
if (ok) router.push('/admin/kesehatan/balita');
};
@@ -55,14 +55,14 @@ export default function BalitaEditPage() {
required
placeholder="Nama balita"
value={form.nama}
onChange={(e) => { form.nama = e.currentTarget.value; }}
onChange={(e) => { balitaState.edit.form.nama = e.currentTarget.value; }}
radius="md"
/>
<TextInput
label="NIK"
placeholder="Nomor Induk Kependudukan"
value={form.nik}
onChange={(e) => { form.nik = e.currentTarget.value; }}
onChange={(e) => { balitaState.edit.form.nik = e.currentTarget.value; }}
radius="md"
/>
<TextInput
@@ -70,7 +70,7 @@ export default function BalitaEditPage() {
required
type="date"
value={form.tanggalLahir}
onChange={(e) => { form.tanggalLahir = e.currentTarget.value; }}
onChange={(e) => { balitaState.edit.form.tanggalLahir = e.currentTarget.value; }}
radius="md"
/>
<Select
@@ -81,7 +81,7 @@ export default function BalitaEditPage() {
{ value: 'P', label: 'Perempuan' },
]}
value={form.jenisKelamin}
onChange={(v) => { if (v) form.jenisKelamin = v as typeof form.jenisKelamin; }}
onChange={(v) => { if (v) balitaState.edit.form.jenisKelamin = v as typeof form.jenisKelamin; }}
radius="md"
/>
<NumberInput
@@ -90,7 +90,7 @@ export default function BalitaEditPage() {
min={0}
decimalScale={1}
value={form.beratBadanKg ?? ''}
onChange={(v) => { form.beratBadanKg = v === '' ? undefined : Number(v); }}
onChange={(v) => { balitaState.edit.form.beratBadanKg = v === '' ? undefined : Number(v); }}
radius="md"
/>
<NumberInput
@@ -99,21 +99,21 @@ export default function BalitaEditPage() {
min={0}
decimalScale={1}
value={form.tinggiBadanCm ?? ''}
onChange={(v) => { form.tinggiBadanCm = v === '' ? undefined : Number(v); }}
onChange={(v) => { balitaState.edit.form.tinggiBadanCm = v === '' ? undefined : Number(v); }}
radius="md"
/>
<TextInput
label="Nama Orang Tua"
placeholder="Nama ayah/ibu"
value={form.namaOrtu}
onChange={(e) => { form.namaOrtu = e.currentTarget.value; }}
onChange={(e) => { balitaState.edit.form.namaOrtu = e.currentTarget.value; }}
radius="md"
/>
<TextInput
label="No. HP Orang Tua"
placeholder="08xx-xxxx-xxxx"
value={form.noHpOrtu}
onChange={(e) => { form.noHpOrtu = e.currentTarget.value; }}
onChange={(e) => { balitaState.edit.form.noHpOrtu = e.currentTarget.value; }}
radius="md"
/>
<Select
@@ -125,7 +125,7 @@ export default function BalitaEditPage() {
{ value: 'STUNTING', label: 'Stunting' },
]}
value={form.statusStunting}
onChange={(v) => { if (v) form.statusStunting = v as typeof form.statusStunting; }}
onChange={(v) => { if (v) balitaState.edit.form.statusStunting = v as typeof form.statusStunting; }}
radius="md"
/>
</SimpleGrid>
@@ -134,7 +134,7 @@ export default function BalitaEditPage() {
label="Alamat"
placeholder="Alamat lengkap"
value={form.alamat}
onChange={(e) => { form.alamat = e.currentTarget.value; }}
onChange={(e) => { balitaState.edit.form.alamat = e.currentTarget.value; }}
radius="md"
/>
@@ -142,17 +142,17 @@ export default function BalitaEditPage() {
<Checkbox
label="Imunisasi Lengkap"
checked={form.imunisasiLengkap}
onChange={(e) => { form.imunisasiLengkap = e.currentTarget.checked; }}
onChange={(e) => { balitaState.edit.form.imunisasiLengkap = e.currentTarget.checked; }}
/>
<Checkbox
label="Gizi Baik"
checked={form.giziBaik}
onChange={(e) => { form.giziBaik = e.currentTarget.checked; }}
onChange={(e) => { balitaState.edit.form.giziBaik = e.currentTarget.checked; }}
/>
<Checkbox
label="Pemeriksaan Rutin"
checked={form.pemeriksaanRutin}
onChange={(e) => { form.pemeriksaanRutin = e.currentTarget.checked; }}
onChange={(e) => { balitaState.edit.form.pemeriksaanRutin = e.currentTarget.checked; }}
/>
</Group>
@@ -160,7 +160,7 @@ export default function BalitaEditPage() {
label="Catatan"
placeholder="Catatan tambahan"
value={form.catatan}
onChange={(e) => { form.catatan = e.currentTarget.value; }}
onChange={(e) => { balitaState.edit.form.catatan = e.currentTarget.value; }}
radius="md"
rows={3}
/>

View File

@@ -25,9 +25,9 @@ export default function IbuHamilCreatePage() {
const form = state.create.form;
const handleSubmit = async () => {
const ok = await state.create.submit();
const ok = await ibuHamilState.create.submit();
if (ok) {
state.create.reset();
ibuHamilState.create.reset();
router.push('/admin/kesehatan/ibu-hamil');
}
};
@@ -49,14 +49,14 @@ export default function IbuHamilCreatePage() {
required
placeholder="Nama ibu hamil"
value={form.nama}
onChange={(e) => { form.nama = e.currentTarget.value; }}
onChange={(e) => { ibuHamilState.create.form.nama = e.currentTarget.value; }}
radius="md"
/>
<TextInput
label="NIK"
placeholder="Nomor Induk Kependudukan"
value={form.nik}
onChange={(e) => { form.nik = e.currentTarget.value; }}
onChange={(e) => { ibuHamilState.create.form.nik = e.currentTarget.value; }}
radius="md"
/>
<TextInput
@@ -64,28 +64,28 @@ export default function IbuHamilCreatePage() {
type="number"
placeholder="0"
value={String(form.usiaKehamilan)}
onChange={(e) => { form.usiaKehamilan = Number(e.currentTarget.value) || 0; }}
onChange={(e) => { ibuHamilState.create.form.usiaKehamilan = Number(e.currentTarget.value) || 0; }}
radius="md"
/>
<TextInput
label="No. HP"
placeholder="08xx-xxxx-xxxx"
value={form.noHp}
onChange={(e) => { form.noHp = e.currentTarget.value; }}
onChange={(e) => { ibuHamilState.create.form.noHp = e.currentTarget.value; }}
radius="md"
/>
<TextInput
label="HPHT (Hari Pertama Haid Terakhir)"
type="date"
value={form.hpht}
onChange={(e) => { form.hpht = e.currentTarget.value; }}
onChange={(e) => { ibuHamilState.create.form.hpht = e.currentTarget.value; }}
radius="md"
/>
<TextInput
label="Taksiran Persalinan"
type="date"
value={form.taksiranLahir}
onChange={(e) => { form.taksiranLahir = e.currentTarget.value; }}
onChange={(e) => { ibuHamilState.create.form.taksiranLahir = e.currentTarget.value; }}
radius="md"
/>
<Select
@@ -98,7 +98,7 @@ export default function IbuHamilCreatePage() {
{ value: 'NONAKTIF', label: 'Nonaktif' },
]}
value={form.status}
onChange={(v) => { if (v) form.status = v as typeof form.status; }}
onChange={(v) => { if (v) ibuHamilState.create.form.status = v as typeof form.status; }}
radius="md"
/>
</SimpleGrid>
@@ -107,7 +107,7 @@ export default function IbuHamilCreatePage() {
label="Alamat"
placeholder="Alamat lengkap"
value={form.alamat}
onChange={(e) => { form.alamat = e.currentTarget.value; }}
onChange={(e) => { ibuHamilState.create.form.alamat = e.currentTarget.value; }}
radius="md"
/>
@@ -115,7 +115,7 @@ export default function IbuHamilCreatePage() {
label="Catatan"
placeholder="Catatan tambahan"
value={form.catatan}
onChange={(e) => { form.catatan = e.currentTarget.value; }}
onChange={(e) => { ibuHamilState.create.form.catatan = e.currentTarget.value; }}
radius="md"
rows={3}
/>

View File

@@ -28,11 +28,11 @@ export default function IbuHamilEditPage() {
const form = state.edit.form;
useEffect(() => {
if (id) state.edit.load(id);
if (id) ibuHamilState.edit.load(id);
}, [id]); // eslint-disable-line react-hooks/exhaustive-deps
const handleSubmit = async () => {
const ok = await state.edit.update();
const ok = await ibuHamilState.edit.update();
if (ok) router.push('/admin/kesehatan/ibu-hamil');
};
@@ -53,14 +53,14 @@ export default function IbuHamilEditPage() {
required
placeholder="Nama ibu hamil"
value={form.nama}
onChange={(e) => { form.nama = e.currentTarget.value; }}
onChange={(e) => { ibuHamilState.edit.form.nama = e.currentTarget.value; }}
radius="md"
/>
<TextInput
label="NIK"
placeholder="Nomor Induk Kependudukan"
value={form.nik}
onChange={(e) => { form.nik = e.currentTarget.value; }}
onChange={(e) => { ibuHamilState.edit.form.nik = e.currentTarget.value; }}
radius="md"
/>
<TextInput
@@ -68,28 +68,28 @@ export default function IbuHamilEditPage() {
type="number"
placeholder="0"
value={String(form.usiaKehamilan)}
onChange={(e) => { form.usiaKehamilan = Number(e.currentTarget.value) || 0; }}
onChange={(e) => { ibuHamilState.edit.form.usiaKehamilan = Number(e.currentTarget.value) || 0; }}
radius="md"
/>
<TextInput
label="No. HP"
placeholder="08xx-xxxx-xxxx"
value={form.noHp}
onChange={(e) => { form.noHp = e.currentTarget.value; }}
onChange={(e) => { ibuHamilState.edit.form.noHp = e.currentTarget.value; }}
radius="md"
/>
<TextInput
label="HPHT"
type="date"
value={form.hpht}
onChange={(e) => { form.hpht = e.currentTarget.value; }}
onChange={(e) => { ibuHamilState.edit.form.hpht = e.currentTarget.value; }}
radius="md"
/>
<TextInput
label="Taksiran Persalinan"
type="date"
value={form.taksiranLahir}
onChange={(e) => { form.taksiranLahir = e.currentTarget.value; }}
onChange={(e) => { ibuHamilState.edit.form.taksiranLahir = e.currentTarget.value; }}
radius="md"
/>
<Select
@@ -102,7 +102,7 @@ export default function IbuHamilEditPage() {
{ value: 'NONAKTIF', label: 'Nonaktif' },
]}
value={form.status}
onChange={(v) => { if (v) form.status = v as typeof form.status; }}
onChange={(v) => { if (v) ibuHamilState.edit.form.status = v as typeof form.status; }}
radius="md"
/>
</SimpleGrid>
@@ -111,7 +111,7 @@ export default function IbuHamilEditPage() {
label="Alamat"
placeholder="Alamat lengkap"
value={form.alamat}
onChange={(e) => { form.alamat = e.currentTarget.value; }}
onChange={(e) => { ibuHamilState.edit.form.alamat = e.currentTarget.value; }}
radius="md"
/>
@@ -119,7 +119,7 @@ export default function IbuHamilEditPage() {
label="Catatan"
placeholder="Catatan tambahan"
value={form.catatan}
onChange={(e) => { form.catatan = e.currentTarget.value; }}
onChange={(e) => { ibuHamilState.edit.form.catatan = e.currentTarget.value; }}
radius="md"
rows={3}
/>