Fix QC Kak Inno 8 Des

Fix QC Kak Ayu 8 Des
Fix QC Pak Jun 8 Des
This commit is contained in:
2025-12-09 17:27:23 +08:00
parent 9dbe172165
commit ac2fc1a705
44 changed files with 712 additions and 477 deletions

View File

@@ -2,7 +2,7 @@
import artikelKesehatanState from '@/app/admin/(dashboard)/_state/kesehatan/data_kesehatan_warga/artikelKesehatan';
import BackButton from '@/app/darmasaba/(pages)/desa/layanan/_com/BackButto';
import colors from '@/con/colors';
import { Box, Divider, Group, Image, List, ListItem, Paper, Skeleton, Stack, Table, TableTbody, TableTd, TableTh, TableThead, TableTr, Text } from '@mantine/core';
import { Box, Divider, Flex, Group, Image, List, ListItem, Paper, Skeleton, Stack, Table, TableTbody, TableTd, TableTh, TableThead, TableTr, Text } from '@mantine/core';
import { useShallowEffect } from '@mantine/hooks';
import { IconAlertCircle, IconCalendar, IconInfoCircle } from '@tabler/icons-react';
import { useParams } from 'next/navigation';
@@ -44,18 +44,18 @@ function Page() {
<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}
<Image
src={state.findUnique.data.image?.link}
alt={state.findUnique.data.title}
height={0}
style={{
style={{
height: 'auto',
width: '100%',
maxHeight: '500px',
objectFit: 'contain',
borderRadius: '8px'
}}
loading="lazy"
loading="lazy"
/>
</Box>
</Box>
@@ -78,25 +78,33 @@ function Page() {
<Box>
<Text fz="h4" fw="bold">Pendahuluan</Text>
<Divider my="xs" />
<Text fz="md" lh={1.6} ta="justify" dangerouslySetInnerHTML={{ __html: state.findUnique.data.introduction?.content }} />
<Box pl={20}>
<Text fz="md" lh={1.6} ta="justify" dangerouslySetInnerHTML={{ __html: state.findUnique.data.introduction?.content }} />
</Box>
</Box>
<Box>
<Text fz="h4" fw="bold">{state.findUnique.data.symptom?.title}</Text>
<Divider my="xs" />
<Text fz="md" lh={1.6} ta="justify" style={{wordBreak: "break-word", whiteSpace: "normal"}} dangerouslySetInnerHTML={{ __html: state.findUnique.data.symptom?.content }} />
<Box pl={20}>
<Text fz="md" lh={1.6} ta="justify" style={{ wordBreak: "break-word", whiteSpace: "normal" }} dangerouslySetInnerHTML={{ __html: state.findUnique.data.symptom?.content }} />
</Box>
</Box>
<Box>
<Text fz="h4" fw="bold">{state.findUnique.data.prevention?.title}</Text>
<Divider my="xs" />
<Text fz="md" lh={1.6} ta="justify" style={{wordBreak: "break-word", whiteSpace: "normal"}} dangerouslySetInnerHTML={{ __html: state.findUnique.data.prevention?.content }} />
<Box pl={20}>
<Text fz="md" lh={1.6} ta="justify" style={{ wordBreak: "break-word", whiteSpace: "normal" }} dangerouslySetInnerHTML={{ __html: state.findUnique.data.prevention?.content }} />
</Box>
</Box>
<Box>
<Text fz="h4" fw="bold">{state.findUnique.data.firstaid?.title}</Text>
<Divider my="xs" />
<Text fz="md" lh={1.6} ta="justify" style={{wordBreak: "break-word", whiteSpace: "normal"}} dangerouslySetInnerHTML={{ __html: state.findUnique.data.firstaid?.content }} />
<Box pl={20}>
<Text fz="md" lh={1.6} ta="justify" style={{ wordBreak: "break-word", whiteSpace: "normal" }} dangerouslySetInnerHTML={{ __html: state.findUnique.data.firstaid?.content }} />
</Box>
</Box>
<Box>
@@ -114,10 +122,14 @@ function Page() {
{state.findUnique.data?.mythvsfact ? (
<TableTr>
<TableTd>
<Text fz="sm" lh={1.6} style={{wordBreak: "break-word", whiteSpace: "normal"}} dangerouslySetInnerHTML={{ __html: state.findUnique.data.mythvsfact.mitos }} />
<Box pl={20}>
<Text fz="sm" lh={1.6} style={{ wordBreak: "break-word", whiteSpace: "normal" }} dangerouslySetInnerHTML={{ __html: state.findUnique.data.mythvsfact.mitos }} />
</Box>
</TableTd>
<TableTd>
<Text fz="sm" lh={1.6} style={{wordBreak: "break-word", whiteSpace: "normal"}} dangerouslySetInnerHTML={{ __html: state.findUnique.data.mythvsfact.fakta }} />
<Box pl={20}>
<Text fz="sm" lh={1.6} style={{ wordBreak: "break-word", whiteSpace: "normal" }} dangerouslySetInnerHTML={{ __html: state.findUnique.data.mythvsfact.fakta }} />
</Box>
</TableTd>
</TableTr>
) : (
@@ -133,17 +145,15 @@ function Page() {
<Box>
<Text fz="h4" fw="bold">Kapan Harus ke Dokter?</Text>
<Divider my="xs" />
<Group gap="xs" mb="xs">
<Flex justify={'flex-start'} gap={"xs"} align={"center"} mb="xs">
<IconAlertCircle size={18} color="red" />
<Text fz="md">Segera bawa penderita ke fasilitas kesehatan jika mengalami:</Text>
</Group>
<Text fz="md" lh={1.6} dangerouslySetInnerHTML={{ __html: state.findUnique.data.doctorsign.content }} />
</Flex>
<Box pl={20}>
<Text fz="md" lh={1.6} dangerouslySetInnerHTML={{ __html: state.findUnique.data.doctorsign.content }} /></Box>
</Box>
<Box>
<Text fz="h4" fw="bold">Kasus DBD di Wilayah Abiansemal</Text>
<Divider my="xs" />
<Paper p="lg" radius="md" bg={colors['blue-button-trans']} withBorder>
<Group gap="xs" mb="sm">
<IconInfoCircle size={20} color={colors['white-1']} />

View File

@@ -95,7 +95,7 @@ function GrafikPenyakit() {
<Box style={{ width: '100%', minWidth: 300, height: 400, minHeight: 300 }}>
<Paper bg={colors['white-1']} p={'md'}>
<Center>
<Title pb={10} order={3}>Grafik Hasil Kepuasan Masyarakat</Title>
<Title pb={10} order={2}>Penderita Penyakit</Title>
<Text c='dimmed'>Belum ada data untuk ditampilkan dalam grafik</Text>
</Center>
</Paper>
@@ -103,7 +103,7 @@ function GrafikPenyakit() {
) : (
<Box style={{ width: '100%', minWidth: 300, height: 420, minHeight: 300 }}>
<Paper bg={colors["white-trans-1"]} p={'md'}>
<Title pb={10} order={4}>Grafik Hasil Kepuasan Masyarakat</Title>
<Title pb={10} order={2}>Penderita Penyakit</Title>
{mounted && diseaseChartData.length > 0 && (
<Center>
<BarChart width={isMobile ? 450 : isTablet ? 500 : 550} height={350} data={diseaseChartData} >

View File

@@ -69,25 +69,33 @@ function Page() {
<Stack gap="sm">
<Text fz="lg" fw="bold">Deskripsi Kegiatan</Text>
<Divider />
<Text ta="justify" fz="md" style={{ wordBreak: "break-word", whiteSpace: "normal" }} dangerouslySetInnerHTML={{ __html: state.findUnique.data.deskripsijadwalkegiatan.deskripsi }} />
<Box pl={20}>
<Text ta="justify" fz="md" style={{ wordBreak: "break-word", whiteSpace: "normal" }} dangerouslySetInnerHTML={{ __html: state.findUnique.data.deskripsijadwalkegiatan.deskripsi }} />
</Box>
</Stack>
<Stack gap="sm">
<Text fz="lg" fw="bold">Layanan yang Tersedia</Text>
<Divider />
<Text ta="justify" fz="md" style={{ wordBreak: "break-word", whiteSpace: "normal" }} dangerouslySetInnerHTML={{ __html: state.findUnique.data.layananjadwalkegiatan.content }} />
<Box pl={20}>
<Text ta="justify" fz="md" style={{ wordBreak: "break-word", whiteSpace: "normal" }} dangerouslySetInnerHTML={{ __html: state.findUnique.data.layananjadwalkegiatan.content }} />
</Box>
</Stack>
<Stack gap="sm">
<Text fz="lg" fw="bold">Syarat & Ketentuan</Text>
<Divider />
<Text ta="justify" fz="md" style={{ wordBreak: "break-word", whiteSpace: "normal" }} dangerouslySetInnerHTML={{ __html: state.findUnique.data.syaratketentuanjadwalkegiatan.content }} />
<Box pl={20}>
<Text ta="justify" fz="md" style={{ wordBreak: "break-word", whiteSpace: "normal" }} dangerouslySetInnerHTML={{ __html: state.findUnique.data.syaratketentuanjadwalkegiatan.content }} />
</Box>
</Stack>
<Stack gap="sm">
<Text fz="lg" fw="bold">Dokumen yang Perlu Dibawa</Text>
<Divider />
<Text ta="justify" fz="md" style={{ wordBreak: "break-word", whiteSpace: "normal" }} dangerouslySetInnerHTML={{ __html: state.findUnique.data.dokumenjadwalkegiatan.content }} />
<Box pl={20}>
<Text ta="justify" fz="md" style={{ wordBreak: "break-word", whiteSpace: "normal" }} dangerouslySetInnerHTML={{ __html: state.findUnique.data.dokumenjadwalkegiatan.content }} />
</Box>
</Stack>
<Stack gap="sm">

View File

@@ -71,11 +71,13 @@ function DetailInfoWabahPenyakitUser() {
{/* Deskripsi */}
<Box>
<Text fz="lg" fw="bold">Deskripsi</Text>
<Text
fz="md"
dangerouslySetInnerHTML={{ __html: data.deskripsiLengkap || '-' }}
style={{ wordBreak: "break-word", whiteSpace: "normal" }}
/>
<Box pl={20}>
<Text
fz="md"
dangerouslySetInnerHTML={{ __html: data.deskripsiLengkap || '-' }}
style={{ wordBreak: "break-word", whiteSpace: "normal" }}
/>
</Box>
</Box>
</Stack>
</Paper>

View File

@@ -30,7 +30,7 @@ function Page() {
const state = useProxy(infoWabahPenyakit);
const router = useTransitionRouter();
const [search, setSearch] = useState('');
const [debouncedSearch] = useDebouncedValue(search, 500)
const [debouncedSearch] = useDebouncedValue(search, 1000)
const { data, page, totalPages, loading, load } = state.findMany;
useShallowEffect(() => {

View File

@@ -0,0 +1,111 @@
'use client'
import kontakDarurat from '@/app/admin/(dashboard)/_state/kesehatan/kontak-darurat/kontakDarurat';
import colors from '@/con/colors';
import { Box, Button, Group, Image, Paper, Skeleton, Stack, Text } from '@mantine/core';
import { useShallowEffect } from '@mantine/hooks';
import { IconArrowBack, IconBrandWhatsapp } from '@tabler/icons-react';
import { useParams, useRouter } from 'next/navigation';
import { useProxy } from 'valtio/utils';
function Page() {
const state = useProxy(kontakDarurat);
const router = useRouter();
const params = useParams();
useShallowEffect(() => {
state.findUnique.load(params?.id as string);
}, []);
if (!state.findUnique.data) {
return (
<Stack py={10}>
<Skeleton height={500} radius="md" />
</Stack>
);
}
const data = state.findUnique.data;
return (
<Box px={{base: 'md', md: 100}} py={10}>
{/* Tombol Back */}
<Button
variant="subtle"
onClick={() => router.back()}
leftSection={<IconArrowBack size={24} color={colors['blue-button']} />}
mb={15}
>
Kembali
</Button>
{/* Wrapper Detail */}
<Paper
withBorder
w="100%"
bg={colors['white-1']}
p="lg"
radius="md"
shadow="sm"
>
<Stack gap="md">
<Text fz="2xl" fw="bold" c={colors['blue-button']}>
Detail Kontak Darurat
</Text>
<Paper bg="#ECEEF8" p="md" radius="md" shadow="xs">
<Stack gap="sm">
<Box>
<Text fz="lg" fw="bold">Judul</Text>
<Text fz="md" c="dimmed">{data.name || '-'}</Text>
</Box>
<Box>
<Text fz="lg" fw="bold">Whatsapp</Text>
<Text fz="md" c="dimmed">{data.whatsapp || '-'}</Text>
</Box>
<Box>
<Text fz="lg" fw="bold">Deskripsi</Text>
<Text
fz="md"
c="dimmed"
dangerouslySetInnerHTML={{ __html: data.deskripsi || '-' }}
style={{ wordBreak: "break-word", whiteSpace: "normal" }}
/>
</Box>
<Box>
<Text fz="lg" fw="bold">Gambar</Text>
{data.image?.link ? (
<Image
src={data.image.link}
alt="gambar"
radius="md"
maw={300}
loading="lazy"
/>
) : (
<Text fz="md" c="dimmed">-</Text>
)}
</Box>
<Group>
<Button
variant="light"
leftSection={<IconBrandWhatsapp size={18} />}
component="a"
href={`https://wa.me/${data.whatsapp.replace(/\D/g, '')}`}
target="_blank"
aria-label="Hubungi WhatsApp"
>
WhatsApp
</Button>
</Group>
</Stack>
</Paper>
</Stack>
</Paper>
</Box>
);
}
export default Page;

View File

@@ -7,6 +7,7 @@ import {
Center,
Grid,
GridCol,
Group,
Image,
Pagination,
Paper,
@@ -17,17 +18,18 @@ import {
TextInput,
Tooltip
} from '@mantine/core';
import { useShallowEffect } from '@mantine/hooks';
import { IconBrandWhatsapp, IconSearch } from '@tabler/icons-react';
import { useDebouncedValue, useShallowEffect } from '@mantine/hooks';
import { IconSearch } from '@tabler/icons-react';
import { useTransitionRouter } from 'next-view-transitions';
import { useState } from 'react';
import { useProxy } from 'valtio/utils';
import BackButton from '../../desa/layanan/_com/BackButto';
import { useDebouncedValue } from '@mantine/hooks';
function Page() {
const state = useProxy(kontakDarurat);
const router = useTransitionRouter()
const [search, setSearch] = useState('');
const [debouncedSearch] = useDebouncedValue(search, 500)
const [debouncedSearch] = useDebouncedValue(search, 1000)
const { data, page, totalPages, loading, load } = state.findMany;
useShallowEffect(() => {
@@ -88,83 +90,79 @@ function Page() {
) : (
<SimpleGrid cols={{ base: 1, sm: 2, md: 3 }} spacing="xl" mt="lg">
{data.map((v, k) => (
<Paper
key={k}
radius="xl"
shadow="md"
withBorder
p="lg"
bg={colors['white-trans-1']}
style={{
transition: 'all 200ms ease',
cursor: 'pointer',
display: 'flex',
flexDirection: 'column',
justifyContent: 'space-between', // ✅ biar button selalu di bawah
height: '100%', // ✅ bikin tinggi seragam
}}
>
<Stack align="center" gap="sm" style={{ flexGrow: 1 }}>
<Box
style={{
width: '100%',
aspectRatio: '16/9',
borderRadius: '12px',
overflow: 'hidden',
position: 'relative',
}}
>
<Image
src={v.image.link}
alt={v.name}
fit="cover"
loading="lazy"
style={{
width: '100%',
height: '100%',
transition: 'transform 0.4s ease',
}}
onMouseEnter={(e) => (e.currentTarget.style.transform = 'scale(1.05)')}
onMouseLeave={(e) => (e.currentTarget.style.transform = 'scale(1)')}
/>
</Box>
<Text ta="center" fw={700} fz="lg" c={colors['blue-button']}>
{v.name}
</Text>
<Text
fz="sm"
ta="center"
lineClamp={3}
lh={1.6}
style={{
minHeight: '4.8em', // tinggi tetap 3 baris
}}
>
<span
style={{ wordBreak: 'break-word', whiteSpace: 'normal' }}
dangerouslySetInnerHTML={{ __html: v.deskripsi }}
/>
</Text>
</Stack>
{/* ✅ Tombol selalu di bagian bawah card */}
<Center mt="md">
<Button
variant="light"
leftSection={<IconBrandWhatsapp size={18} />}
component="a"
href={`https://wa.me/${v.whatsapp.replace(/\D/g, '')}`}
target="_blank"
aria-label="Hubungi WhatsApp"
>
WhatsApp
</Button>
</Center>
</Paper>
<Paper
key={k}
radius="xl"
shadow="md"
withBorder
p="lg"
bg={colors['white-trans-1']}
style={{
transition: 'all 200ms ease',
cursor: 'pointer',
display: 'flex',
flexDirection: 'column',
justifyContent: 'space-between', // ✅ biar button selalu di bawah
height: '100%', // ✅ bikin tinggi seragam
}}
>
<Stack align="center" gap="sm" style={{ flexGrow: 1 }}>
<Box
style={{
width: '100%',
aspectRatio: '16/9',
borderRadius: '12px',
overflow: 'hidden',
position: 'relative',
}}
>
<Image
src={v.image.link}
alt={v.name}
fit="cover"
loading="lazy"
style={{
width: '100%',
height: '100%',
transition: 'transform 0.4s ease',
}}
onMouseEnter={(e) => (e.currentTarget.style.transform = 'scale(1.05)')}
onMouseLeave={(e) => (e.currentTarget.style.transform = 'scale(1)')}
/>
</Box>
<Text ta="center" fw={700} fz="lg" c={colors['blue-button']}>
{v.name}
</Text>
<Text
fz="sm"
ta="center"
lineClamp={3}
lh={1.6}
style={{
minHeight: '4.8em', // tinggi tetap 3 baris
}}
>
<span
style={{ wordBreak: 'break-word', whiteSpace: 'normal' }}
dangerouslySetInnerHTML={{ __html: v.deskripsi }}
/>
</Text>
</Stack>
{/* ✅ Tombol selalu di bagian bawah card */}
<Group mt="md" justify='center'>
<Button
bg={colors['blue-button']}
onClick={() => router.push(`/darmasaba/kesehatan/kontak-darurat/${v.id}`)}
>
Detail
</Button>
</Group>
</Paper>
))}
</SimpleGrid>
)}

View File

@@ -26,7 +26,7 @@ import BackButton from '../../desa/layanan/_com/BackButto'
function Page() {
const state = useProxy(penangananDarurat)
const [search, setSearch] = useState('')
const [debouncedSearch] = useDebouncedValue(search, 500)
const [debouncedSearch] = useDebouncedValue(search, 1000)
const { data, page, totalPages, loading, load } = state.findMany
useShallowEffect(() => {

View File

@@ -12,7 +12,7 @@ import { useTransitionRouter } from "next-view-transitions";
export default function Page() {
const state = useProxy(posyandustate);
const [search, setSearch] = useState("");
const [debouncedSearch] = useDebouncedValue(search, 500); // 500ms delay
const [debouncedSearch] = useDebouncedValue(search, 1000); // 500ms delay
const router = useTransitionRouter()
const { data, page, totalPages, loading, load } = state.findMany;

View File

@@ -57,7 +57,7 @@ export default function Page() {
const state = useProxy(programKesehatan);
const router = useRouter();
const [search, setSearch] = useState("");
const [debouncedSearch] = useDebouncedValue(search, 500); // 500ms delay
const [debouncedSearch] = useDebouncedValue(search, 1000); // 500ms delay
const { data, page, totalPages, loading, load } = state.findMany;
useShallowEffect(() => {

View File

@@ -7,10 +7,12 @@ import { IconSearch, IconMapPin, IconPhone, IconMail } from '@tabler/icons-react
import { useState } from 'react';
import { useProxy } from 'valtio/utils';
import BackButton from '../../desa/layanan/_com/BackButto';
import { useDebouncedValue } from '@mantine/hooks';
function Page() {
const state = useProxy(puskesmasState)
const [search, setSearch] = useState('')
const [debouncedSearch] = useDebouncedValue(search, 1000);
const {
data,
@@ -21,8 +23,8 @@ function Page() {
} = state.findMany;
useShallowEffect(() => {
load(page, 6, search)
}, [page, search])
load(page, 6, debouncedSearch)
}, [page, debouncedSearch])
if (loading || !data) {
return (
@@ -95,17 +97,17 @@ function Page() {
</Group>
<Stack gap={6}>
<Group gap="xs" align="flex-start" wrap="nowrap">
<Box pt={2}><IconMapPin size={16} /></Box>
<Box pt={2}><IconMapPin size={20} /></Box>
<Text fz="sm" c="dimmed">{v.alamat}</Text>
</Group>
<Group gap="xs" align="flex-start" wrap="nowrap">
<Box pt={2}><IconPhone size={16} /></Box>
<Box pt={2}><IconPhone size={20} /></Box>
<Text fz="sm" c="dimmed">{v.kontak.kontakPuskesmas}</Text>
</Group>
<Group gap="xs" align="flex-start" wrap="nowrap">
<Box pt={2}><IconMail size={16} /></Box>
<Box pt={2}><IconMail size={20} /></Box>
<Text fz="sm" c="dimmed">{v.kontak.email}</Text>
</Group>
</Stack>