Fix UI Mobile User & Admin Menu Kesehatan, QC Menu Kesehatan

This commit is contained in:
2025-09-25 10:40:47 +08:00
parent 3e4a7a1c0a
commit cac146471a
32 changed files with 381 additions and 523 deletions

View File

@@ -850,8 +850,8 @@ model JadwalKegiatan {
syaratKetentuanJadwalKegiatanId String syaratKetentuanJadwalKegiatanId String
dokumenjadwalkegiatan DokumenJadwalKegiatan @relation(fields: [dokumenJadwalKegiatanId], references: [id]) dokumenjadwalkegiatan DokumenJadwalKegiatan @relation(fields: [dokumenJadwalKegiatanId], references: [id])
dokumenJadwalKegiatanId String dokumenJadwalKegiatanId String
pendaftaranjadwalkegiatan PendaftaranJadwalKegiatan @relation(fields: [pendaftaranJadwalKegiatanId], references: [id]) pendaftaranjadwalkegiatan PendaftaranJadwalKegiatan? @relation(fields: [pendaftaranJadwalKegiatanId], references: [id])
pendaftaranJadwalKegiatanId String pendaftaranJadwalKegiatanId String?
createdAt DateTime @default(now()) createdAt DateTime @default(now())
updatedAt DateTime @updatedAt updatedAt DateTime @updatedAt
deletedAt DateTime @default(now()) deletedAt DateTime @default(now())

View File

@@ -26,14 +26,6 @@ const templateForm = z.object({
dokumenJadwalKegiatan: z.object({ dokumenJadwalKegiatan: z.object({
content: z.string().min(1, "Content minimal 1 karakter"), content: z.string().min(1, "Content minimal 1 karakter"),
}), }),
pendaftaranJadwalKegiatan: z.object({
name: z.string().min(1, "Name minimal 1 karakter"),
tanggal: z.string().min(1, "Tanggal minimal 1 karakter"),
namaOrangtua: z.string().min(1, "Nama Orangtua minimal 1 karakter"),
nomor: z.string().min(1, "Nomor minimal 1 karakter"),
alamat: z.string().min(1, "Alamat minimal 1 karakter"),
catatan: z.string().min(1, "Catatan minimal 1 karakter"),
}),
}); });
const defaultForm = { const defaultForm = {
@@ -55,15 +47,7 @@ const defaultForm = {
}, },
dokumenJadwalKegiatan: { dokumenJadwalKegiatan: {
content: "", content: "",
}, }
pendaftaranJadwalKegiatan: {
name: "",
tanggal: "",
namaOrangtua: "",
nomor: "",
alamat: "",
catatan: "",
},
}; };
const jadwalkegiatanState = proxy({ const jadwalkegiatanState = proxy({
@@ -116,7 +100,6 @@ const jadwalkegiatanState = proxy({
deskripsijadwalkegiatan: true; deskripsijadwalkegiatan: true;
layananjadwalkegiatan: true; layananjadwalkegiatan: true;
dokumenjadwalkegiatan: true; dokumenjadwalkegiatan: true;
pendaftaranjadwalkegiatan: true;
}; };
}>[] }>[]
| null, | null,
@@ -161,7 +144,6 @@ const jadwalkegiatanState = proxy({
layananjadwalkegiatan: true; layananjadwalkegiatan: true;
syaratketentuanjadwalkegiatan: true; syaratketentuanjadwalkegiatan: true;
dokumenjadwalkegiatan: true; dokumenjadwalkegiatan: true;
pendaftaranjadwalkegiatan: true;
}; };
}> | null, }> | null,
loading: false, loading: false,
@@ -209,15 +191,7 @@ const jadwalkegiatanState = proxy({
}, },
dokumenJadwalKegiatan: { dokumenJadwalKegiatan: {
content: data.dokumenjadwalkegiatan.content, content: data.dokumenjadwalkegiatan.content,
}, }
pendaftaranJadwalKegiatan: {
name: data.pendaftaranjadwalkegiatan.name,
tanggal: data.pendaftaranjadwalkegiatan.tanggal,
namaOrangtua: data.pendaftaranjadwalkegiatan.namaOrangtua,
nomor: data.pendaftaranjadwalkegiatan.nomor,
alamat: data.pendaftaranjadwalkegiatan.alamat,
catatan: data.pendaftaranjadwalkegiatan.catatan,
},
}; };
}, },
async submit() { async submit() {
@@ -259,20 +233,6 @@ const jadwalkegiatanState = proxy({
content: content:
jadwalkegiatanState.edit.form.dokumenJadwalKegiatan.content, jadwalkegiatanState.edit.form.dokumenJadwalKegiatan.content,
}, },
pendaftaranJadwalKegiatan: {
name: jadwalkegiatanState.edit.form.pendaftaranJadwalKegiatan.name,
tanggal:
jadwalkegiatanState.edit.form.pendaftaranJadwalKegiatan.tanggal,
namaOrangtua:
jadwalkegiatanState.edit.form.pendaftaranJadwalKegiatan
.namaOrangtua,
nomor:
jadwalkegiatanState.edit.form.pendaftaranJadwalKegiatan.nomor,
alamat:
jadwalkegiatanState.edit.form.pendaftaranJadwalKegiatan.alamat,
catatan:
jadwalkegiatanState.edit.form.pendaftaranJadwalKegiatan.catatan,
},
}; };
const res = await fetch( const res = await fetch(

View File

@@ -114,12 +114,22 @@ function ListFasilitasKesehatan({ search }: { search: string }) {
filteredData.map((item) => ( filteredData.map((item) => (
<TableTr key={item.id}> <TableTr key={item.id}>
<TableTd> <TableTd>
<Text fw={500} truncate="end" lineClamp={1}> <Box w={150}>
{item.name} <Text fw={500} truncate="end" lineClamp={1}>
</Text> {item.name}
</Text>
</Box>
</TableTd>
<TableTd>
<Box w={150}>
{item.dokterdantenagamedis?.name || '-'}
</Box>
</TableTd>
<TableTd>
<Box w={150}>
{item.tarifdanlayanan?.layanan || '-'}
</Box>
</TableTd> </TableTd>
<TableTd>{item.dokterdantenagamedis?.name || '-'}</TableTd>
<TableTd>{item.tarifdanlayanan?.layanan || '-'}</TableTd>
<TableTd> <TableTd>
<Button <Button
variant="light" variant="light"

View File

@@ -149,16 +149,30 @@ function ListGrafikHasilKepuasanMasyarakat({ search }: { search: string }) {
{filteredData.length > 0 ? ( {filteredData.length > 0 ? (
filteredData.map((item) => ( filteredData.map((item) => (
<TableTr key={item.id}> <TableTr key={item.id}>
<TableTd>{item.nama}</TableTd>
<TableTd> <TableTd>
{new Date(item.tanggal).toLocaleDateString('id-ID', { <Box w={150}>
day: '2-digit', {item.nama}
month: 'long', </Box>
year: 'numeric', </TableTd>
})} <TableTd>
<Box w={150}>
{new Date(item.tanggal).toLocaleDateString('id-ID', {
day: '2-digit',
month: 'long',
year: 'numeric',
})}
</Box>
</TableTd>
<TableTd>
<Box w={150}>
{item.jenisKelamin}
</Box>
</TableTd>
<TableTd>
<Box w={150}>
{item.penyakit}
</Box>
</TableTd> </TableTd>
<TableTd>{item.jenisKelamin}</TableTd>
<TableTd>{item.penyakit}</TableTd>
<TableTd> <TableTd>
<Button <Button
variant="light" variant="light"
@@ -212,24 +226,26 @@ function ListGrafikHasilKepuasanMasyarakat({ search }: { search: string }) {
<Paper bg={colors['white-1']} p={'md'}> <Paper bg={colors['white-1']} p={'md'}>
<Title pb={10} order={4}>Grafik Hasil Kepuasan Masyarakat</Title> <Title pb={10} order={4}>Grafik Hasil Kepuasan Masyarakat</Title>
{mounted && diseaseChartData.length > 0 ? ( {mounted && diseaseChartData.length > 0 ? (
<BarChart <Center>
width={isMobile ? 450 : isTablet ? 500 : 550} <BarChart
height={350} width={isMobile ? 320 : isTablet ? 600 : 800} // kecilin biar muat
data={diseaseChartData} height={350}
> data={diseaseChartData}
<XAxis >
dataKey="name" <XAxis
tick={{ fontSize: 12 }} dataKey="name"
interval={0} tick={{ fontSize: 12 }}
angle={-45} interval={0}
textAnchor="end" angle={-45}
height={70} textAnchor="end"
/> height={70}
<YAxis /> />
<ChartTooltip /> <YAxis />
<Legend /> <ChartTooltip />
<Bar dataKey="count" fill={colors['blue-button']} name="Jumlah Kasus" /> <Legend />
</BarChart> <Bar dataKey="count" fill={colors['blue-button']} name="Jumlah Kasus" />
</BarChart>
</Center>
) : ( ) : (
<Text c="dimmed">Belum ada data untuk ditampilkan dalam grafik</Text> <Text c="dimmed">Belum ada data untuk ditampilkan dalam grafik</Text>
)} )}

View File

@@ -41,14 +41,6 @@ interface JadwalKegiatanFormBase {
dokumenJadwalKegiatan: { dokumenJadwalKegiatan: {
content: string; content: string;
}; };
pendaftaranJadwalKegiatan: {
name: string;
tanggal: string;
namaOrangtua: string;
nomor: string;
alamat: string;
catatan: string;
};
} }
function EditJadwalKegiatan() { function EditJadwalKegiatan() {
@@ -76,14 +68,6 @@ function EditJadwalKegiatan() {
dokumenJadwalKegiatan: { dokumenJadwalKegiatan: {
content: stateJadwalKegiatan.edit.form.dokumenJadwalKegiatan?.content || '', content: stateJadwalKegiatan.edit.form.dokumenJadwalKegiatan?.content || '',
}, },
pendaftaranJadwalKegiatan: {
name: stateJadwalKegiatan.edit.form.pendaftaranJadwalKegiatan?.name || '',
tanggal: stateJadwalKegiatan.edit.form.pendaftaranJadwalKegiatan?.tanggal || '',
namaOrangtua: stateJadwalKegiatan.edit.form.pendaftaranJadwalKegiatan?.namaOrangtua || '',
nomor: stateJadwalKegiatan.edit.form.pendaftaranJadwalKegiatan?.nomor || '',
alamat: stateJadwalKegiatan.edit.form.pendaftaranJadwalKegiatan?.alamat || '',
catatan: stateJadwalKegiatan.edit.form.pendaftaranJadwalKegiatan?.catatan || '',
},
}); });
useEffect(() => { useEffect(() => {
@@ -115,14 +99,6 @@ function EditJadwalKegiatan() {
dokumenJadwalKegiatan: { dokumenJadwalKegiatan: {
content: form.dokumenJadwalKegiatan?.content || '', content: form.dokumenJadwalKegiatan?.content || '',
}, },
pendaftaranJadwalKegiatan: {
name: form.pendaftaranJadwalKegiatan?.name || '',
tanggal: form.pendaftaranJadwalKegiatan?.tanggal || '',
namaOrangtua: form.pendaftaranJadwalKegiatan?.namaOrangtua || '',
nomor: form.pendaftaranJadwalKegiatan?.nomor || '',
alamat: form.pendaftaranJadwalKegiatan?.alamat || '',
catatan: form.pendaftaranJadwalKegiatan?.catatan || '',
},
}); });
} }
} catch (error) { } catch (error) {
@@ -142,8 +118,7 @@ function EditJadwalKegiatan() {
deskripsiJadwalKegiatan: { ...formData.deskripsiJadwalKegiatan }, deskripsiJadwalKegiatan: { ...formData.deskripsiJadwalKegiatan },
layananJadwalKegiatan: { ...formData.layananJadwalKegiatan }, layananJadwalKegiatan: { ...formData.layananJadwalKegiatan },
syaratKetentuanJadwalKegiatan: { ...formData.syaratKetentuanJadwalKegiatan }, syaratKetentuanJadwalKegiatan: { ...formData.syaratKetentuanJadwalKegiatan },
dokumenJadwalKegiatan: { ...formData.dokumenJadwalKegiatan }, dokumenJadwalKegiatan: { ...formData.dokumenJadwalKegiatan }
pendaftaranJadwalKegiatan: { ...formData.pendaftaranJadwalKegiatan },
}; };
const success = await stateJadwalKegiatan.edit.submit(); const success = await stateJadwalKegiatan.edit.submit();
@@ -252,7 +227,7 @@ function EditJadwalKegiatan() {
{/* Dokumen */} {/* Dokumen */}
<Box> <Box>
<Text fz="md" fw="bold">Dokumen Jadwal Kegiatan</Text> <Text fz="md" fw="bold">Dokumen Yang Perlu Dibawa</Text>
<EditEditor <EditEditor
value={formData.dokumenJadwalKegiatan.content} value={formData.dokumenJadwalKegiatan.content}
onChange={(val) => setFormData((prev) => ({ onChange={(val) => setFormData((prev) => ({
@@ -262,41 +237,6 @@ function EditJadwalKegiatan() {
/> />
</Box> </Box>
{/* Pendaftaran */}
<Box>
<Text fz="md" fw="bold">Pendaftaran Jadwal Kegiatan</Text>
<TextInput label="Nama" value={formData.pendaftaranJadwalKegiatan.name}
onChange={(e) => setFormData((prev) => ({
...prev, pendaftaranJadwalKegiatan: { ...prev.pendaftaranJadwalKegiatan, name: e.target.value }
}))}
/>
<TextInput type="date" label="Tanggal" value={formData.pendaftaranJadwalKegiatan.tanggal}
onChange={(e) => setFormData((prev) => ({
...prev, pendaftaranJadwalKegiatan: { ...prev.pendaftaranJadwalKegiatan, tanggal: e.target.value }
}))}
/>
<TextInput label="Nama Orangtua" value={formData.pendaftaranJadwalKegiatan.namaOrangtua}
onChange={(e) => setFormData((prev) => ({
...prev, pendaftaranJadwalKegiatan: { ...prev.pendaftaranJadwalKegiatan, namaOrangtua: e.target.value }
}))}
/>
<TextInput label="Nomor" value={formData.pendaftaranJadwalKegiatan.nomor}
onChange={(e) => setFormData((prev) => ({
...prev, pendaftaranJadwalKegiatan: { ...prev.pendaftaranJadwalKegiatan, nomor: e.target.value }
}))}
/>
<TextInput label="Alamat" value={formData.pendaftaranJadwalKegiatan.alamat}
onChange={(e) => setFormData((prev) => ({
...prev, pendaftaranJadwalKegiatan: { ...prev.pendaftaranJadwalKegiatan, alamat: e.target.value }
}))}
/>
<TextInput label="Catatan" value={formData.pendaftaranJadwalKegiatan.catatan}
onChange={(e) => setFormData((prev) => ({
...prev, pendaftaranJadwalKegiatan: { ...prev.pendaftaranJadwalKegiatan, catatan: e.target.value }
}))}
/>
</Box>
{/* Submit */} {/* Submit */}
<Group justify="right"> <Group justify="right">
<Button <Button

View File

@@ -109,18 +109,7 @@ function DetailJadwalKegiatan() {
<Text fz="lg" fw="bold">Dokumen</Text> <Text fz="lg" fw="bold">Dokumen</Text>
<Text fz="md" c="dimmed" dangerouslySetInnerHTML={{ __html: data.dokumenjadwalkegiatan.content }} /> <Text fz="md" c="dimmed" dangerouslySetInnerHTML={{ __html: data.dokumenjadwalkegiatan.content }} />
</Box> </Box>
{/* Prosedur Pendaftaran */}
<Box>
<Text fz="lg" fw="bold">Prosedur Pendaftaran</Text>
<Text fz="md" c="dimmed">{data.pendaftaranjadwalkegiatan.name}</Text>
<Text fz="md" c="dimmed">{data.pendaftaranjadwalkegiatan.tanggal}</Text>
<Text fz="md" c="dimmed">{data.pendaftaranjadwalkegiatan.namaOrangtua}</Text>
<Text fz="md" c="dimmed">{data.pendaftaranjadwalkegiatan.nomor}</Text>
<Text fz="md" c="dimmed">{data.pendaftaranjadwalkegiatan.alamat}</Text>
<Text fz="md" c="dimmed" dangerouslySetInnerHTML={{ __html: data.pendaftaranjadwalkegiatan.catatan }} />
</Box>
{/* Aksi */} {/* Aksi */}
<Group gap="sm"> <Group gap="sm">
<Tooltip label="Hapus Data" withArrow position="top"> <Tooltip label="Hapus Data" withArrow position="top">

View File

@@ -42,15 +42,7 @@ function CreateJadwalKegiatan() {
}, },
dokumenJadwalKegiatan: { dokumenJadwalKegiatan: {
content: '', content: '',
}, }
pendaftaranJadwalKegiatan: {
name: '',
tanggal: '',
namaOrangtua: '',
nomor: '',
alamat: '',
catatan: '',
},
}; };
}; };
@@ -173,7 +165,7 @@ function CreateJadwalKegiatan() {
</Box> </Box>
<Box> <Box>
<Text fz="md" fw="bold" mb="sm">Dokumen</Text> <Text fz="md" fw="bold" mb="sm">Dokumen Yang Perlu Dibawa</Text>
<CreateEditor <CreateEditor
value={stateJadwalKegiatan.create.form.dokumenJadwalKegiatan.content} value={stateJadwalKegiatan.create.form.dokumenJadwalKegiatan.content}
onChange={(e) => { onChange={(e) => {
@@ -181,65 +173,6 @@ function CreateJadwalKegiatan() {
}} }}
/> />
</Box> </Box>
<Box>
<Text fz="md" fw="bold" mb="sm">Pendaftaran Jadwal Kegiatan</Text>
<TextInput
label="Nama"
required
placeholder="Masukkan nama"
value={stateJadwalKegiatan.create.form.pendaftaranJadwalKegiatan.name}
onChange={(e) => {
stateJadwalKegiatan.create.form.pendaftaranJadwalKegiatan.name = e.target.value;
}}
/>
<TextInput
type="date"
required
label="Tanggal"
value={stateJadwalKegiatan.create.form.pendaftaranJadwalKegiatan.tanggal}
onChange={(e) => {
stateJadwalKegiatan.create.form.pendaftaranJadwalKegiatan.tanggal = e.target.value;
}}
/>
<TextInput
label="Nama Orangtua"
required
placeholder="Masukkan nama orangtua"
value={stateJadwalKegiatan.create.form.pendaftaranJadwalKegiatan.namaOrangtua}
onChange={(e) => {
stateJadwalKegiatan.create.form.pendaftaranJadwalKegiatan.namaOrangtua = e.target.value;
}}
/>
<TextInput
label="Nomor"
required
placeholder="Masukkan nomor"
value={stateJadwalKegiatan.create.form.pendaftaranJadwalKegiatan.nomor}
onChange={(e) => {
stateJadwalKegiatan.create.form.pendaftaranJadwalKegiatan.nomor = e.target.value;
}}
/>
<TextInput
label="Alamat"
required
placeholder="Masukkan alamat"
value={stateJadwalKegiatan.create.form.pendaftaranJadwalKegiatan.alamat}
onChange={(e) => {
stateJadwalKegiatan.create.form.pendaftaranJadwalKegiatan.alamat = e.target.value;
}}
/>
<TextInput
label="Catatan"
required
placeholder="Masukkan catatan"
value={stateJadwalKegiatan.create.form.pendaftaranJadwalKegiatan.catatan}
onChange={(e) => {
stateJadwalKegiatan.create.form.pendaftaranJadwalKegiatan.catatan = e.target.value;
}}
/>
</Box>
{/* Save Button */} {/* Save Button */}
<Group justify="right"> <Group justify="right">
<Button <Button

View File

@@ -111,11 +111,14 @@ function ListJadwalKegiatan({ search }: { search: string }) {
filteredData.map((item) => ( filteredData.map((item) => (
<TableTr key={item.id}> <TableTr key={item.id}>
<TableTd> <TableTd>
<Text fw={500} truncate="end" lineClamp={1}> <Box w={150}>
{item.informasijadwalkegiatan.name} <Text fw={500} truncate="end" lineClamp={1}>
</Text> {item.informasijadwalkegiatan.name}
</Text>
</Box>
</TableTd> </TableTd>
<TableTd> <TableTd>
<Box w={150}>
{new Date(item.informasijadwalkegiatan.tanggal).toLocaleDateString( {new Date(item.informasijadwalkegiatan.tanggal).toLocaleDateString(
'id-ID', 'id-ID',
{ {
@@ -124,12 +127,19 @@ function ListJadwalKegiatan({ search }: { search: string }) {
year: 'numeric', year: 'numeric',
} }
)} )}
</Box>
</TableTd> </TableTd>
<TableTd>{item.informasijadwalkegiatan.waktu}</TableTd>
<TableTd> <TableTd>
<Text truncate fz="sm" c="dimmed"> <Box w={150}>
{item.informasijadwalkegiatan.lokasi} {item.informasijadwalkegiatan.waktu}
</Text> </Box>
</TableTd>
<TableTd>
<Box w={150}>
<Text truncate fz="sm" c="dimmed">
{item.informasijadwalkegiatan.lokasi}
</Text>
</Box>
</TableTd> </TableTd>
<TableTd> <TableTd>
<Button <Button

View File

@@ -124,22 +124,32 @@ function ListKelahiran({ search }: { search: string }) {
filteredData.map((item) => ( filteredData.map((item) => (
<TableTr key={item.id}> <TableTr key={item.id}>
<TableTd> <TableTd>
<Box w={150}>
<Text fw={500} truncate="end" lineClamp={1}> <Text fw={500} truncate="end" lineClamp={1}>
{item.nama} {item.nama}
</Text> </Text>
</Box>
</TableTd> </TableTd>
<TableTd> <TableTd>
<Box w={150}>
{new Date(item.tanggal).toLocaleDateString('id-ID', { {new Date(item.tanggal).toLocaleDateString('id-ID', {
day: '2-digit', day: '2-digit',
month: 'long', month: 'long',
year: 'numeric', year: 'numeric',
})} })}
</Box>
</TableTd> </TableTd>
<TableTd>{item.jenisKelamin}</TableTd>
<TableTd> <TableTd>
<Box w={150}>
{item.jenisKelamin}
</Box>
</TableTd>
<TableTd>
<Box w={150}>
<Text truncate fz="sm" c="dimmed"> <Text truncate fz="sm" c="dimmed">
{item.alamat} {item.alamat}
</Text> </Text>
</Box>
</TableTd> </TableTd>
<TableTd> <TableTd>
<Button <Button

View File

@@ -13,152 +13,150 @@ import colors from '@/con/colors';
function DetailKematian() { function DetailKematian() {
const state = useProxy(persentaseKelahiranKematian.kematian); const state = useProxy(persentaseKelahiranKematian.kematian);
const [modalHapus, setModalHapus] = useState(false); const [modalHapus, setModalHapus] = useState(false);
const [selectedId, setSelectedId] = useState<string | null>(null); const [selectedId, setSelectedId] = useState<string | null>(null);
const params = useParams(); const params = useParams();
const router = useRouter(); const router = useRouter();
useShallowEffect(() => { useShallowEffect(() => {
state.findUnique.load(params?.id as string); state.findUnique.load(params?.id as string);
}, []); }, []);
const handleHapus = () => { const handleHapus = () => {
if (selectedId) { if (selectedId) {
state.delete.byId(selectedId); state.delete.byId(selectedId);
setModalHapus(false); setModalHapus(false);
setSelectedId(null); setSelectedId(null);
router.push("/admin/kesehatan/data-kesehatan-warga/persentase_data_kelahiran_kematian/kelahiran"); router.push("/admin/kesehatan/data-kesehatan-warga/persentase_data_kelahiran_kematian/kelahiran");
} }
}; };
if (!state.findUnique.data) { if (!state.findUnique.data) {
return ( return (
<Stack py={10}> <Stack py={10}>
<Skeleton height={500} radius="md" /> <Skeleton height={500} radius="md" />
</Stack> </Stack>
); );
} }
const data = state.findUnique.data; const data = state.findUnique.data;
return ( return (
<Box py={10}> <Box py={10}>
{/* Tombol kembali */} {/* Tombol kembali */}
<Button <Button
variant="subtle" variant="subtle"
onClick={() => router.back()} onClick={() => router.back()}
leftSection={<IconArrowBack size={24} color={colors['blue-button']} />} leftSection={<IconArrowBack size={24} color={colors['blue-button']} />}
mb={15} mb={15}
> >
Kembali Kembali
</Button> </Button>
<Paper <Paper
withBorder withBorder
w={{ base: "100%", md: "50%" }} w={{ base: "100%", md: "50%" }}
bg={colors['white-1']} bg={colors['white-1']}
p="lg" p="lg"
radius="md" radius="md"
shadow="sm" shadow="sm"
> >
<Stack gap="md"> <Stack gap="md">
<Text fz="2xl" fw="bold" c={colors['blue-button']}> <Text fz="2xl" fw="bold" c={colors['blue-button']}>
Detail Data Kematian Detail Data Kematian
</Text> </Text>
<Paper bg="#ECEEF8" p="md" radius="md" shadow="xs"> <Paper bg="#ECEEF8" p="md" radius="md" shadow="xs">
<Stack gap="sm"> <Stack gap="sm">
<Box> <Box>
<Text fz="lg" fw="bold">Nama</Text> <Text fz="lg" fw="bold">Nama</Text>
<Text fz="md" c="dimmed">{data?.nama || '-'}</Text> <Text fz="md" c="dimmed">{data?.nama || '-'}</Text>
</Box> </Box>
<Box> <Box>
<Text fz="lg" fw="bold">Tanggal</Text> <Text fz="lg" fw="bold">Tanggal</Text>
<Text fz="md" c="dimmed"> <Text fz="md" c="dimmed">
{data?.tanggal instanceof Date {new Date(data.tanggal).toLocaleDateString("id-ID", {
? data.tanggal.toLocaleDateString('id-ID', { day: "2-digit",
day: '2-digit', month: "long",
month: 'long', year: "numeric",
year: 'numeric' })}
}) </Text>
: data?.tanggal || '-'} </Box>
</Text>
</Box>
<Box> <Box>
<Text fz="lg" fw="bold">Jenis Kelamin</Text> <Text fz="lg" fw="bold">Jenis Kelamin</Text>
<Text fz="md" c="dimmed">{data?.jenisKelamin || '-'}</Text> <Text fz="md" c="dimmed">{data?.jenisKelamin || '-'}</Text>
</Box> </Box>
<Box> <Box>
<Text fz="lg" fw="bold">Alamat</Text> <Text fz="lg" fw="bold">Alamat</Text>
<Text fz="md" c="dimmed">{data?.alamat || '-'}</Text> <Text fz="md" c="dimmed">{data?.alamat || '-'}</Text>
</Box> </Box>
<Box> <Box>
<Text fz="lg" fw="bold">Penyebab</Text> <Text fz="lg" fw="bold">Penyebab</Text>
<Text fz="md" c="dimmed" dangerouslySetInnerHTML={{ __html: data?.penyebab || '-' }} /> <Text fz="md" c="dimmed" dangerouslySetInnerHTML={{ __html: data?.penyebab || '-' }} />
</Box> </Box>
<Group gap="sm"> <Group gap="sm">
<Tooltip label="Hapus Data" withArrow position="top"> <Tooltip label="Hapus Data" withArrow position="top">
<Button <Button
color="red" color="red"
onClick={() => { onClick={() => {
setSelectedId(data.id); setSelectedId(data.id);
setModalHapus(true); setModalHapus(true);
}} }}
variant="light" variant="light"
radius="md" radius="md"
size="md" size="md"
> >
<IconTrash size={20} /> <IconTrash size={20} />
</Button> </Button>
</Tooltip> </Tooltip>
<Tooltip label="Edit Data" withArrow position="top"> <Tooltip label="Edit Data" withArrow position="top">
<Button <Button
color="green" color="green"
onClick={() => router.push( onClick={() => router.push(
`/admin/kesehatan/data-kesehatan-warga/persentase_data_kelahiran_kematian/kematian/${data.id}/edit` `/admin/kesehatan/data-kesehatan-warga/persentase_data_kelahiran_kematian/kematian/${data.id}/edit`
)} )}
variant="light" variant="light"
radius="md" radius="md"
size="md" size="md"
> >
<IconEdit size={20} /> <IconEdit size={20} />
</Button> </Button>
</Tooltip> </Tooltip>
</Group> </Group>
</Stack> </Stack>
</Paper> </Paper>
</Stack> </Stack>
</Paper> </Paper>
<ModalKonfirmasiHapus <ModalKonfirmasiHapus
opened={modalHapus} opened={modalHapus}
onClose={() => setModalHapus(false)} onClose={() => setModalHapus(false)}
onConfirm={handleHapus} onConfirm={handleHapus}
text="Apakah Anda yakin ingin menghapus data ini?" text="Apakah Anda yakin ingin menghapus data ini?"
/> />
</Box> </Box>
); );
} }

View File

@@ -122,19 +122,33 @@ function ListKematian({ search }: { search: string }) {
filteredData.map((item) => ( filteredData.map((item) => (
<TableTr key={item.id}> <TableTr key={item.id}>
<TableTd> <TableTd>
<Box w={150}>
<Text fw={500} truncate="end" lineClamp={1}> <Text fw={500} truncate="end" lineClamp={1}>
{item.nama} {item.nama}
</Text> </Text>
</Box>
</TableTd> </TableTd>
<TableTd> <TableTd>
<Box w={150}>
{new Date(item.tanggal).toLocaleDateString('id-ID', { {new Date(item.tanggal).toLocaleDateString('id-ID', {
day: '2-digit', day: '2-digit',
month: 'long', month: 'long',
year: 'numeric', year: 'numeric',
})} })}
</Box>
</TableTd>
<TableTd>
<Box w={150}>
{item.jenisKelamin}
</Box>
</TableTd>
<TableTd>
<Box w={150}>
<Text truncate fz="sm" c="dimmed">
{item.alamat}
</Text>
</Box>
</TableTd> </TableTd>
<TableTd>{item.jenisKelamin}</TableTd>
<TableTd>{item.alamat}</TableTd>
<TableTd> <TableTd>
<Button <Button
variant="light" variant="light"

View File

@@ -4,7 +4,7 @@ import {
Box, Box,
Button, Button,
Center, Center,
Image, Group,
Pagination, Pagination,
Paper, Paper,
Skeleton, Skeleton,
@@ -17,16 +17,15 @@ import {
TableTr, TableTr,
Text, Text,
Title, Title,
Tooltip, Tooltip
Group,
} from '@mantine/core'; } from '@mantine/core';
import { IconDeviceImacCog, IconPlus, IconSearch } from '@tabler/icons-react';
import HeaderSearch from '../../_com/header';
import { useRouter } from 'next/navigation';
import { useProxy } from 'valtio/utils';
import infoWabahPenyakit from '../../_state/kesehatan/info-wabah-penyakit/infoWabahPenyakit';
import { useShallowEffect } from '@mantine/hooks'; import { useShallowEffect } from '@mantine/hooks';
import { IconDeviceImacCog, IconPlus, IconSearch } from '@tabler/icons-react';
import { useRouter } from 'next/navigation';
import { useState } from 'react'; import { useState } from 'react';
import { useProxy } from 'valtio/utils';
import HeaderSearch from '../../_com/header';
import infoWabahPenyakit from '../../_state/kesehatan/info-wabah-penyakit/infoWabahPenyakit';
function InfoWabahPenyakit() { function InfoWabahPenyakit() {
const [search, setSearch] = useState(""); const [search, setSearch] = useState("");
@@ -96,7 +95,6 @@ function ListInfoWabahPenyakit({ search }: { search: string }) {
<TableTr> <TableTr>
<TableTh>Judul</TableTh> <TableTh>Judul</TableTh>
<TableTh>Deskripsi Singkat</TableTh> <TableTh>Deskripsi Singkat</TableTh>
<TableTh>Image</TableTh>
<TableTh>Aksi</TableTh> <TableTh>Aksi</TableTh>
</TableTr> </TableTr>
</TableThead> </TableThead>
@@ -105,17 +103,18 @@ function ListInfoWabahPenyakit({ search }: { search: string }) {
filteredData.map((item) => ( filteredData.map((item) => (
<TableTr key={item.id}> <TableTr key={item.id}>
<TableTd> <TableTd>
<Text fw={500} truncate="end" lineClamp={1}> <Box w={200}>
{item.name} <Text fw={500} truncate="end" lineClamp={1}>
</Text> {item.name}
</Text>
</Box>
</TableTd> </TableTd>
<TableTd> <TableTd>
<Text truncate fz="sm" c="dimmed"> <Box w={200}>
{item.deskripsiSingkat} <Text truncate fz="sm" c="dimmed">
</Text> {item.deskripsiSingkat}
</TableTd> </Text>
<TableTd> </Box>
<Image w={100} src={item.image?.link} alt="image" radius="md" loading="lazy"/>
</TableTd> </TableTd>
<TableTd> <TableTd>
<Button <Button

View File

@@ -4,7 +4,7 @@ import {
Box, Box,
Button, Button,
Center, Center,
Image, Group,
Pagination, Pagination,
Paper, Paper,
Skeleton, Skeleton,
@@ -17,7 +17,7 @@ import {
TableTr, TableTr,
Text, Text,
Title, Title,
Tooltip, Tooltip
} from '@mantine/core'; } from '@mantine/core';
import { useShallowEffect } from '@mantine/hooks'; import { useShallowEffect } from '@mantine/hooks';
import { IconDeviceImacCog, IconPlus, IconSearch } from '@tabler/icons-react'; import { IconDeviceImacCog, IconPlus, IconSearch } from '@tabler/icons-react';
@@ -71,7 +71,7 @@ function ListKontakDarurat({ search }: { search: string }) {
<Paper withBorder bg={colors['white-1']} p={'lg'} shadow="md" radius="md"> <Paper withBorder bg={colors['white-1']} p={'lg'} shadow="md" radius="md">
{/* Judul + Tombol Tambah */} {/* Judul + Tombol Tambah */}
<Stack mb="md" gap="sm"> <Stack mb="md" gap="sm">
<Box display="flex" style={{ justifyContent: "space-between", alignItems: "center" }}> <Group justify="space-between">
<Title order={4}>Daftar Kontak Darurat</Title> <Title order={4}>Daftar Kontak Darurat</Title>
<Tooltip label="Tambah Kontak Darurat" withArrow> <Tooltip label="Tambah Kontak Darurat" withArrow>
<Button <Button
@@ -83,7 +83,7 @@ function ListKontakDarurat({ search }: { search: string }) {
Tambah Baru Tambah Baru
</Button> </Button>
</Tooltip> </Tooltip>
</Box> </Group>
</Stack> </Stack>
{/* Tabel */} {/* Tabel */}
@@ -93,7 +93,6 @@ function ListKontakDarurat({ search }: { search: string }) {
<TableTr> <TableTr>
<TableTh>Judul</TableTh> <TableTh>Judul</TableTh>
<TableTh>Deskripsi</TableTh> <TableTh>Deskripsi</TableTh>
<TableTh>Image</TableTh>
<TableTh>Aksi</TableTh> <TableTh>Aksi</TableTh>
</TableTr> </TableTr>
</TableThead> </TableThead>
@@ -102,15 +101,16 @@ function ListKontakDarurat({ search }: { search: string }) {
filteredData.map((item) => ( filteredData.map((item) => (
<TableTr key={item.id}> <TableTr key={item.id}>
<TableTd> <TableTd>
<Text fw={500} truncate="end" lineClamp={1}> <Box w={150}>
{item.name} <Text fw={500} truncate="end" lineClamp={1}>
</Text> {item.name}
</Text>
</Box>
</TableTd> </TableTd>
<TableTd> <TableTd>
<Text truncate fz="sm" c="dimmed" lineClamp={1} dangerouslySetInnerHTML={{ __html: item.deskripsi }} /> <Box w={200}>
</TableTd> <Text truncate fz="sm" c="dimmed" lineClamp={1} dangerouslySetInnerHTML={{ __html: item.deskripsi }} />
<TableTd> </Box>
<Image w={100} src={item.image?.link} alt="image" radius="md" loading="lazy"/>
</TableTd> </TableTd>
<TableTd> <TableTd>
<Button <Button

View File

@@ -5,7 +5,6 @@ import {
Button, Button,
Center, Center,
Group, Group,
Image,
Pagination, Pagination,
Paper, Paper,
Skeleton, Skeleton,
@@ -18,15 +17,15 @@ import {
TableTr, TableTr,
Text, Text,
Title, Title,
Tooltip, Tooltip
} from '@mantine/core'; } from '@mantine/core';
import { IconDeviceImacCog, IconPlus, IconSearch } from '@tabler/icons-react';
import HeaderSearch from '../../_com/header';
import { useRouter } from 'next/navigation';
import { useProxy } from 'valtio/utils';
import { useShallowEffect } from '@mantine/hooks'; import { useShallowEffect } from '@mantine/hooks';
import penangananDarurat from '../../_state/kesehatan/penanganan-darurat/penangananDarurat'; import { IconDeviceImacCog, IconPlus, IconSearch } from '@tabler/icons-react';
import { useRouter } from 'next/navigation';
import { useState } from 'react'; import { useState } from 'react';
import { useProxy } from 'valtio/utils';
import HeaderSearch from '../../_com/header';
import penangananDarurat from '../../_state/kesehatan/penanganan-darurat/penangananDarurat';
function PenangananDarurat() { function PenangananDarurat() {
const [search, setSearch] = useState(""); const [search, setSearch] = useState("");
@@ -91,7 +90,6 @@ function ListPenangananDarurat({ search }: { search: string }) {
<TableTr> <TableTr>
<TableTh>Judul</TableTh> <TableTh>Judul</TableTh>
<TableTh>Deskripsi</TableTh> <TableTh>Deskripsi</TableTh>
<TableTh>Gambar</TableTh>
<TableTh>Aksi</TableTh> <TableTh>Aksi</TableTh>
</TableTr> </TableTr>
</TableThead> </TableThead>
@@ -100,21 +98,22 @@ function ListPenangananDarurat({ search }: { search: string }) {
filteredData.map((item) => ( filteredData.map((item) => (
<TableTr key={item.id}> <TableTr key={item.id}>
<TableTd> <TableTd>
<Text fw={500} truncate="end" lineClamp={1}> <Box w={150}>
{item.name} <Text fw={500} truncate="end" lineClamp={1}>
</Text> {item.name}
</Text>
</Box>
</TableTd> </TableTd>
<TableTd> <TableTd>
<Text <Box w={200}>
fz="sm" <Text
c="dimmed" fz="sm"
truncate c="dimmed"
lineClamp={1} truncate
lineClamp={1}
dangerouslySetInnerHTML={{ __html: item.deskripsi }} dangerouslySetInnerHTML={{ __html: item.deskripsi }}
/> />
</TableTd> </Box>
<TableTd>
<Image w={100} src={item.image?.link} alt="image" loading="lazy"/>
</TableTd> </TableTd>
<TableTd> <TableTd>
<Button <Button

View File

@@ -107,21 +107,28 @@ function ListPosyandu({ search }: { search: string }) {
filteredData.map((item) => ( filteredData.map((item) => (
<TableTr key={item.id}> <TableTr key={item.id}>
<TableTd style={{ width: '25%' }}> <TableTd style={{ width: '25%' }}>
<Box w={150}>
<Text fw={500} truncate="end" lineClamp={1}> <Text fw={500} truncate="end" lineClamp={1}>
{item.name} {item.name}
</Text> </Text>
</Box>
</TableTd> </TableTd>
<TableTd style={{ width: '20%' }}> <TableTd style={{ width: '20%' }}>
<Box w={150}>
<Text truncate fz="sm" c="dimmed"> <Text truncate fz="sm" c="dimmed">
{item.nomor || '-'} {item.nomor || '-'}
</Text> </Text>
</Box>
</TableTd> </TableTd>
<TableTd style={{ width: '30%' }}> <TableTd style={{ width: '30%' }}>
<Box w={150}>
<Text <Text
lineClamp={1}
truncate truncate
fz="sm" fz="sm"
dangerouslySetInnerHTML={{ __html: item.deskripsi }} dangerouslySetInnerHTML={{ __html: item.deskripsi }}
/> />
</Box>
</TableTd> </TableTd>
<TableTd style={{ width: '15%' }}> <TableTd style={{ width: '15%' }}>
<Button <Button

View File

@@ -5,7 +5,6 @@ import {
Button, Button,
Center, Center,
Group, Group,
Image,
Pagination, Pagination,
Paper, Paper,
Skeleton, Skeleton,
@@ -18,15 +17,15 @@ import {
TableTr, TableTr,
Text, Text,
Title, Title,
Tooltip, Tooltip
} from '@mantine/core'; } from '@mantine/core';
import { IconDeviceImacCog, IconPlus, IconSearch } from '@tabler/icons-react';
import HeaderSearch from '../../_com/header';
import { useRouter } from 'next/navigation';
import programKesehatan from '../../_state/kesehatan/program-kesehatan/programKesehatan';
import { useProxy } from 'valtio/utils';
import { useShallowEffect } from '@mantine/hooks'; import { useShallowEffect } from '@mantine/hooks';
import { IconDeviceImacCog, IconPlus, IconSearch } from '@tabler/icons-react';
import { useRouter } from 'next/navigation';
import { useState } from 'react'; import { useState } from 'react';
import { useProxy } from 'valtio/utils';
import HeaderSearch from '../../_com/header';
import programKesehatan from '../../_state/kesehatan/program-kesehatan/programKesehatan';
function ProgramKesehatan() { function ProgramKesehatan() {
const [search, setSearch] = useState(""); const [search, setSearch] = useState("");
@@ -90,7 +89,7 @@ function ListProgramKesehatan({ search }: { search: string }) {
<TableTr> <TableTr>
<TableTh>Judul</TableTh> <TableTh>Judul</TableTh>
<TableTh>Deskripsi Singkat</TableTh> <TableTh>Deskripsi Singkat</TableTh>
<TableTh>Image</TableTh> <TableTh>Deskripsi</TableTh>
<TableTh>Aksi</TableTh> <TableTh>Aksi</TableTh>
</TableTr> </TableTr>
</TableThead> </TableThead>
@@ -105,11 +104,13 @@ function ListProgramKesehatan({ search }: { search: string }) {
</TableTd> </TableTd>
<TableTd> <TableTd>
<Box w={200}> <Box w={200}>
<Text fz="sm" truncate="end" lineClamp={2} dangerouslySetInnerHTML={{ __html: item.deskripsiSingkat }} /> <Text fz="sm" truncate="end" lineClamp={1} dangerouslySetInnerHTML={{ __html: item.deskripsiSingkat }} />
</Box> </Box>
</TableTd> </TableTd>
<TableTd> <TableTd>
<Image w={100} src={item.image?.link} alt="image" radius="md" loading="lazy"/> <Box w={200}>
<Text fz="sm" truncate="end" lineClamp={1} dangerouslySetInnerHTML={{ __html: item.deskripsi }} />
</Box>
</TableTd> </TableTd>
<TableTd> <TableTd>
<Button <Button

View File

@@ -78,8 +78,9 @@ function DetailPuskesmas() {
<Box> <Box>
<Text fz="lg" fw="bold">Jam Operasional</Text> <Text fz="lg" fw="bold">Jam Operasional</Text>
<Text fz="md" c="dimmed">{data?.jam?.workDays || '-'}</Text> <Text fz="md" c="dimmed">Senin - Jumat</Text>
<Text fz="md" c="dimmed">{data?.jam?.weekDays || '-'}</Text> <Text fz="md" c="dimmed">{data?.jam?.workDays || '-'} - {data?.jam?.weekDays || '-'}</Text>
<Text fz="md" c="dimmed">Sabtu - Minggu / Hari Libur</Text>
<Text fz="md" c="dimmed">{data?.jam?.holiday || '-'}</Text> <Text fz="md" c="dimmed">{data?.jam?.holiday || '-'}</Text>
</Box> </Box>
@@ -94,9 +95,13 @@ function DetailPuskesmas() {
<Box> <Box>
<Text fz="lg" fw="bold">Kontak</Text> <Text fz="lg" fw="bold">Kontak</Text>
<Text fz="md" c="dimmed">Kontak Puskesmas</Text>
<Text fz="md" c="dimmed">{data?.kontak?.kontakPuskesmas || '-'}</Text> <Text fz="md" c="dimmed">{data?.kontak?.kontakPuskesmas || '-'}</Text>
<Text fz="md" c="dimmed">Email</Text>
<Text fz="md" c="dimmed">{data?.kontak?.email || '-'}</Text> <Text fz="md" c="dimmed">{data?.kontak?.email || '-'}</Text>
<Text fz="md" c="dimmed">Facebook</Text>
<Text fz="md" c="dimmed">{data?.kontak?.facebook || '-'}</Text> <Text fz="md" c="dimmed">{data?.kontak?.facebook || '-'}</Text>
<Text fz="md" c="dimmed">Kontak UGD</Text>
<Text fz="md" c="dimmed">{data?.kontak?.kontakUGD || '-'}</Text> <Text fz="md" c="dimmed">{data?.kontak?.kontakUGD || '-'}</Text>
</Box> </Box>

View File

@@ -5,7 +5,6 @@ import {
Button, Button,
Center, Center,
Group, Group,
Image,
Pagination, Pagination,
Paper, Paper,
Skeleton, Skeleton,
@@ -18,7 +17,7 @@ import {
TableTr, TableTr,
Text, Text,
Title, Title,
Tooltip, Tooltip
} from '@mantine/core'; } from '@mantine/core';
import { useShallowEffect } from '@mantine/hooks'; import { useShallowEffect } from '@mantine/hooks';
import { IconDeviceImacCog, IconPlus, IconSearch } from '@tabler/icons-react'; import { IconDeviceImacCog, IconPlus, IconSearch } from '@tabler/icons-react';
@@ -90,7 +89,7 @@ function ListPuskesmas({ search }: { search: string }) {
<TableTr> <TableTr>
<TableTh>Nama Puskesmas</TableTh> <TableTh>Nama Puskesmas</TableTh>
<TableTh>Alamat</TableTh> <TableTh>Alamat</TableTh>
<TableTh>Image</TableTh> <TableTh>Kontak</TableTh>
<TableTh>Aksi</TableTh> <TableTh>Aksi</TableTh>
</TableTr> </TableTr>
</TableThead> </TableThead>
@@ -99,13 +98,25 @@ function ListPuskesmas({ search }: { search: string }) {
filteredData.map((item) => ( filteredData.map((item) => (
<TableTr key={item.id}> <TableTr key={item.id}>
<TableTd> <TableTd>
<Text fw={500} truncate="end" lineClamp={1}> <Box w={150}>
{item.name} <Text fw={500} truncate="end" lineClamp={1}>
</Text> {item.name}
</Text>
</Box>
</TableTd> </TableTd>
<TableTd>{item.alamat}</TableTd>
<TableTd> <TableTd>
<Image w={100} src={item.image.link} alt="image" radius="md" loading="lazy"/> <Box w={150}>
<Text truncate fz="sm" c="dimmed" lineClamp={1}>
{item.alamat}
</Text>
</Box>
</TableTd>
<TableTd>
<Box w={150}>
<Text truncate fz="sm" c="dimmed" lineClamp={1}>
{item.kontak.kontakPuskesmas}
</Text>
</Box>
</TableTd> </TableTd>
<TableTd> <TableTd>
<Button <Button

View File

@@ -8,7 +8,6 @@ type JadwalKegiatanInput = {
layananJadwalKegiatan: { content: string }; layananJadwalKegiatan: { content: string };
syaratKetentuanJadwalKegiatan: { content: string }; syaratKetentuanJadwalKegiatan: { content: string };
dokumenJadwalKegiatan: { content: string }; dokumenJadwalKegiatan: { content: string };
pendaftaranJadwalKegiatan: { name: string, tanggal: string, namaOrangtua: string, nomor: string, alamat: string, catatan: string };
} }
const jadwalKegiatanCreate = async (context: Context) => { const jadwalKegiatanCreate = async (context: Context) => {
@@ -21,16 +20,14 @@ const jadwalKegiatanCreate = async (context: Context) => {
layananJadwalKegiatan, layananJadwalKegiatan,
syaratKetentuanJadwalKegiatan, syaratKetentuanJadwalKegiatan,
dokumenJadwalKegiatan, dokumenJadwalKegiatan,
pendaftaranJadwalKegiatan,
} = body; } = body;
const [createdInformasiJadwalKegiatan, createdDeskripsiJadwalKegiatan, createdLayananJadwalKegiatan, createdSyaratKetentuanJadwalKegiatan, createdDokumenJadwalKegiatan, createdPendaftaranJadwalKegiatan] = await Promise.all([ const [createdInformasiJadwalKegiatan, createdDeskripsiJadwalKegiatan, createdLayananJadwalKegiatan, createdSyaratKetentuanJadwalKegiatan, createdDokumenJadwalKegiatan] = await Promise.all([
prisma.informasiJadwalKegiatan.create({ data: informasiJadwalKegiatan }), prisma.informasiJadwalKegiatan.create({ data: informasiJadwalKegiatan }),
prisma.deskripsiJadwalKegiatan.create({ data: deskripsiJadwalKegiatan }), prisma.deskripsiJadwalKegiatan.create({ data: deskripsiJadwalKegiatan }),
prisma.layananJadwalKegiatan.create({ data: layananJadwalKegiatan }), prisma.layananJadwalKegiatan.create({ data: layananJadwalKegiatan }),
prisma.syaratKetentuanJadwalKegiatan.create({ data: syaratKetentuanJadwalKegiatan }), prisma.syaratKetentuanJadwalKegiatan.create({ data: syaratKetentuanJadwalKegiatan }),
prisma.dokumenJadwalKegiatan.create({ data: dokumenJadwalKegiatan }), prisma.dokumenJadwalKegiatan.create({ data: dokumenJadwalKegiatan }),
prisma.pendaftaranJadwalKegiatan.create({ data: pendaftaranJadwalKegiatan }),
]) ])
const jadwalKegiatan = await prisma.jadwalKegiatan.create({ const jadwalKegiatan = await prisma.jadwalKegiatan.create({
@@ -41,7 +38,6 @@ const jadwalKegiatanCreate = async (context: Context) => {
layananJadwalKegiatanId: createdLayananJadwalKegiatan.id, layananJadwalKegiatanId: createdLayananJadwalKegiatan.id,
syaratKetentuanJadwalKegiatanId: createdSyaratKetentuanJadwalKegiatan.id, syaratKetentuanJadwalKegiatanId: createdSyaratKetentuanJadwalKegiatan.id,
dokumenJadwalKegiatanId: createdDokumenJadwalKegiatan.id, dokumenJadwalKegiatanId: createdDokumenJadwalKegiatan.id,
pendaftaranJadwalKegiatanId: createdPendaftaranJadwalKegiatan.id,
}, },
include: { include: {
informasijadwalkegiatan: true, informasijadwalkegiatan: true,
@@ -49,7 +45,6 @@ const jadwalKegiatanCreate = async (context: Context) => {
layananjadwalkegiatan: true, layananjadwalkegiatan: true,
syaratketentuanjadwalkegiatan: true, syaratketentuanjadwalkegiatan: true,
dokumenjadwalkegiatan: true, dokumenjadwalkegiatan: true,
pendaftaranjadwalkegiatan: true,
} }
}) })
return { return {

View File

@@ -19,7 +19,6 @@ const jadwalKegiatanDelete = async (context: Context) => {
layananjadwalkegiatan: true, layananjadwalkegiatan: true,
syaratketentuanjadwalkegiatan: true, syaratketentuanjadwalkegiatan: true,
dokumenjadwalkegiatan: true, dokumenjadwalkegiatan: true,
pendaftaranjadwalkegiatan: true,
} }
}) })

View File

@@ -20,7 +20,6 @@ export default async function jadwalKegiatanFindMany(context: Context) {
{layananjadwalkegiatan: { content: { contains: search, mode: "insensitive" } } }, {layananjadwalkegiatan: { content: { contains: search, mode: "insensitive" } } },
{syaratketentuanjadwalkegiatan: { content: { contains: search, mode: "insensitive" } } }, {syaratketentuanjadwalkegiatan: { content: { contains: search, mode: "insensitive" } } },
{dokumenjadwalkegiatan: { content: { contains: search, mode: "insensitive" } } }, {dokumenjadwalkegiatan: { content: { contains: search, mode: "insensitive" } } },
{pendaftaranjadwalkegiatan: { content: { contains: search, mode: "insensitive" } } },
]; ];
} }
try { try {
@@ -33,8 +32,7 @@ export default async function jadwalKegiatanFindMany(context: Context) {
layananjadwalkegiatan: true, layananjadwalkegiatan: true,
syaratketentuanjadwalkegiatan: true, syaratketentuanjadwalkegiatan: true,
dokumenjadwalkegiatan: true, dokumenjadwalkegiatan: true,
pendaftaranjadwalkegiatan: true, },
},
skip, skip,
take: limit, take: limit,
orderBy: { createdAt: "desc" }, orderBy: { createdAt: "desc" },

View File

@@ -28,7 +28,6 @@ export default async function jadwalKegiatanFindUnique(request: Request) {
layananjadwalkegiatan: true, layananjadwalkegiatan: true,
syaratketentuanjadwalkegiatan: true, syaratketentuanjadwalkegiatan: true,
dokumenjadwalkegiatan: true, dokumenjadwalkegiatan: true,
pendaftaranjadwalkegiatan: true,
} }
}) })

View File

@@ -30,14 +30,6 @@ const JadwalKegiatan = new Elysia({
dokumenJadwalKegiatan: t.Object({ dokumenJadwalKegiatan: t.Object({
content: t.String(), content: t.String(),
}), }),
pendaftaranJadwalKegiatan: t.Object({
name: t.String(),
tanggal: t.String(),
namaOrangtua: t.String(),
nomor: t.String(),
alamat: t.String(),
catatan: t.String(),
}),
}), }),
}) })
.get("/find-many", jadwalKegiatanFindMany) .get("/find-many", jadwalKegiatanFindMany)
@@ -75,14 +67,6 @@ const JadwalKegiatan = new Elysia({
dokumenJadwalKegiatan: t.Object({ dokumenJadwalKegiatan: t.Object({
content: t.String(), content: t.String(),
}), }),
pendaftaranJadwalKegiatan: t.Object({
name: t.String(),
tanggal: t.String(),
namaOrangtua: t.String(),
nomor: t.String(),
alamat: t.String(),
catatan: t.String(),
}),
}), }),
} }
); );

View File

@@ -13,14 +13,6 @@ type JadwalKegiatanUpdateInput = {
layananJadwalKegiatan: { content: string }; layananJadwalKegiatan: { content: string };
syaratKetentuanJadwalKegiatan: { content: string }; syaratKetentuanJadwalKegiatan: { content: string };
dokumenJadwalKegiatan: { content: string }; dokumenJadwalKegiatan: { content: string };
pendaftaranJadwalKegiatan: {
name: string;
tanggal: string;
namaOrangtua: string;
nomor: string;
alamat: string;
catatan: string;
};
}; };
const jadwalKegiatanUpdate = async (context: Context) => { const jadwalKegiatanUpdate = async (context: Context) => {
@@ -50,7 +42,6 @@ const jadwalKegiatanUpdate = async (context: Context) => {
layananJadwalKegiatan, layananJadwalKegiatan,
syaratKetentuanJadwalKegiatan, syaratKetentuanJadwalKegiatan,
dokumenJadwalKegiatan, dokumenJadwalKegiatan,
pendaftaranJadwalKegiatan,
} = body; } = body;
await Promise.all([ await Promise.all([
@@ -74,10 +65,6 @@ const jadwalKegiatanUpdate = async (context: Context) => {
where: { id: existing.dokumenJadwalKegiatanId }, where: { id: existing.dokumenJadwalKegiatanId },
data: dokumenJadwalKegiatan data: dokumenJadwalKegiatan
}), }),
prisma.pendaftaranJadwalKegiatan.update({
where: { id: existing.pendaftaranJadwalKegiatanId },
data: pendaftaranJadwalKegiatan,
}),
]); ]);
const updated = await prisma.jadwalKegiatan.update({ const updated = await prisma.jadwalKegiatan.update({
@@ -91,7 +78,6 @@ const jadwalKegiatanUpdate = async (context: Context) => {
layananjadwalkegiatan: true, layananjadwalkegiatan: true,
syaratketentuanjadwalkegiatan: true, syaratketentuanjadwalkegiatan: true,
dokumenjadwalkegiatan: true, dokumenjadwalkegiatan: true,
pendaftaranjadwalkegiatan: true,
}, },
}); });
return { return {

View File

@@ -2,7 +2,7 @@
import artikelKesehatanState from '@/app/admin/(dashboard)/_state/kesehatan/data_kesehatan_warga/artikelKesehatan'; import artikelKesehatanState from '@/app/admin/(dashboard)/_state/kesehatan/data_kesehatan_warga/artikelKesehatan';
import BackButton from '@/app/darmasaba/(pages)/desa/layanan/_com/BackButto'; import BackButton from '@/app/darmasaba/(pages)/desa/layanan/_com/BackButto';
import colors from '@/con/colors'; import colors from '@/con/colors';
import { Box, Divider, Group, List, ListItem, Paper, Skeleton, Stack, Table, TableTbody, TableTd, TableTh, TableThead, TableTr, Text } from '@mantine/core'; import { Box, Divider, Group, Image, List, ListItem, Paper, Skeleton, Stack, Table, TableTbody, TableTd, TableTh, TableThead, TableTr, Text } from '@mantine/core';
import { useShallowEffect } from '@mantine/hooks'; import { useShallowEffect } from '@mantine/hooks';
import { IconAlertCircle, IconCalendar, IconInfoCircle } from '@tabler/icons-react'; import { IconAlertCircle, IconCalendar, IconInfoCircle } from '@tabler/icons-react';
import { useParams } from 'next/navigation'; import { useParams } from 'next/navigation';
@@ -42,6 +42,24 @@ function Page() {
</Text> </Text>
</Box> </Box>
<Box p="lg">
<Box style={{ position: 'relative', width: '100%', maxWidth: '800px', margin: '0 auto' }}>
<Image
src={state.findUnique.data.image?.link}
alt={state.findUnique.data.title}
height={0}
style={{
height: 'auto',
width: '100%',
maxHeight: '500px',
objectFit: 'contain',
borderRadius: '8px'
}}
loading="lazy"
/>
</Box>
</Box>
<Box p="lg"> <Box p="lg">
<Stack gap="lg"> <Stack gap="lg">
<Group gap="xs"> <Group gap="xs">
@@ -56,7 +74,7 @@ function Page() {
</Group> </Group>
<Stack gap="lg"> <Stack gap="lg">
<Box> <Box>
<Text fz="h4" fw="bold">Pendahuluan</Text> <Text fz="h4" fw="bold">Pendahuluan</Text>
<Divider my="xs" /> <Divider my="xs" />

View File

@@ -3,9 +3,9 @@
import fasilitasKesehatanState from '@/app/admin/(dashboard)/_state/kesehatan/data_kesehatan_warga/fasilitasKesehatan'; import fasilitasKesehatanState from '@/app/admin/(dashboard)/_state/kesehatan/data_kesehatan_warga/fasilitasKesehatan';
import BackButton from '@/app/darmasaba/(pages)/desa/layanan/_com/BackButto'; import BackButton from '@/app/darmasaba/(pages)/desa/layanan/_com/BackButto';
import colors from '@/con/colors'; import colors from '@/con/colors';
import { ActionIcon, Anchor, AspectRatio, Badge, Box, Button, Card, Chip, CopyButton, Divider, Grid, Group, List, ListItem, Paper, Skeleton, Stack, Table, TableTbody, TableTd, TableTh, TableThead, TableTr, Text, ThemeIcon, Title, Tooltip } from '@mantine/core'; import { ActionIcon, Anchor, AspectRatio, Badge, Box, Button, Card, Chip, CopyButton, Divider, Grid, Group, Paper, Skeleton, Stack, Table, TableTbody, TableTd, TableTh, TableThead, TableTr, Text, ThemeIcon, Title, Tooltip } from '@mantine/core';
import { useShallowEffect } from '@mantine/hooks'; import { useShallowEffect } from '@mantine/hooks';
import { IconArrowRight, IconBrandWhatsapp, IconCheck, IconCopy, IconDeviceLandlinePhone, IconFileDownload, IconHeart, IconInfoCircle, IconMail, IconMapPin, IconMoodEmpty, IconSearch, IconStethoscope, IconUser, IconUsersGroup, IconWallet } from '@tabler/icons-react'; import { IconBrandWhatsapp, IconCheck, IconCopy, IconDeviceLandlinePhone, IconHeart, IconInfoCircle, IconMail, IconMapPin, IconMoodEmpty, IconSearch, IconStethoscope, IconUser, IconUsersGroup, IconWallet } from '@tabler/icons-react';
import { useParams } from 'next/navigation'; import { useParams } from 'next/navigation';
import { useMemo } from 'react'; import { useMemo } from 'react';
import { useProxy } from 'valtio/utils'; import { useProxy } from 'valtio/utils';
@@ -16,14 +16,6 @@ interface Kontak {
email: string; email: string;
} }
interface LayananItem {
nama: string;
keterangan?: string;
}
interface LayananUnggulan {
items: LayananItem[];
}
interface Lokasi { interface Lokasi {
mapsEmbed: string; mapsEmbed: string;
@@ -46,21 +38,23 @@ function Page() {
const data = state.findUnique.data as any; // Temporary any to fix type issues const data = state.findUnique.data as any; // Temporary any to fix type issues
const nama = data?.name || 'Fasilitas Kesehatan'; const nama = data?.name || 'Fasilitas Kesehatan';
const prosedur = data?.prosedurpendaftaran.content || '';
console.log("Prosedur:", data?.prosedurpendaftaran);
const alamat = data?.informasiumum?.alamat || '-'; const alamat = data?.informasiumum?.alamat || '-';
const jam = data?.informasiumum?.jamOperasional || '-'; const jam = data?.informasiumum?.jamOperasional || '-';
const layananUnggulan = (data?.layananunggulan as LayananUnggulan)?.items || []; const layananUnggulan = data?.layananunggulan || '';
const tenaga = data?.dokterdantenagamedis || null; const tenaga = data?.dokterdantenagamedis || null;
const fasilitasPendukungHtml = data?.fasilitaspendukung?.content || ''; const fasilitasPendukungHtml = data?.fasilitaspendukung?.content || '';
const tarif = (data?.tarifdanlayanan as TarifDanLayanan) || null; const tarif = (data?.tarifdanlayanan as TarifDanLayanan) || null;
const kontak = (data?.kontak as Kontak) || { const kontak = (data?.kontak as Kontak) || {
telepon: '(0361) 123456', telepon: '(0361) 123456',
whatsapp: '6289647037426', whatsapp: '6289647037426',
email: 'info@fasilitas-kesehatan.id' email: 'info@fasilitas-kesehatan.id'
}; };
const lokasi = (data?.lokasi as Lokasi) || { const lokasi = (data?.lokasi as Lokasi) || {
mapsEmbed: 'https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d3945.272172359321!2d115.21836257533302!3d-8.569807186941553!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x2dd23e9d99b9395f%3A0xb002795fdcb33b30!2sUPTD%20Puskesmas%20Abiansemal%20III!5e0!3m2!1sid!2sid!4v1744792682341!5m2!1sid!2sid' mapsEmbed: 'https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d3945.272172359321!2d115.21836257533302!3d-8.569807186941553!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x2dd23e9d99b9395f%3A0xb002795fdcb33b30!2sUPTD%20Puskesmas%20Abiansemal%20III!5e0!3m2!1sid!2sid!4v1744792682341!5m2!1sid!2sid'
}; };
const gratisBpjs = (data?.tarifdanlayanan as TarifDanLayanan)?.gratisBpjs ?? true; const gratisBpjs = (data?.tarifdanlayanan as TarifDanLayanan)?.gratisBpjs ?? true;
const formatRupiah = useMemo( const formatRupiah = useMemo(
@@ -187,22 +181,14 @@ function Page() {
</Group> </Group>
<Divider /> <Divider />
<Title order={4}>Layanan Unggulan</Title> <Title order={4}>Layanan Unggulan</Title>
{Array.isArray(layananUnggulan) && layananUnggulan.length > 0 ? ( <Divider />
<List spacing="xs" icon={<ThemeIcon variant="light" radius="xl"><IconArrowRight size={16} /></ThemeIcon>}> {layananUnggulan ? (
{layananUnggulan.map((x: any, idx: number) => ( <Text fz="md" style={{ lineHeight: 1.7 }} dangerouslySetInnerHTML={{ __html: layananUnggulan }} />
<ListItem key={idx}>
<Group gap="xs" wrap="wrap">
<Text fw={600}>{x?.nama || 'Layanan'}</Text>
{x?.keterangan && <Badge variant="light" radius="sm">{x.keterangan}</Badge>}
</Group>
</ListItem>
))}
</List>
) : ( ) : (
<Paper withBorder radius="md" p="md"> <Paper withBorder radius="md" p="md">
<Group gap="sm"> <Group gap="sm">
<IconMoodEmpty /> <IconMoodEmpty />
<Text>Tidak ada layanan unggulan yang tercatat.</Text> <Text>Belum ada informasi fasilitas pendukung.</Text>
</Group> </Group>
</Paper> </Paper>
)} )}
@@ -322,9 +308,6 @@ function Page() {
<Text fw={600}>Gratis dengan BPJS Kesehatan</Text> <Text fw={600}>Gratis dengan BPJS Kesehatan</Text>
</Group> </Group>
)} )}
<Group>
<Button variant="gradient" gradient={{ from: 'blue', to: 'cyan' }} leftSection={<IconFileDownload size={18} />}>Unduh Brosur (PDF)</Button>
</Group>
</Stack> </Stack>
</Card> </Card>
</Grid.Col> </Grid.Col>
@@ -336,13 +319,11 @@ function Page() {
<Stack gap="md"> <Stack gap="md">
<Title order={3}>Prosedur Pendaftaran</Title> <Title order={3}>Prosedur Pendaftaran</Title>
<Divider /> <Divider />
<List type="ordered" spacing="xs" icon={<ThemeIcon variant="light" radius="xl"><IconArrowRight size={16} /></ThemeIcon>}> {prosedur ? (
<ListItem>Pendaftaran dibuka pukul 07.30 WITA</ListItem> <Text fz="md" style={{ lineHeight: 1.7 }} dangerouslySetInnerHTML={{ __html: prosedur }} />
<ListItem>Bawa KTP dan Kartu BPJS (jika ada)</ListItem> ) : (
<ListItem>Ambil nomor antrian di loket pendaftaran</ListItem> <Text fz="md" c="dimmed">Belum ada prosedur pendaftaran</Text>
<ListItem>Pengunjung baru mengisi formulir pendaftaran</ListItem> )}
<ListItem>Pendaftaran online tersedia melalui aplikasi S-Sehat</ListItem>
</List>
</Stack> </Stack>
</Paper> </Paper>
</Box> </Box>

View File

@@ -4,7 +4,6 @@ import BackButton from '@/app/darmasaba/(pages)/desa/layanan/_com/BackButto';
import colors from '@/con/colors'; import colors from '@/con/colors';
import { import {
Box, Box,
Button,
Divider, Divider,
Group, Group,
Paper, Paper,
@@ -13,7 +12,7 @@ import {
Text Text
} from '@mantine/core'; } from '@mantine/core';
import { useShallowEffect } from '@mantine/hooks'; import { useShallowEffect } from '@mantine/hooks';
import { IconDownload, IconMail, IconPhone, IconUser } from '@tabler/icons-react'; import { IconMail, IconPhone, IconUser } from '@tabler/icons-react';
import { useParams } from 'next/navigation'; import { useParams } from 'next/navigation';
import { useProxy } from 'valtio/utils'; import { useProxy } from 'valtio/utils';
import CreatePendaftaran from '../create/page'; import CreatePendaftaran from '../create/page';
@@ -107,12 +106,6 @@ function Page() {
</Group> </Group>
</Stack> </Stack>
</Paper> </Paper>
<Group>
<Button size="md" radius="lg" leftSection={<IconDownload size={18} />} color="green">
Unduh Jadwal Posyandu 2025 (PDF)
</Button>
</Group>
</Stack> </Stack>
</Box> </Box>
</Paper> </Paper>

View File

@@ -32,7 +32,7 @@ function Page() {
const { data, page, totalPages, loading, load } = state.findMany; const { data, page, totalPages, loading, load } = state.findMany;
useShallowEffect(() => { useShallowEffect(() => {
load(page, 6, search); load(page, 3, search);
}, [page, search]); }, [page, search]);
if (loading || !data) { if (loading || !data) {
@@ -153,7 +153,7 @@ function Page() {
)} )}
</Box> </Box>
{totalPages > 1 && (
<Center> <Center>
<Pagination <Pagination
value={page} value={page}
@@ -164,7 +164,7 @@ function Page() {
mt="lg" mt="lg"
/> />
</Center> </Center>
)}
</Stack> </Stack>
); );
} }

View File

@@ -1,7 +1,7 @@
'use client' 'use client'
import posyandustate from "@/app/admin/(dashboard)/_state/kesehatan/posyandu/posyandu"; import posyandustate from "@/app/admin/(dashboard)/_state/kesehatan/posyandu/posyandu";
import colors from "@/con/colors"; import colors from "@/con/colors";
import { Badge, Box, Center, Flex, Image, List, ListItem, Pagination, Paper, SimpleGrid, Skeleton, Spoiler, Stack, Text, TextInput } from "@mantine/core"; import { Badge, Box, Center, Flex, Group, Image, List, ListItem, Pagination, Paper, SimpleGrid, Skeleton, Spoiler, Stack, Text, TextInput } from "@mantine/core";
import { useShallowEffect } from "@mantine/hooks"; import { useShallowEffect } from "@mantine/hooks";
import { IconCalendar, IconInfoCircle, IconPhone, IconSearch } from "@tabler/icons-react"; import { IconCalendar, IconInfoCircle, IconPhone, IconSearch } from "@tabler/icons-react";
import { useState } from "react"; import { useState } from "react";
@@ -82,14 +82,14 @@ export default function Page() {
}} }}
> >
<Stack gap="sm"> <Stack gap="sm">
<Flex justify="space-between" align="center"> <Group justify="space-between" align="center">
<Text c={colors["blue-button"]} fw="bold" fz="lg" lineClamp={1}> <Text c={colors["blue-button"]} fw="bold" fz="lg" lineClamp={1}>
{v.name} {v.name}
</Text> </Text>
<Badge color="blue" variant="light" size="sm" radius="sm"> <Badge color="blue" variant="light" size="sm" radius="sm">
Aktif Aktif
</Badge> </Badge>
</Flex> </Group>
<Center> <Center>
<Image <Image
src={v.image.link} src={v.image.link}

View File

@@ -90,18 +90,25 @@ function Page() {
<Divider /> <Divider />
<Box> <Stack gap={"xs"}>
<Title order={3} mb={10}>Jam Operasional</Title> <Title order={3} mb={10}>Jam Operasional</Title>
<Text fw="bold" fz="md">Senin - Jumat</Text>
<Group gap={8}> <Group gap={8}>
<IconClock size={18} /> <IconClock size={18} />
<Text fw="bold" fz="md"> <Text fw="bold" fz="md">{data.jam.workDays} - {data.jam.weekDays}</Text>
{data.jam.workDays} - {data.jam.weekDays}
</Text>
<Tooltip label="Hari aktif pelayanan puskesmas" position="top" withArrow> <Tooltip label="Hari aktif pelayanan puskesmas" position="top" withArrow>
<Badge size="sm" variant="light" color="blue">Aktif</Badge> <Badge size="sm" variant="light" color="blue">Aktif</Badge>
</Tooltip> </Tooltip>
</Group> </Group>
</Box> <Text fw="bold" fz="md">Sabtu - Minggu / Hari Libur</Text>
<Group gap={8}>
<IconClock size={18} />
<Text fw="bold" fz="md">{data.jam.holiday}</Text>
<Tooltip label="Hari aktif pelayanan puskesmas" position="top" withArrow>
<Badge size="sm" variant="light" color="blue">Aktif</Badge>
</Tooltip>
</Group>
</Stack>
</Stack> </Stack>
</GridCol> </GridCol>

View File

@@ -27,11 +27,7 @@ function Page() {
if (loading || !data) { if (loading || !data) {
return ( return (
<Box py="xl" px={{ base: 'md', md: 100 }}> <Box py="xl" px={{ base: 'md', md: 100 }}>
<SimpleGrid cols={{ base: 1, md: 3 }} spacing="lg"> <Skeleton height={500} radius="lg" />
{Array.from({ length: 6 }).map((_, i) => (
<Skeleton key={i} height={320} radius="lg" />
))}
</SimpleGrid>
</Box> </Box>
) )
} }

View File

@@ -144,9 +144,9 @@ export default function SDGS() {
mt={40} mt={40}
variant="gradient" variant="gradient"
gradient={{ from: "#26667F", to: "#124170" }} gradient={{ from: "#26667F", to: "#124170" }}
style={{ boxShadow: "0 6px 14px rgba(18,65,112,0.25)" }} style={{ boxShadow: "0 6px 14px rgba(18,65,112,0.25)"}}
> >
Jelajahi Semua Tujuan SDGs Desa <Text c="white" fz={{ base: "md", md: "lg" }} fw="bold">Jelajahi Semua Tujuan SDGs Desa</Text>
</Button> </Button>
</Center> </Center>
</Box> </Box>