feat(kesehatan): admin page ringkasan-kesehatan + sidebar entry - bump ke 0.1.51
- New page src/app/admin/(dashboard)/kesehatan/ringkasan-kesehatan/page.tsx konsumsi ringkasanKesehatanState (load + submit) dengan 7 NumberInput (3 count + 4 pct). - Tambah Kesehatan_8 "Ringkasan Kesehatan" di 3 instance sidebar (list_PageAdmin.tsx). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -49,7 +49,9 @@ prisma/migrations/20260504000000_add_statistik_pct_ringkasan_kesehatan/migration
|
||||
src/app/api/[[...slugs]]/_lib/kesehatan/ringkasan-kesehatan/updt.ts
|
||||
src/app/api/[[...slugs]]/_lib/kesehatan/ringkasan-kesehatan/index.ts
|
||||
src/app/admin/(dashboard)/_state/kesehatan/ringkasan-kesehatan/ringkasanKesehatan.ts [NEW]
|
||||
package.json (0.1.48 → 0.1.50)
|
||||
src/app/admin/(dashboard)/kesehatan/ringkasan-kesehatan/page.tsx [NEW]
|
||||
src/app/admin/_com/list_PageAdmin.tsx (3 sidebar instances → tambah Kesehatan_8)
|
||||
package.json (0.1.48 → 0.1.51)
|
||||
MIND/PLAN/task-statistik-kesehatan-ringkasan.md [NEW]
|
||||
```
|
||||
|
||||
@@ -57,3 +59,4 @@ MIND/PLAN/task-statistik-kesehatan-ringkasan.md [NEW]
|
||||
|
||||
- `ba2b90be` feat(kesehatan): tambah 4 field statistik pct ke RingkasanKesehatanDesa - bump ke 0.1.49
|
||||
- `68a2a639` feat(kesehatan): tambah state file ringkasanKesehatan + bump ke 0.1.50
|
||||
- (next) feat(kesehatan): admin page ringkasan-kesehatan + sidebar entry - bump ke 0.1.51
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "desa-darmasaba",
|
||||
"version": "0.1.50",
|
||||
"version": "0.1.51",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "next dev",
|
||||
|
||||
194
src/app/admin/(dashboard)/kesehatan/ringkasan-kesehatan/page.tsx
Normal file
194
src/app/admin/(dashboard)/kesehatan/ringkasan-kesehatan/page.tsx
Normal file
@@ -0,0 +1,194 @@
|
||||
'use client';
|
||||
|
||||
import colors from '@/con/colors';
|
||||
import {
|
||||
Box,
|
||||
Button,
|
||||
Divider,
|
||||
Group,
|
||||
Loader,
|
||||
NumberInput,
|
||||
Paper,
|
||||
SimpleGrid,
|
||||
Stack,
|
||||
Text,
|
||||
Title,
|
||||
} from '@mantine/core';
|
||||
import { IconArrowBack } from '@tabler/icons-react';
|
||||
import { useRouter } from 'next/navigation';
|
||||
import { useEffect } from 'react';
|
||||
import { toast } from 'react-toastify';
|
||||
import { useProxy } from 'valtio/utils';
|
||||
import ringkasanKesehatanState from '../../_state/kesehatan/ringkasan-kesehatan/ringkasanKesehatan';
|
||||
|
||||
export default function RingkasanKesehatanPage() {
|
||||
const router = useRouter();
|
||||
const state = useProxy(ringkasanKesehatanState);
|
||||
|
||||
useEffect(() => {
|
||||
state.findUnique.load();
|
||||
}, []); // eslint-disable-line react-hooks/exhaustive-deps
|
||||
|
||||
const setField = (key: keyof typeof state.update.form, value: number) => {
|
||||
state.update.form[key] = Number.isFinite(value) ? value : 0;
|
||||
};
|
||||
|
||||
const handleSubmit = async () => {
|
||||
const ok = await state.update.submit();
|
||||
if (ok) router.refresh();
|
||||
};
|
||||
|
||||
const handleReset = () => {
|
||||
state.update.reset();
|
||||
if (state.findUnique.data) {
|
||||
const d = state.findUnique.data;
|
||||
state.update.form = {
|
||||
ibuHamilAkh: d.ibuHamilAkh,
|
||||
balitaTerdaftar: d.balitaTerdaftar,
|
||||
alertStunting: d.alertStunting,
|
||||
imunisasiLengkapPct: d.imunisasiLengkapPct,
|
||||
pemeriksaanRutinPct: d.pemeriksaanRutinPct,
|
||||
giziBaikPct: d.giziBaikPct,
|
||||
targetStuntingPct: d.targetStuntingPct,
|
||||
};
|
||||
}
|
||||
toast.info('Form dikembalikan ke data awal');
|
||||
};
|
||||
|
||||
const isLoading = state.findUnique.loading;
|
||||
const isSubmitting = state.update.loading;
|
||||
|
||||
return (
|
||||
<Box px={{ base: 0, md: 'lg' }} py="xs">
|
||||
<Group mb="md" gap="sm">
|
||||
<Button variant="subtle" onClick={() => router.back()} radius="md">
|
||||
<IconArrowBack size={20} stroke={2} />
|
||||
</Button>
|
||||
<Title order={3} c="black">Ringkasan Kesehatan Desa</Title>
|
||||
</Group>
|
||||
|
||||
<Paper
|
||||
withBorder
|
||||
w={{ base: '100%', md: '80%' }}
|
||||
p="lg"
|
||||
radius="md"
|
||||
shadow="xl"
|
||||
bg="white"
|
||||
>
|
||||
{isLoading ? (
|
||||
<Group justify="center" py="xl">
|
||||
<Loader />
|
||||
</Group>
|
||||
) : (
|
||||
<Stack gap="lg">
|
||||
<Box>
|
||||
<Text fw={600} mb="xs">KPI Utama</Text>
|
||||
<SimpleGrid cols={{ base: 1, md: 3 }} spacing="md">
|
||||
<NumberInput
|
||||
label="Ibu Hamil Aktif"
|
||||
description="Jumlah ibu hamil yang aktif tercatat"
|
||||
min={0}
|
||||
value={state.update.form.ibuHamilAkh}
|
||||
onChange={(v) => setField('ibuHamilAkh', Number(v))}
|
||||
radius="md"
|
||||
/>
|
||||
<NumberInput
|
||||
label="Balita Terdaftar"
|
||||
description="Total balita terdaftar di posyandu"
|
||||
min={0}
|
||||
value={state.update.form.balitaTerdaftar}
|
||||
onChange={(v) => setField('balitaTerdaftar', Number(v))}
|
||||
radius="md"
|
||||
/>
|
||||
<NumberInput
|
||||
label="Alert Stunting"
|
||||
description="Jumlah balita kategori alert stunting"
|
||||
min={0}
|
||||
value={state.update.form.alertStunting}
|
||||
onChange={(v) => setField('alertStunting', Number(v))}
|
||||
radius="md"
|
||||
/>
|
||||
</SimpleGrid>
|
||||
</Box>
|
||||
|
||||
<Divider />
|
||||
|
||||
<Box>
|
||||
<Text fw={600} mb="xs">Statistik Kesehatan (%)</Text>
|
||||
<SimpleGrid cols={{ base: 1, md: 2 }} spacing="md">
|
||||
<NumberInput
|
||||
label="Imunisasi Lengkap"
|
||||
description="Persentase balita imunisasi lengkap (0-100)"
|
||||
min={0}
|
||||
max={100}
|
||||
suffix="%"
|
||||
value={state.update.form.imunisasiLengkapPct}
|
||||
onChange={(v) => setField('imunisasiLengkapPct', Number(v))}
|
||||
radius="md"
|
||||
/>
|
||||
<NumberInput
|
||||
label="Pemeriksaan Rutin"
|
||||
description="Persentase warga pemeriksaan rutin (0-100)"
|
||||
min={0}
|
||||
max={100}
|
||||
suffix="%"
|
||||
value={state.update.form.pemeriksaanRutinPct}
|
||||
onChange={(v) => setField('pemeriksaanRutinPct', Number(v))}
|
||||
radius="md"
|
||||
/>
|
||||
<NumberInput
|
||||
label="Gizi Baik"
|
||||
description="Persentase balita dengan status gizi baik (0-100)"
|
||||
min={0}
|
||||
max={100}
|
||||
suffix="%"
|
||||
value={state.update.form.giziBaikPct}
|
||||
onChange={(v) => setField('giziBaikPct', Number(v))}
|
||||
radius="md"
|
||||
/>
|
||||
<NumberInput
|
||||
label="Target Stunting"
|
||||
description="Target penurunan stunting (0-100)"
|
||||
min={0}
|
||||
max={100}
|
||||
suffix="%"
|
||||
value={state.update.form.targetStuntingPct}
|
||||
onChange={(v) => setField('targetStuntingPct', Number(v))}
|
||||
radius="md"
|
||||
/>
|
||||
</SimpleGrid>
|
||||
</Box>
|
||||
|
||||
<Group justify="right">
|
||||
<Button
|
||||
variant="outline"
|
||||
color="gray"
|
||||
radius="md"
|
||||
size="md"
|
||||
onClick={handleReset}
|
||||
disabled={isSubmitting}
|
||||
>
|
||||
Batal
|
||||
</Button>
|
||||
<Button
|
||||
onClick={handleSubmit}
|
||||
radius="md"
|
||||
size="md"
|
||||
disabled={isSubmitting}
|
||||
style={{
|
||||
background: isSubmitting
|
||||
? 'linear-gradient(135deg, #cccccc, #eeeeee)'
|
||||
: `linear-gradient(135deg, ${colors['blue-button']}, #4facfe)`,
|
||||
color: '#fff',
|
||||
boxShadow: '0 4px 15px rgba(79, 172, 254, 0.4)',
|
||||
}}
|
||||
>
|
||||
{isSubmitting ? <Loader size="sm" color="white" /> : 'Simpan'}
|
||||
</Button>
|
||||
</Group>
|
||||
</Stack>
|
||||
)}
|
||||
</Paper>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
@@ -166,6 +166,11 @@ export const devBar = [
|
||||
id: "Kesehatan_7",
|
||||
name: "Info Wabah/Penyakit",
|
||||
path: "/admin/kesehatan/info-wabah-penyakit"
|
||||
},
|
||||
{
|
||||
id: "Kesehatan_8",
|
||||
name: "Ringkasan Kesehatan",
|
||||
path: "/admin/kesehatan/ringkasan-kesehatan"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -602,6 +607,11 @@ export const navBar = [
|
||||
id: "Kesehatan_7",
|
||||
name: "Info Wabah/Penyakit",
|
||||
path: "/admin/kesehatan/info-wabah-penyakit"
|
||||
},
|
||||
{
|
||||
id: "Kesehatan_8",
|
||||
name: "Ringkasan Kesehatan",
|
||||
path: "/admin/kesehatan/ringkasan-kesehatan"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -1272,6 +1282,11 @@ export const role2 = [
|
||||
id: "Kesehatan_7",
|
||||
name: "Info Wabah/Penyakit",
|
||||
path: "/admin/kesehatan/info-wabah-penyakit"
|
||||
},
|
||||
{
|
||||
id: "Kesehatan_8",
|
||||
name: "Ringkasan Kesehatan",
|
||||
path: "/admin/kesehatan/ringkasan-kesehatan"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user