Fix QC Kak Inno Tgl 11 Des

Fix QC Kak Ayu Tgl 11 Des
Fix font style {font size, color, line height} menu kesehatan
This commit is contained in:
2025-12-12 17:06:33 +08:00
parent a00481152c
commit f6f77d9e35
28 changed files with 802 additions and 496 deletions

View File

@@ -76,13 +76,13 @@ function Page() {
</Box> </Box>
<Flex pb={30} justify={'center'} gap={'xl'} align={'center'}> <Flex pb={30} justify={'center'} gap={'xl'} align={'center'}>
<Box> <Box>
<Flex gap={{ base: 0, md: 5 }} align={'center'}> <Flex gap={{base: 7, md: 5}} align={'center'}>
<Text fw={'bold'} fz={{ base: 'md', md: 'h4' }}>Laki-Laki</Text> <Text fw={'bold'} fz={{ base: 'md', md: 'h4' }}>Laki-Laki</Text>
<ColorSwatch color="#5082EE" size={30} /> <ColorSwatch color="#5082EE" size={30} />
</Flex> </Flex>
</Box> </Box>
<Box> <Box>
<Flex gap={{ base: 0, md: 5 }} align={'center'}> <Flex gap={{base: 7, md: 5}} align={'center'}>
<Text fw={'bold'} fz={{ base: 'md', md: 'h4' }}>Perempuan</Text> <Text fw={'bold'} fz={{ base: 'md', md: 'h4' }}>Perempuan</Text>
<ColorSwatch color="#6EDF9C" size={30} /> <ColorSwatch color="#6EDF9C" size={30} />
</Flex> </Flex>

View File

@@ -66,7 +66,7 @@ function Page() {
value={search} value={search}
onChange={(e) => setSearch(e.target.value)} onChange={(e) => setSearch(e.target.value)}
leftSection={<IconSearch size={20} />} leftSection={<IconSearch size={20} />}
w={{ base: "50%", md: "100%" }} w={"100%"}
/> />
</GridCol> </GridCol>
</Grid> </Grid>

View File

@@ -53,6 +53,7 @@ function Page() {
Ton: item.value, Ton: item.value,
})); }));
const chartWidth = Math.max(600, chartData.length * 150); // contoh: 150px per bar
return ( return (
<Stack pos={"relative"} bg={colors.Bg} py={"xl"} gap={"22"}> <Stack pos={"relative"} bg={colors.Bg} py={"xl"} gap={"22"}>
@@ -78,7 +79,7 @@ function Page() {
<Box style={{ width: '100%', overflowX: 'auto' }}> <Box style={{ width: '100%', overflowX: 'auto' }}>
<Paper p="xl"> <Paper p="xl">
<Text pb={10} fw="bold" fz="h4">Statistik Sektor Unggulan Darmasaba</Text> <Text pb={10} fw="bold" fz="h4">Statistik Sektor Unggulan Darmasaba</Text>
<Box style={{ width: '100%', minWidth: '600px' }}> <Box style={{ width: '100%', overflowX: 'auto', maxWidth: `${chartWidth}px` }}>
<BarChart <BarChart
p={10} p={10}
h={300} h={300}
@@ -90,11 +91,14 @@ function Page() {
tickLine="y" tickLine="y"
tooltipAnimationDuration={200} tooltipAnimationDuration={200}
withTooltip withTooltip
style={{ withXAxis
fontFamily: 'inherit', withYAxis
}}
xAxisLabel="Sektor" xAxisLabel="Sektor"
yAxisLabel="Ton" yAxisLabel="Ton"
style={{
fontFamily: 'inherit',
fontSize: '12px', // ukuran font lebih kecil di mobile
}}
/> />
</Box> </Box>
</Paper> </Paper>

View File

@@ -365,7 +365,6 @@ function StrukturOrganisasiBumDes() {
<Box <Box
ref={chartContainerRef} ref={chartContainerRef}
style={{ style={{
borderRadius: '12px',
overflowX: 'auto', overflowX: 'auto',
overflowY: 'auto', overflowY: 'auto',
width: '100%', width: '100%',

View File

@@ -1,20 +1,18 @@
'use client' 'use client'
import CreateEditor from '@/app/admin/(dashboard)/_com/createEditor';
import ajukanIdeInovatifState from '@/app/admin/(dashboard)/_state/inovasi/ajukan-ide-inovatif'; import ajukanIdeInovatifState from '@/app/admin/(dashboard)/_state/inovasi/ajukan-ide-inovatif';
import colors from '@/con/colors'; import colors from '@/con/colors';
import { ActionIcon, Box, Button, Flex, List, ListItem, Modal, Paper, SimpleGrid, Stack, Text, TextInput, Title } from '@mantine/core'; import { ActionIcon, Box, Button, Flex, List, ListItem, Modal, Paper, SimpleGrid, Stack, Text, TextInput, Title } from '@mantine/core';
import { useDisclosure } from '@mantine/hooks'; import { useDisclosure } from '@mantine/hooks';
import { IconArrowRight, IconBulbFilled } from '@tabler/icons-react'; import { IconBulbFilled } from '@tabler/icons-react';
import { useProxy } from 'valtio/utils'; import { useProxy } from 'valtio/utils';
import BackButton from '../../desa/layanan/_com/BackButto'; import BackButton from '../../desa/layanan/_com/BackButto';
import CreateEditor from '@/app/admin/(dashboard)/_com/createEditor';
function Page() { function Page() {
const [opened, { open, close }] = useDisclosure(false); const [opened, { open, close }] = useDisclosure(false);
const ideInovatif = useProxy(ajukanIdeInovatifState) const ideInovatif = useProxy(ajukanIdeInovatifState);
const resetForm = () => { const resetForm = () => {
// Reset state di valtio
ideInovatif.create.form = { ideInovatif.create.form = {
name: "", name: "",
deskripsi: "", deskripsi: "",
@@ -23,53 +21,66 @@ function Page() {
masalah: "", masalah: "",
benefit: "", benefit: "",
}; };
// Reset state lokal
}; };
const handleSubmit = async () => { const handleSubmit = async () => {
// Submit data berita
await ideInovatif.create.create(); await ideInovatif.create.create();
// Reset form setelah submit
resetForm(); resetForm();
close(); close();
}; };
return ( return (
<Stack pos={"relative"} bg={colors.Bg} py={"xl"} gap={"22"}> <Stack pos="relative" bg={colors.Bg} py="xl" gap="22">
<Box px={{ base: 'md', md: 100 }}> <Box px={{ base: 'md', md: 100 }}>
<BackButton /> <BackButton />
</Box> </Box>
<Box px={{ base: 'md', md: 100 }}> <Box px={{ base: 'md', md: 100 }}>
<Text ta={"center"} fz={{ base: "h1", md: "2.5rem" }} c={colors["blue-button"]} fw={"bold"}> <Title
Ajukan Ide Inovatif order={1}
</Text> ta="center"
<Text ta={'center'} fz={'h4'}>Desa Darmasaba percaya bahwa setiap warga memiliki potensi luar biasa untuk menciptakan perubahan positif. Platform &quot;Ajukan Ide Inovatif&quot; hadir sebagai ruang inklusif bagi seluruh masyarakat untuk mengembangkan dan mengusulkan gagasan transformatif.</Text> c={colors["blue-button"]}
</Box> fw="bold"
<Box px={{ base: "md", md: 100 }}> style={{ fontSize: 'clamp(1.75rem, 4vw, 2.25rem)' }}
<Stack gap={'lg'} p={'lg'}>
<SimpleGrid
cols={{
base: 1,
md: 2,
}}
> >
<Paper p={'xl'} > Ajukan Ide Inovatif
<Stack gap={"xs"}> </Title>
<Text fz={'h3'} fw={'bold'} c={colors['blue-button']}>Tujuan Ide Inovatif Ini</Text> <Text ta="center" fz={{ base: 'sm', md: 'md' }} c="black" lh="1.6">
Desa Darmasaba percaya bahwa setiap warga memiliki potensi luar biasa untuk menciptakan perubahan positif. Platform &quot;Ajukan Ide Inovatif&quot; hadir sebagai ruang inklusif bagi seluruh masyarakat untuk mengembangkan dan mengusulkan gagasan transformatif.
</Text>
</Box>
<Box px={{ base: 'md', md: 100 }}>
<Stack gap="lg" p="lg">
<SimpleGrid cols={{ base: 1, md: 2 }}>
<Paper p="xl">
<Stack gap="xs">
<Title order={2} c={colors['blue-button']} fw="bold">
Tujuan Ide Inovatif Ini
</Title>
<List> <List>
<ListItem ta={'justify'} fz={{ base: 'h4', md: 'lg' }}>Mendorong partisipasi aktif masyarakat</ListItem> <ListItem ta="justify" fz={{ base: 'sm', md: 'md' }} lh="1.5">
<ListItem ta={'justify'} fz={{ base: 'h4', md: 'lg' }}>Memfasilitasi inovasi berbasis lokal</ListItem> Mendorong partisipasi aktif masyarakat
<ListItem ta={'justify'} fz={{ base: 'h4', md: 'lg' }}>Memecahkan tantangan komunal</ListItem> </ListItem>
<ListItem ta={'justify'} fz={{ base: 'h4', md: 'lg' }}>Mengembangkan potensi kreativitas warga</ListItem> <ListItem ta="justify" fz={{ base: 'sm', md: 'md' }} lh="1.5">
Memfasilitasi inovasi berbasis lokal
</ListItem>
<ListItem ta="justify" fz={{ base: 'sm', md: 'md' }} lh="1.5">
Memecahkan tantangan komunal
</ListItem>
<ListItem ta="justify" fz={{ base: 'sm', md: 'md' }} lh="1.5">
Mengembangkan potensi kreativitas warga
</ListItem>
</List> </List>
</Stack> </Stack>
</Paper> </Paper>
<Paper p={'xl'} >
<Flex align={'center'} justify={'space-between'}> <Paper p="xl">
<Flex align="center" justify="space-between" direction={{ base: 'column', md: 'row' }} gap="md">
<Box> <Box>
<Text fz={'h4'} fw={'bold'} c={colors['blue-button']}>Apabila Anda Ingin Mengajukan Ide Inovatif Bisa Klik Pada Gambar Di Samping</Text> <Title order={3} c={colors['blue-button']} fw="bold" ta={{ base: 'center', md: 'start' }}>
<IconArrowRight size={30} color={colors['blue-button']} /> Apabila Anda Ingin Mengajukan Ide Inovatif Bisa Klik Pada Gambar
</Title>
</Box> </Box>
<Box px={{ base: 5, md: 10 }} py={5}> <Box px={{ base: 5, md: 10 }} py={5}>
<ActionIcon variant="transparent" size={150} onClick={open}> <ActionIcon variant="transparent" size={150} onClick={open}>
@@ -88,32 +99,46 @@ function Page() {
radius={0} radius={0}
transitionProps={{ transition: 'fade', duration: 200 }} transitionProps={{ transition: 'fade', duration: 200 }}
> >
<Paper p={"md"} withBorder> <Paper p="md" withBorder>
<Stack gap={"xs"}> <Stack gap="xs">
<Title order={3}>Ajukan Ide Inovatif</Title> <Title order={3}>Ajukan Ide Inovatif</Title>
<TextInput <TextInput
label={<Text fz={"sm"} fw={"bold"}>Nama</Text>} label={
<Text fz="sm" fw="bold">
Nama
</Text>
}
placeholder="masukkan nama" placeholder="masukkan nama"
onChange={(val) => { onChange={(val) => {
ideInovatif.create.form.name = val.target.value ideInovatif.create.form.name = val.target.value;
}} }}
/> />
<TextInput <TextInput
label={<Text fz={"sm"} fw={"bold"}>Alamat</Text>} label={
<Text fz="sm" fw="bold">
Alamat
</Text>
}
placeholder="masukkan alamat" placeholder="masukkan alamat"
onChange={(val) => { onChange={(val) => {
ideInovatif.create.form.alamat = val.target.value ideInovatif.create.form.alamat = val.target.value;
}} }}
/> />
<TextInput <TextInput
label={<Text fz={"sm"} fw={"bold"}>Nama Ide</Text>} label={
<Text fz="sm" fw="bold">
Nama Ide
</Text>
}
placeholder="masukkan nama ide" placeholder="masukkan nama ide"
onChange={(val) => { onChange={(val) => {
ideInovatif.create.form.namaIde = val.target.value ideInovatif.create.form.namaIde = val.target.value;
}} }}
/> />
<Box> <Box>
<Text fz={"sm"} fw={"bold"}>Deskripsi</Text> <Text fz="sm" fw="bold">
Deskripsi
</Text>
<CreateEditor <CreateEditor
value={ideInovatif.create.form.deskripsi} value={ideInovatif.create.form.deskripsi}
onChange={(htmlContent) => { onChange={(htmlContent) => {
@@ -122,24 +147,33 @@ function Page() {
/> />
</Box> </Box>
<TextInput <TextInput
label={<Text fz={"sm"} fw={"bold"}>Masalah</Text>} label={
<Text fz="sm" fw="bold">
Masalah
</Text>
}
placeholder="masukkan masalah" placeholder="masukkan masalah"
onChange={(val) => { onChange={(val) => {
ideInovatif.create.form.masalah = val.target.value ideInovatif.create.form.masalah = val.target.value;
}} }}
/> />
<TextInput <TextInput
label={<Text fz={"sm"} fw={"bold"}>Benefit</Text>} label={
<Text fz="sm" fw="bold">
Benefit
</Text>
}
placeholder="masukkan benefit" placeholder="masukkan benefit"
onChange={(val) => { onChange={(val) => {
ideInovatif.create.form.benefit = val.target.value ideInovatif.create.form.benefit = val.target.value;
}} }}
/> />
<Button bg={colors['blue-button']} onClick={handleSubmit}>Simpan</Button> <Button bg={colors['blue-button']} onClick={handleSubmit}>
Simpan
</Button>
</Stack> </Stack>
</Paper> </Paper>
</Modal> </Modal>
</Stack> </Stack>
); );
} }

View File

@@ -58,7 +58,7 @@ function Page() {
/> />
</GridCol> </GridCol>
</Grid> </Grid>
<Text fz={'md'}>Menjadikan Desa Darmasaba pusat inovasi digital untuk pemberdayaan masyarakat</Text> <Text pt={20} fz={'md'}>Menjadikan Desa Darmasaba pusat inovasi digital untuk pemberdayaan masyarakat</Text>
<Text fz={'md'}>dan peningkatan ekonomi berbasis teknologi.</Text> <Text fz={'md'}>dan peningkatan ekonomi berbasis teknologi.</Text>
</Box> </Box>
<Box px={{ base: "md", md: 100 }}> <Box px={{ base: "md", md: 100 }}>

View File

@@ -1,17 +1,17 @@
'use client' 'use client'
import colors from '@/con/colors'; import colors from '@/con/colors';
import { Box, Center, Grid, GridCol, Image, Pagination, Paper, SimpleGrid, Skeleton, Stack, Text, TextInput } from '@mantine/core'; import { Box, Center, Grid, GridCol, Image, Pagination, Paper, SimpleGrid, Skeleton, Stack, Text, TextInput, Title } from '@mantine/core';
import BackButton from '../../desa/layanan/_com/BackButto';
import { useProxy } from 'valtio/utils'; import { useProxy } from 'valtio/utils';
import { useDebouncedValue, useShallowEffect } from '@mantine/hooks'; import { useDebouncedValue, useShallowEffect } from '@mantine/hooks';
import { useState } from 'react'; import { useState } from 'react';
import infoTeknoState from '@/app/admin/(dashboard)/_state/inovasi/info-tekno'; import infoTeknoState from '@/app/admin/(dashboard)/_state/inovasi/info-tekno';
import { IconSearch } from '@tabler/icons-react'; import { IconSearch } from '@tabler/icons-react';
import BackButton from '../../desa/layanan/_com/BackButto';
function Page() { function Page() {
const [search, setSearch] = useState("") const [search, setSearch] = useState("")
const [debouncedSearch] = useDebouncedValue(search, 1000); // 500ms delay const [debouncedSearch] = useDebouncedValue(search, 1000);
const state = useProxy(infoTeknoState) const state = useProxy(infoTeknoState)
const { const {
data, data,
@@ -34,17 +34,24 @@ function Page() {
</Stack> </Stack>
) )
} }
return ( return (
<Stack pos={"relative"} bg={colors.Bg} py={"xl"} gap={"22"}> <Stack pos={"relative"} bg={colors.Bg} py={"xl"} gap={"22"}>
<Box px={{ base: 'md', md: 100 }}> <Box px={{ base: 'md', md: 100 }}>
<BackButton /> <BackButton />
</Box> </Box>
<Box px={{ base: 'md', md: 100 }}> <Box px={{ base: 'md', md: 100 }}>
<Grid align='center'> <Grid align='center'>
<GridCol span={{ base: 12, md: 9 }}> <GridCol span={{ base: 12, md: 9 }}>
<Text fz={{ base: "h1", md: "2.5rem" }} c={colors["blue-button"]} fw={"bold"}> <Title
order={1}
c={colors["blue-button"]}
fw={"bold"}
ta={{ base: 'center', md: 'left' }}
>
Info Teknologi Tepat Guna Info Teknologi Tepat Guna
</Text> </Title>
</GridCol> </GridCol>
<GridCol span={{ base: 12, md: 3 }}> <GridCol span={{ base: 12, md: 3 }}>
<TextInput <TextInput
@@ -53,13 +60,19 @@ function Page() {
value={search} value={search}
onChange={(e) => setSearch(e.target.value)} onChange={(e) => setSearch(e.target.value)}
leftSection={<IconSearch size={20} />} leftSection={<IconSearch size={20} />}
w={{ base: "50%", md: "100%" }} w={{ base: "100%", md: "100%" }}
/> />
</GridCol> </GridCol>
</Grid> </Grid>
<Text fz={'md'}>Desa Darmasaba berkomitmen mengembangkan teknologi tepat guna yang sesuai dengan kebutuhan masyarakat,</Text>
<Text fz={'md'}>mendukung pembangunan berkelanjutan, dan meningkatkan kualitas hidup warga.</Text> <Text pt={20} fz={{ base: 'sm', md: 'md' }} ta={{ base: 'center', md: 'left' }} lh={1.5}>
Desa Darmasaba berkomitmen mengembangkan teknologi tepat guna yang sesuai dengan kebutuhan masyarakat,
</Text>
<Text fz={{ base: 'sm', md: 'md' }} ta={{ base: 'center', md: 'left' }} lh={1.5}>
mendukung pembangunan berkelanjutan, dan meningkatkan kualitas hidup warga.
</Text>
</Box> </Box>
<Box px={{ base: "md", md: 100 }}> <Box px={{ base: "md", md: 100 }}>
<Stack gap={'lg'} p={'lg'}> <Stack gap={'lg'} p={'lg'}>
<SimpleGrid <SimpleGrid
@@ -74,12 +87,14 @@ function Page() {
<Paper p={'xl'} key={k}> <Paper p={'xl'} key={k}>
<Stack gap={"xs"}> <Stack gap={"xs"}>
<Image src={v.image.link || ''} pb={10} radius={10} alt='' loading="lazy" /> <Image src={v.image.link || ''} pb={10} radius={10} alt='' loading="lazy" />
<Text fz={'h3'} fw={'bold'}>{v.name}</Text> <Title order={3} fw={'bold'} ta="left">
{v.name}
</Title>
<Box pr={'lg'} pb={10}> <Box pr={'lg'} pb={10}>
<Text <Text
size="md" fz={{ base: 'xs', md: 'sm' }}
ta="justify" ta="justify"
lh={1} // line height biar enak dibaca lh={1.5}
style={{ style={{
wordBreak: "break-word", wordBreak: "break-word",
whiteSpace: "normal", whiteSpace: "normal",
@@ -94,10 +109,11 @@ function Page() {
</SimpleGrid> </SimpleGrid>
</Stack> </Stack>
</Box> </Box>
<Center> <Center>
<Pagination <Pagination
value={page} value={page}
onChange={(newPage) => load(newPage)} // ini penting! onChange={(newPage) => load(newPage)}
total={totalPages} total={totalPages}
my="md" my="md"
/> />

View File

@@ -56,7 +56,7 @@ function Page() {
value={search} value={search}
onChange={(e) => setSearch(e.target.value)} onChange={(e) => setSearch(e.target.value)}
leftSection={<IconSearch size={20} />} leftSection={<IconSearch size={20} />}
w={{ base: '50%', md: '100%' }} w={'100%'}
/> />
</GridCol> </GridCol>
</Grid> </Grid>

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, Flex, 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, Title } 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';
@@ -37,9 +37,9 @@ function Page() {
<Stack gap="lg"> <Stack gap="lg">
<Paper radius="xl" shadow="md" withBorder> <Paper radius="xl" shadow="md" withBorder>
<Box style={{ borderTopLeftRadius: 16, borderTopRightRadius: 16 }} bg={colors['blue-button']}> <Box style={{ borderTopLeftRadius: 16, borderTopRightRadius: 16 }} bg={colors['blue-button']}>
<Text p="md" fz={{ base: 'h3', md: 'h2' }} c={colors['white-1']} fw="bold"> <Title order={1} p="md" c={colors['white-1']} fw="bold">
{state.findUnique.data.title || 'Detail Artikel Kesehatan'} {state.findUnique.data.title || 'Detail Artikel Kesehatan'}
</Text> </Title>
</Box> </Box>
<Box p="lg"> <Box p="lg">
@@ -64,7 +64,7 @@ function Page() {
<Stack gap="lg"> <Stack gap="lg">
<Group gap="xs"> <Group gap="xs">
<IconCalendar size={18} color={colors['blue-button']} /> <IconCalendar size={18} color={colors['blue-button']} />
<Text c="dimmed" fz="sm"> <Text fz={{ base: 'xs', md: 'sm' }} lh={1.5}>
{new Date(state.findUnique.data.createdAt).toLocaleDateString('id-ID', { {new Date(state.findUnique.data.createdAt).toLocaleDateString('id-ID', {
year: 'numeric', year: 'numeric',
month: 'long', month: 'long',
@@ -74,48 +74,47 @@ function Page() {
</Group> </Group>
<Stack gap="lg"> <Stack gap="lg">
<Box> <Box>
<Text fz="h4" fw="bold">Pendahuluan</Text> <Title order={2} fw="bold">Pendahuluan</Title>
<Divider my="xs" /> <Divider my="xs" />
<Box pl={20}> <Box pl={20}>
<Text fz="md" lh={1.6} ta="justify" dangerouslySetInnerHTML={{ __html: state.findUnique.data.introduction?.content }} /> <Text fz={{ base: 'sm', md: 'md' }} lh={1.6} ta="justify" dangerouslySetInnerHTML={{ __html: state.findUnique.data.introduction?.content }} />
</Box> </Box>
</Box> </Box>
<Box> <Box>
<Text fz="h4" fw="bold">{state.findUnique.data.symptom?.title}</Text> <Title order={2} fw="bold">{state.findUnique.data.symptom?.title}</Title>
<Divider my="xs" /> <Divider my="xs" />
<Box pl={20}> <Box pl={20}>
<Text fz="md" lh={1.6} ta="justify" style={{ wordBreak: "break-word", whiteSpace: "normal" }} dangerouslySetInnerHTML={{ __html: state.findUnique.data.symptom?.content }} /> <Text fz={{ base: 'sm', md: 'md' }} lh={1.6} ta="justify" style={{ wordBreak: "break-word", whiteSpace: "normal" }} dangerouslySetInnerHTML={{ __html: state.findUnique.data.symptom?.content }} />
</Box> </Box>
</Box> </Box>
<Box> <Box>
<Text fz="h4" fw="bold">{state.findUnique.data.prevention?.title}</Text> <Title order={2} fw="bold">{state.findUnique.data.prevention?.title}</Title>
<Divider my="xs" /> <Divider my="xs" />
<Box pl={20}> <Box pl={20}>
<Text fz="md" lh={1.6} ta="justify" style={{ wordBreak: "break-word", whiteSpace: "normal" }} dangerouslySetInnerHTML={{ __html: state.findUnique.data.prevention?.content }} /> <Text fz={{ base: 'sm', md: 'md' }} lh={1.6} ta="justify" style={{ wordBreak: "break-word", whiteSpace: "normal" }} dangerouslySetInnerHTML={{ __html: state.findUnique.data.prevention?.content }} />
</Box> </Box>
</Box> </Box>
<Box> <Box>
<Text fz="h4" fw="bold">{state.findUnique.data.firstaid?.title}</Text> <Title order={2} fw="bold">{state.findUnique.data.firstaid?.title}</Title>
<Divider my="xs" /> <Divider my="xs" />
<Box pl={20}> <Box pl={20}>
<Text fz="md" lh={1.6} ta="justify" style={{ wordBreak: "break-word", whiteSpace: "normal" }} dangerouslySetInnerHTML={{ __html: state.findUnique.data.firstaid?.content }} /> <Text fz={{ base: 'sm', md: 'md' }} lh={1.6} ta="justify" style={{ wordBreak: "break-word", whiteSpace: "normal" }} dangerouslySetInnerHTML={{ __html: state.findUnique.data.firstaid?.content }} />
</Box> </Box>
</Box> </Box>
<Box> <Box>
<Text fz="h4" fw="bold">{state.findUnique.data.mythvsfact?.title}</Text> <Title order={2} fw="bold">{state.findUnique.data.mythvsfact?.title}</Title>
<Divider my="xs" /> <Divider my="xs" />
<Box pb="md"> <Box pb="md">
<Table highlightOnHover withTableBorder withColumnBorders striped> <Table highlightOnHover withTableBorder withColumnBorders striped>
<TableThead> <TableThead>
<TableTr> <TableTr>
<TableTh fz="sm" fw="bold">Mitos</TableTh> <TableTh fz={{ base: 'xs', md: 'sm' }} fw="bold">Mitos</TableTh>
<TableTh fz="sm" fw="bold">Fakta</TableTh> <TableTh fz={{ base: 'xs', md: 'sm' }} fw="bold">Fakta</TableTh>
</TableTr> </TableTr>
</TableThead> </TableThead>
<TableTbody> <TableTbody>
@@ -123,12 +122,12 @@ function Page() {
<TableTr> <TableTr>
<TableTd> <TableTd>
<Box pl={20}> <Box pl={20}>
<Text fz="sm" lh={1.6} style={{ wordBreak: "break-word", whiteSpace: "normal" }} dangerouslySetInnerHTML={{ __html: state.findUnique.data.mythvsfact.mitos }} /> <Text fz={{ base: 'xs', md: 'sm' }} lh={1.6} style={{ wordBreak: "break-word", whiteSpace: "normal" }} dangerouslySetInnerHTML={{ __html: state.findUnique.data.mythvsfact.mitos }} />
</Box> </Box>
</TableTd> </TableTd>
<TableTd> <TableTd>
<Box pl={20}> <Box pl={20}>
<Text fz="sm" lh={1.6} style={{ wordBreak: "break-word", whiteSpace: "normal" }} dangerouslySetInnerHTML={{ __html: state.findUnique.data.mythvsfact.fakta }} /> <Text fz={{ base: 'xs', md: 'sm' }} lh={1.6} style={{ wordBreak: "break-word", whiteSpace: "normal" }} dangerouslySetInnerHTML={{ __html: state.findUnique.data.mythvsfact.fakta }} />
</Box> </Box>
</TableTd> </TableTd>
</TableTr> </TableTr>
@@ -143,34 +142,35 @@ function Page() {
</Box> </Box>
<Box> <Box>
<Text fz="h4" fw="bold">Kapan Harus ke Dokter?</Text> <Title order={2} fw="bold">Kapan Harus ke Dokter?</Title>
<Divider my="xs" /> <Divider my="xs" />
<Flex justify={'flex-start'} gap={"xs"} align={"center"} mb="xs"> <Flex justify={'flex-start'} gap={"xs"} align={"center"} mb="xs">
<IconAlertCircle size={18} color="red" /> <IconAlertCircle size={18} color="red" />
<Text fz="md">Segera bawa penderita ke fasilitas kesehatan jika mengalami:</Text> <Text fz={{ base: 'sm', md: 'md' }} lh={1.5}>Segera bawa penderita ke fasilitas kesehatan jika mengalami:</Text>
</Flex> </Flex>
<Box pl={20}> <Box pl={20}>
<Text fz="md" lh={1.6} dangerouslySetInnerHTML={{ __html: state.findUnique.data.doctorsign.content }} /></Box> <Text fz={{ base: 'sm', md: 'md' }} lh={1.6} dangerouslySetInnerHTML={{ __html: state.findUnique.data.doctorsign.content }} />
</Box>
</Box> </Box>
<Box> <Box>
<Paper p="lg" radius="md" bg={colors['blue-button-trans']} withBorder> <Paper p="lg" radius="md" bg={colors['blue-button-trans']} withBorder>
<Group gap="xs" mb="sm"> <Group gap="xs" mb="sm">
<IconInfoCircle size={20} color={colors['white-1']} /> <IconInfoCircle size={20} color={colors['white-1']} />
<Text fz="h4" c={colors['white-1']} fw="bold">Informasi Lebih Lanjut</Text> <Title order={3} c={colors['white-1']} fw="bold">Informasi Lebih Lanjut</Title>
</Group> </Group>
<Stack gap={4}> <Stack gap={4}>
<Text fz="sm" c={colors['white-1']}>Hotline DBD: <b>(0361) 123456</b></Text> <Text fz={{ base: 'xs', md: 'sm' }} c={colors['white-1']}>Hotline DBD: <b>(0361) 123456</b></Text>
<Text fz="sm" c={colors['white-1']}>WhatsApp Center: <b>081234567890</b></Text> <Text fz={{ base: 'xs', md: 'sm' }} c={colors['white-1']}>WhatsApp Center: <b>081234567890</b></Text>
<Text fz="sm" c={colors['white-1']}>Email: <b>p2p@dinkes.badungkab.go.id</b></Text> <Text fz={{ base: 'xs', md: 'sm' }} c={colors['white-1']}>Email: <b>p2p@dinkes.badungkab.go.id</b></Text>
</Stack> </Stack>
</Paper> </Paper>
</Box> </Box>
<Box> <Box>
<Text fz="h4" fw="bold">Referensi</Text> <Title order={2} fw="bold">Referensi</Title>
<Divider my="xs" /> <Divider my="xs" />
<List spacing="xs" size="sm" type="ordered"> <List spacing="xs" fz={{ base: 'xs', md: 'sm' }} type="ordered">
<ListItem>Kementerian Kesehatan RI. (2024). Pedoman Pencegahan dan Pengendalian DBD.</ListItem> <ListItem>Kementerian Kesehatan RI. (2024). Pedoman Pencegahan dan Pengendalian DBD.</ListItem>
<ListItem>World Health Organization. (2024). Dengue Guidelines for Diagnosis, Treatment, Prevention and Control.</ListItem> <ListItem>World Health Organization. (2024). Dengue Guidelines for Diagnosis, Treatment, Prevention and Control.</ListItem>
<ListItem>Dinas Kesehatan Kabupaten Badung. (2025). Laporan Surveilans DBD Triwulan I 2025.</ListItem> <ListItem>Dinas Kesehatan Kabupaten Badung. (2025). Laporan Surveilans DBD Triwulan I 2025.</ListItem>

View File

@@ -1,7 +1,7 @@
'use client' 'use client'
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 colors from '@/con/colors'; import colors from '@/con/colors';
import { Box, Button, Card, Divider, Group, Image, Paper, Skeleton, Stack, Text } from '@mantine/core'; import { Box, Button, Card, Divider, Group, Image, Paper, Skeleton, Stack, Text, Title } from '@mantine/core';
import { useShallowEffect } from '@mantine/hooks'; import { useShallowEffect } from '@mantine/hooks';
import { IconCalendar, IconChevronRight } from '@tabler/icons-react'; import { IconCalendar, IconChevronRight } from '@tabler/icons-react';
import { useRouter } from 'next/navigation'; import { useRouter } from 'next/navigation';
@@ -27,13 +27,13 @@ function ArtikelKesehatanPage() {
<Box> <Box>
<Paper p="xl" bg={colors['white-trans-1']} radius="xl" shadow="md"> <Paper p="xl" bg={colors['white-trans-1']} radius="xl" shadow="md">
<Stack gap="lg"> <Stack gap="lg">
<Text ta="center" fw={700} fz="32px" c={colors['blue-button']}> <Title ta="center" order={1} c={colors['blue-button']}>
Artikel Kesehatan Artikel Kesehatan
</Text> </Title>
<Divider size="sm" color={colors['blue-button']} /> <Divider size="sm" color={colors['blue-button']} />
{state.findMany.data.length === 0 ? ( {state.findMany.data.length === 0 ? (
<Box py="xl" ta="center"> <Box py="xl" ta="center">
<Text fz="lg" c="dimmed"> <Text fz={{ base: 'sm', sm: 'md' }} c="dimmed">
Belum ada artikel kesehatan yang tersedia Belum ada artikel kesehatan yang tersedia
</Text> </Text>
</Box> </Box>
@@ -50,17 +50,26 @@ function ArtikelKesehatanPage() {
onMouseLeave={(e) => (e.currentTarget.style.transform = 'translateY(0)')} onMouseLeave={(e) => (e.currentTarget.style.transform = 'translateY(0)')}
> >
<Card.Section> <Card.Section>
<Image style={{ borderTopLeftRadius: '10px', borderTopRightRadius: '10px' }} src={item.image?.link} alt={item.title} height={200} fit="cover" loading="lazy" /> <Image
style={{ borderTopLeftRadius: '10px', borderTopRightRadius: '10px' }}
src={item.image?.link}
alt={item.title}
height={200}
fit="cover"
loading="lazy"
/>
</Card.Section> </Card.Section>
<Stack gap="xs" mt="md"> <Stack gap="xs" mt="md">
<Text fw="bold" fz="xl" c={colors['blue-button']}>{item.title}</Text> <Title order={3} c={colors['blue-button']}>
{item.title}
</Title>
<Group gap="xs"> <Group gap="xs">
<IconCalendar size={16} color='gray' /> <IconCalendar size={16} color='gray' />
<Text fz="sm" c="dimmed"> <Text fz={{ base: 'xs', sm: 'sm' }} c="dimmed">
{new Date(item.createdAt).toLocaleDateString('id-ID', { year: 'numeric', month: 'long', day: 'numeric' })} Dinas Kesehatan {new Date(item.createdAt).toLocaleDateString('id-ID', { year: 'numeric', month: 'long', day: 'numeric' })} Dinas Kesehatan
</Text> </Text>
</Group> </Group>
<Text fz="md" lineClamp={3}> <Text fz={{ base: 'sm', sm: 'md' }} lh={{ base: 'sm', sm: 'md' }} lineClamp={3}>
{item.content} {item.content}
</Text> </Text>
<Group justify="flex-start"> <Group justify="flex-start">

View File

@@ -16,7 +16,6 @@ interface Kontak {
email: string; email: string;
} }
interface Lokasi { interface Lokasi {
mapsEmbed: string; mapsEmbed: string;
} }
@@ -35,7 +34,7 @@ function Page() {
state.findUnique.load(params?.id as string); state.findUnique.load(params?.id as string);
}, []); }, []);
const data = state.findUnique.data as any; // Temporary any to fix type issues const data = state.findUnique.data as any;
const nama = data?.name || 'Fasilitas Kesehatan'; const nama = data?.name || 'Fasilitas Kesehatan';
const prosedur = data?.prosedurpendaftaran.content || ''; const prosedur = data?.prosedurpendaftaran.content || '';
@@ -111,11 +110,11 @@ function Page() {
<Group gap="md" wrap="wrap"> <Group gap="md" wrap="wrap">
<Group gap="xs"> <Group gap="xs">
<ThemeIcon variant="light" radius="xl"><IconMapPin size={18} /></ThemeIcon> <ThemeIcon variant="light" radius="xl"><IconMapPin size={18} /></ThemeIcon>
<Text>{alamat}</Text> <Text fz={{ base: 'sm', md: 'md' }} lh={1.5}>{alamat}</Text>
</Group> </Group>
<Group gap="xs"> <Group gap="xs">
<ThemeIcon variant="light" radius="xl"><IconDeviceLandlinePhone size={18} /></ThemeIcon> <ThemeIcon variant="light" radius="xl"><IconDeviceLandlinePhone size={18} /></ThemeIcon>
<Text>{kontak.telepon}</Text> <Text fz={{ base: 'sm', md: 'md' }} lh={1.5}>{kontak.telepon}</Text>
<CopyButton value={kontak.telepon}> <CopyButton value={kontak.telepon}>
{({ copied, copy }) => ( {({ copied, copy }) => (
<Tooltip label={copied ? 'Disalin' : 'Salin nomor'}> <Tooltip label={copied ? 'Disalin' : 'Salin nomor'}>
@@ -126,7 +125,7 @@ function Page() {
</Group> </Group>
<Group gap="xs"> <Group gap="xs">
<ThemeIcon variant="light" radius="xl"><IconBrandWhatsapp size={18} /></ThemeIcon> <ThemeIcon variant="light" radius="xl"><IconBrandWhatsapp size={18} /></ThemeIcon>
<Text>{kontak.whatsapp}</Text> <Text fz={{ base: 'sm', md: 'md' }} lh={1.5}>{kontak.whatsapp}</Text>
<CopyButton value={kontak.whatsapp}> <CopyButton value={kontak.whatsapp}>
{({ copied, copy }) => ( {({ copied, copy }) => (
<Tooltip label={copied ? 'Disalin' : 'Salin WhatsApp'}> <Tooltip label={copied ? 'Disalin' : 'Salin WhatsApp'}>
@@ -137,7 +136,7 @@ function Page() {
</Group> </Group>
<Group gap="xs"> <Group gap="xs">
<ThemeIcon variant="light" radius="xl"><IconMail size={18} /></ThemeIcon> <ThemeIcon variant="light" radius="xl"><IconMail size={18} /></ThemeIcon>
<Text>{kontak.email}</Text> <Text fz={{ base: 'sm', md: 'md' }} lh={1.5}>{kontak.email}</Text>
<CopyButton value={kontak.email}> <CopyButton value={kontak.email}>
{({ copied, copy }) => ( {({ copied, copy }) => (
<Tooltip label={copied ? 'Disalin' : 'Salin email'}> <Tooltip label={copied ? 'Disalin' : 'Salin email'}>
@@ -163,33 +162,43 @@ function Page() {
<Divider /> <Divider />
<Group gap="xl" align="start"> <Group gap="xl" align="start">
<Stack gap={2}> <Stack gap={2}>
<Text c="dimmed" fz="sm">Nama Fasilitas</Text> <Text c="dimmed" fz={{ base: 'xs', md: 'sm' }}>Nama Fasilitas</Text>
<Text fw={600}>{nama}</Text> <Text fz={{ base: 'sm', md: 'md' }} fw={600} lh={1.5}>{nama}</Text>
</Stack> </Stack>
<Stack gap={2}> <Stack gap={2}>
<Text c="dimmed" fz="sm">Jam Operasional</Text> <Text c="dimmed" fz={{ base: 'xs', md: 'sm' }}>Jam Operasional</Text>
<Text fw={600}>{jam}</Text> <Text fz={{ base: 'sm', md: 'md' }} fw={600} lh={1.5}>{jam}</Text>
</Stack> </Stack>
</Group> </Group>
<Divider /> <Divider />
<Title order={4}>Layanan Unggulan</Title> <Title order={4}>Layanan Unggulan</Title>
<Divider /> <Divider />
{layananUnggulan ? ( {layananUnggulan ? (
<Box pl={"lg"}> <Box pl="lg">
<Text fz="md" style={{ lineHeight: 1.7, wordBreak: "break-word", whiteSpace: "normal" }} dangerouslySetInnerHTML={{ __html: layananUnggulan }} /> <Text
fz={{ base: 'sm', md: 'md' }}
lh={{ base: 1.6, md: 1.7 }}
style={{ wordBreak: 'break-word', whiteSpace: 'normal' }}
dangerouslySetInnerHTML={{ __html: layananUnggulan }}
/>
</Box> </Box>
) : ( ) : (
<Paper withBorder radius="md" p="md"> <Paper withBorder radius="md" p="md">
<Group gap="sm"> <Group gap="sm">
<IconMoodEmpty /> <IconMoodEmpty />
<Text>Belum ada informasi fasilitas pendukung.</Text> <Text fz={{ base: 'sm', md: 'md' }} c="dimmed">Belum ada informasi layanan unggulan.</Text>
</Group> </Group>
</Paper> </Paper>
)} )}
<Divider /> <Divider />
<Title order={4}>Peta Lokasi</Title> <Title order={4}>Peta Lokasi</Title>
<AspectRatio ratio={16 / 9}> <AspectRatio ratio={16 / 9}>
<iframe src={lokasi.mapsEmbed} style={{ border: 0, width: '100%', height: '100%', borderRadius: 16 }} loading="lazy" aria-label="Peta Lokasi" /> <iframe
src={lokasi.mapsEmbed}
style={{ border: 0, width: '100%', height: '100%', borderRadius: 16 }}
loading="lazy"
aria-label="Peta Lokasi"
/>
</AspectRatio> </AspectRatio>
</Stack> </Stack>
</Card> </Card>
@@ -201,9 +210,15 @@ function Page() {
<Stack gap="md"> <Stack gap="md">
<Title order={4}>Kontak Cepat</Title> <Title order={4}>Kontak Cepat</Title>
<Group gap="sm" wrap="wrap"> <Group gap="sm" wrap="wrap">
<Button variant="light" leftSection={<IconDeviceLandlinePhone size={18} />} component="a" href={`tel:${kontak.telepon}`} aria-label="Hubungi Telepon">Telepon</Button> <Button variant="light" leftSection={<IconDeviceLandlinePhone size={18} />} component="a" href={`tel:${kontak.telepon}`} aria-label="Hubungi Telepon">
<Button variant="light" leftSection={<IconBrandWhatsapp size={18} />} component="a" href={`https://wa.me/${kontak.whatsapp.replace(/\D/g, '')}`} target="_blank" aria-label="Hubungi WhatsApp">WhatsApp</Button> <Text fz={{ base: 'xs', md: 'sm' }}>Telepon</Text>
<Button variant="light" leftSection={<IconMail size={18} />} component="a" href={`mailto:${kontak.email}`} aria-label="Kirim Email">Email</Button> </Button>
<Button variant="light" leftSection={<IconBrandWhatsapp size={18} />} component="a" href={`https://wa.me/${kontak.whatsapp.replace(/\D/g, '')}`} target="_blank" aria-label="Hubungi WhatsApp">
<Text fz={{ base: 'xs', md: 'sm' }}>WhatsApp</Text>
</Button>
<Button variant="light" leftSection={<IconMail size={18} />} component="a" href={`mailto:${kontak.email}`} aria-label="Kirim Email">
<Text fz={{ base: 'xs', md: 'sm' }}>Email</Text>
</Button>
</Group> </Group>
</Stack> </Stack>
</Card> </Card>
@@ -214,9 +229,15 @@ function Page() {
<Table highlightOnHover withTableBorder withColumnBorders aria-label="Tabel Dokter"> <Table highlightOnHover withTableBorder withColumnBorders aria-label="Tabel Dokter">
<TableThead> <TableThead>
<TableTr> <TableTr>
<TableTh>Nama</TableTh> <TableTh>
<TableTh>Spesialisasi</TableTh> <Text fz={{ base: 'xs', md: 'sm' }} fw={600}>Nama</Text>
<TableTh>Jadwal</TableTh> </TableTh>
<TableTh>
<Text fz={{ base: 'xs', md: 'sm' }} fw={600}>Spesialisasi</Text>
</TableTh>
<TableTh>
<Text fz={{ base: 'xs', md: 'sm' }} fw={600}>Jadwal</Text>
</TableTh>
</TableTr> </TableTr>
</TableThead> </TableThead>
<TableTbody> <TableTbody>
@@ -226,11 +247,15 @@ function Page() {
<TableTd> <TableTd>
<Group gap="xs"> <Group gap="xs">
<IconUser size={16} /> <IconUser size={16} />
<Text>{dokter.name || '-'}</Text> <Text fz={{ base: 'sm', md: 'md' }}>{dokter.name || '-'}</Text>
</Group> </Group>
</TableTd> </TableTd>
<TableTd>{dokter.specialist || '-'}</TableTd> <TableTd>
<TableTd>{dokter.jadwal || '-'}</TableTd> <Text fz={{ base: 'sm', md: 'md' }}>{dokter.specialist || '-'}</Text>
</TableTd>
<TableTd>
<Text fz={{ base: 'sm', md: 'md' }}>{dokter.jadwal || '-'}</Text>
</TableTd>
</TableTr> </TableTr>
)) ))
) : ( ) : (
@@ -238,7 +263,7 @@ function Page() {
<TableTd colSpan={3}> <TableTd colSpan={3}>
<Group justify="center" gap="xs" c="dimmed"> <Group justify="center" gap="xs" c="dimmed">
<IconSearch size={18} /> <IconSearch size={18} />
<Text>Tidak ada data tenaga medis.</Text> <Text fz={{ base: 'sm', md: 'md' }}>Tidak ada data tenaga medis.</Text>
</Group> </Group>
</TableTd> </TableTd>
</TableTr> </TableTr>
@@ -254,13 +279,18 @@ function Page() {
<Divider /> <Divider />
{fasilitasPendukungHtml ? ( {fasilitasPendukungHtml ? (
<Box pl="lg"> <Box pl="lg">
<Text fz="md" style={{ wordBreak: "break-word", whiteSpace: "normal", lineHeight: 1.7 }} dangerouslySetInnerHTML={{ __html: fasilitasPendukungHtml }} /> <Text
fz={{ base: 'sm', md: 'md' }}
lh={{ base: 1.6, md: 1.7 }}
style={{ wordBreak: 'break-word', whiteSpace: 'normal' }}
dangerouslySetInnerHTML={{ __html: fasilitasPendukungHtml }}
/>
</Box> </Box>
) : ( ) : (
<Paper withBorder radius="md" p="md"> <Paper withBorder radius="md" p="md">
<Group gap="sm"> <Group gap="sm">
<IconMoodEmpty /> <IconMoodEmpty />
<Text>Belum ada informasi fasilitas pendukung.</Text> <Text fz={{ base: 'sm', md: 'md' }} c="dimmed">Belum ada informasi fasilitas pendukung.</Text>
</Group> </Group>
</Paper> </Paper>
)} )}
@@ -274,16 +304,24 @@ function Page() {
<Table highlightOnHover withTableBorder withColumnBorders aria-label="Tabel Layanan dan Tarif"> <Table highlightOnHover withTableBorder withColumnBorders aria-label="Tabel Layanan dan Tarif">
<TableThead> <TableThead>
<TableTr> <TableTr>
<TableTh>Layanan</TableTh> <TableTh>
<TableTh>Tarif</TableTh> <Text fz={{ base: 'xs', md: 'sm' }} fw={600}>Layanan</Text>
</TableTh>
<TableTh>
<Text fz={{ base: 'xs', md: 'sm' }} fw={600}>Tarif</Text>
</TableTh>
</TableTr> </TableTr>
</TableThead> </TableThead>
<TableTbody> <TableTbody>
{Array.isArray(data?.tarifdanlayanan) && data.tarifdanlayanan.length > 0 ? ( {Array.isArray(data?.tarifdanlayanan) && data.tarifdanlayanan.length > 0 ? (
data.tarifdanlayanan.map((item: any) => ( data.tarifdanlayanan.map((item: any) => (
<TableTr key={item.id}> <TableTr key={item.id}>
<TableTd>{item.layanan || '-'}</TableTd> <TableTd>
<TableTd>{formatRupiah(item.tarif)}</TableTd> <Text fz={{ base: 'sm', md: 'md' }}>{item.layanan || '-'}</Text>
</TableTd>
<TableTd>
<Text fz={{ base: 'sm', md: 'md' }}>{formatRupiah(item.tarif)}</Text>
</TableTd>
</TableTr> </TableTr>
)) ))
) : ( ) : (
@@ -291,7 +329,7 @@ function Page() {
<TableTd colSpan={2}> <TableTd colSpan={2}>
<Group justify="center" gap="xs" c="dimmed"> <Group justify="center" gap="xs" c="dimmed">
<IconSearch size={18} /> <IconSearch size={18} />
<Text>Tidak ada data tarif.</Text> <Text fz={{ base: 'sm', md: 'md' }}>Tidak ada data tarif.</Text>
</Group> </Group>
</TableTd> </TableTd>
</TableTr> </TableTr>
@@ -301,7 +339,7 @@ function Page() {
{gratisBpjs && ( {gratisBpjs && (
<Group gap="xs"> <Group gap="xs">
<ThemeIcon variant="light" radius="xl"><IconCheck size={18} /></ThemeIcon> <ThemeIcon variant="light" radius="xl"><IconCheck size={18} /></ThemeIcon>
<Text fw={600}>Gratis dengan BPJS Kesehatan</Text> <Text fz={{ base: 'sm', md: 'md' }} fw={600}>Gratis dengan BPJS Kesehatan</Text>
</Group> </Group>
)} )}
</Stack> </Stack>
@@ -317,9 +355,16 @@ function Page() {
<Title order={3}>Prosedur Pendaftaran</Title> <Title order={3}>Prosedur Pendaftaran</Title>
<Divider /> <Divider />
{prosedur ? ( {prosedur ? (
<Box pl="lg"><Text fz="md" style={{ wordBreak: "break-word", whiteSpace: "normal", lineHeight: 1.7 }} dangerouslySetInnerHTML={{ __html: prosedur }} /></Box> <Box pl="lg">
<Text
fz={{ base: 'sm', md: 'md' }}
lh={{ base: 1.6, md: 1.7 }}
style={{ wordBreak: 'break-word', whiteSpace: 'normal' }}
dangerouslySetInnerHTML={{ __html: prosedur }}
/>
</Box>
) : ( ) : (
<Text fz="md" c="dimmed">Belum ada prosedur pendaftaran</Text> <Text fz={{ base: 'sm', md: 'md' }} c="dimmed">Belum ada prosedur pendaftaran</Text>
)} )}
</Stack> </Stack>
</Paper> </Paper>

View File

@@ -40,7 +40,11 @@ function FasilitasKesehatanPage() {
<Stack gap="lg"> <Stack gap="lg">
{state.findMany.data.length === 0 ? ( {state.findMany.data.length === 0 ? (
<Box py="xl" ta="center"> <Box py="xl" ta="center">
<Text size="lg" c="dimmed" lh="1.5"> <Text
fz={{ base: 'sm', sm: 'md' }}
c={colors['blue-button']}
lh={{ base: '1.5', sm: '1.6' }}
>
Belum ada fasilitas kesehatan yang tersedia Belum ada fasilitas kesehatan yang tersedia
</Text> </Text>
</Box> </Box>
@@ -67,20 +71,36 @@ function FasilitasKesehatanPage() {
> >
<Stack gap="sm"> <Stack gap="sm">
<Group justify="space-between" align="center"> <Group justify="space-between" align="center">
<Title order={3} fw={700} c={colors['blue-button']} lh="1.3" /> <Title
order={3}
fw={700}
c={colors['blue-button']}
fz={{ base: 'sm', sm: 'md' }}
lh={{ base: '1.3', sm: '1.3' }}
>
{item.name}
</Title>
<Badge color="blue" radius="sm" variant="light" size="xs"> <Badge color="blue" radius="sm" variant="light" size="xs">
Aktif Aktif
</Badge> </Badge>
</Group> </Group>
<Group gap="xs"> <Group gap="xs">
<IconMapPin size={18} stroke={1.5} /> <IconMapPin size={18} stroke={1.5} />
<Text size="sm" lh="1.5"> <Text
fz={{ base: 'xs', sm: 'sm' }}
lh={{ base: '1.5', sm: '1.5' }}
c="text"
>
{item.informasiumum.alamat} {item.informasiumum.alamat}
</Text> </Text>
</Group> </Group>
<Group gap="xs"> <Group gap="xs">
<IconClock size={18} stroke={1.5} /> <IconClock size={18} stroke={1.5} />
<Text size="sm" lh="1.5"> <Text
fz={{ base: 'xs', sm: 'sm' }}
lh={{ base: '1.5', sm: '1.5' }}
c="text"
>
{item.informasiumum.jamOperasional} {item.informasiumum.jamOperasional}
</Text> </Text>
</Group> </Group>

View File

@@ -11,7 +11,8 @@ import {
Paper, Paper,
Skeleton, Skeleton,
Stack, Stack,
Text Text,
Title
} from '@mantine/core'; } from '@mantine/core';
import { useDisclosure, useShallowEffect } from '@mantine/hooks'; import { useDisclosure, useShallowEffect } from '@mantine/hooks';
import { IconMail, IconPhone, IconUser } from '@tabler/icons-react'; import { IconMail, IconPhone, IconUser } from '@tabler/icons-react';
@@ -51,55 +52,97 @@ function Page() {
style={{ borderTopLeftRadius: 16, borderTopRightRadius: 16 }} style={{ borderTopLeftRadius: 16, borderTopRightRadius: 16 }}
bg={colors['blue-button']} bg={colors['blue-button']}
> >
<Text p="md" fz={{ base: "h3", md: "h2" }} c={colors['white-1']} fw="bold"> <Title
p="md"
order={1}
c={colors['white-1']}
fw="bold"
ta={{ base: 'center', md: 'left' }}
>
Detail & Pendaftaran Kegiatan Detail & Pendaftaran Kegiatan
</Text> </Title>
</Box> </Box>
<Box p="lg"> <Box p="lg">
<Stack gap="xl"> <Stack gap="xl">
<Stack gap="sm"> <Stack gap="sm">
<Text fz="lg" fw="bold">Informasi Kegiatan</Text> <Title order={2} fw="bold">Informasi Kegiatan</Title>
<Divider /> <Divider />
<Text fz="md" fw="bold">Nama Kegiatan: <Text span>{state.findUnique.data.informasijadwalkegiatan.name}</Text></Text> <Text fw="bold">
<Text fz="md" fw="bold">Tanggal: <Text span>{state.findUnique.data.informasijadwalkegiatan.tanggal}</Text></Text> Nama Kegiatan:&nbsp;
<Text fz="md" fw="bold">Waktu: <Text span>{state.findUnique.data.informasijadwalkegiatan.waktu}</Text></Text> <Text span fw="normal">
<Text fz="md" fw="bold">Lokasi: <Text span>{state.findUnique.data.informasijadwalkegiatan.lokasi}</Text></Text> {state.findUnique.data.informasijadwalkegiatan.name}
</Text>
</Text>
<Text fw="bold">
Tanggal:&nbsp;
<Text span fw="normal">
{state.findUnique.data.informasijadwalkegiatan.tanggal}
</Text>
</Text>
<Text fw="bold">
Waktu:&nbsp;
<Text span fw="normal">
{state.findUnique.data.informasijadwalkegiatan.waktu}
</Text>
</Text>
<Text fw="bold">
Lokasi:&nbsp;
<Text span fw="normal">
{state.findUnique.data.informasijadwalkegiatan.lokasi}
</Text>
</Text>
</Stack> </Stack>
<Stack gap="sm"> <Stack gap="sm">
<Text fz="lg" fw="bold">Deskripsi Kegiatan</Text> <Title order={2} fw="bold">Deskripsi Kegiatan</Title>
<Divider /> <Divider />
<Box pl={20}> <Box pl={20}>
<Text ta="justify" fz="md" style={{ wordBreak: "break-word", whiteSpace: "normal" }} dangerouslySetInnerHTML={{ __html: state.findUnique.data.deskripsijadwalkegiatan.deskripsi }} /> <Text
ta="justify"
style={{ wordBreak: "break-word", whiteSpace: "normal" }}
dangerouslySetInnerHTML={{ __html: state.findUnique.data.deskripsijadwalkegiatan.deskripsi }}
/>
</Box> </Box>
</Stack> </Stack>
<Stack gap="sm"> <Stack gap="sm">
<Text fz="lg" fw="bold">Layanan yang Tersedia</Text> <Title order={2} fw="bold">Layanan yang Tersedia</Title>
<Divider /> <Divider />
<Box pl={20}> <Box pl={20}>
<Text ta="justify" fz="md" style={{ wordBreak: "break-word", whiteSpace: "normal" }} dangerouslySetInnerHTML={{ __html: state.findUnique.data.layananjadwalkegiatan.content }} /> <Text
ta="justify"
style={{ wordBreak: "break-word", whiteSpace: "normal" }}
dangerouslySetInnerHTML={{ __html: state.findUnique.data.layananjadwalkegiatan.content }}
/>
</Box> </Box>
</Stack> </Stack>
<Stack gap="sm"> <Stack gap="sm">
<Text fz="lg" fw="bold">Syarat & Ketentuan</Text> <Title order={2} fw="bold">Syarat & Ketentuan</Title>
<Divider /> <Divider />
<Box pl={20}> <Box pl={20}>
<Text ta="justify" fz="md" style={{ wordBreak: "break-word", whiteSpace: "normal" }} dangerouslySetInnerHTML={{ __html: state.findUnique.data.syaratketentuanjadwalkegiatan.content }} /> <Text
ta="justify"
style={{ wordBreak: "break-word", whiteSpace: "normal" }}
dangerouslySetInnerHTML={{ __html: state.findUnique.data.syaratketentuanjadwalkegiatan.content }}
/>
</Box> </Box>
</Stack> </Stack>
<Stack gap="sm"> <Stack gap="sm">
<Text fz="lg" fw="bold">Dokumen yang Perlu Dibawa</Text> <Title order={2} fw="bold">Dokumen yang Perlu Dibawa</Title>
<Divider /> <Divider />
<Box pl={20}> <Box pl={20}>
<Text ta="justify" fz="md" style={{ wordBreak: "break-word", whiteSpace: "normal" }} dangerouslySetInnerHTML={{ __html: state.findUnique.data.dokumenjadwalkegiatan.content }} /> <Text
ta="justify"
style={{ wordBreak: "break-word", whiteSpace: "normal" }}
dangerouslySetInnerHTML={{ __html: state.findUnique.data.dokumenjadwalkegiatan.content }}
/>
</Box> </Box>
</Stack> </Stack>
<Stack gap="sm"> <Stack gap="sm">
<Text fz="lg" fw="bold">Pendaftaran Kegiatan</Text> <Title order={2} fw="bold">Pendaftaran Kegiatan</Title>
<Divider /> <Divider />
<Group> <Group>
<Button onClick={open}>Buat Pendaftaran</Button> <Button onClick={open}>Buat Pendaftaran</Button>
@@ -112,18 +155,21 @@ function Page() {
<Paper p="lg" radius="md" bg={colors['blue-button-trans']} shadow="sm"> <Paper p="lg" radius="md" bg={colors['blue-button-trans']} shadow="sm">
<Stack gap="xs"> <Stack gap="xs">
<Text fz="lg" c={colors['white-1']} fw="bold">Informasi Kontak</Text> <Title order={3} c={colors['white-1']} fw="bold">Informasi Kontak</Title>
<Group gap="xs"> <Group gap="xs" justify="flex-start">
<IconUser size={18} color="white" /> <IconUser size={18} color="white" />
<Text fz="md" c={colors['white-1']}>Penanggung Jawab: <Text span fw="bold">Bidan Komang Ayu</Text></Text> <Text c={colors['white-1']}>
Penanggung Jawab:&nbsp;
<Text span fw="bold">Bidan Komang Ayu</Text>
</Text>
</Group> </Group>
<Group gap="xs"> <Group gap="xs">
<IconPhone size={18} color="white" /> <IconPhone size={18} color="white" />
<Text fz="md" c={colors['white-1']}>081234567890</Text> <Text c={colors['white-1']}>081234567890</Text>
</Group> </Group>
<Group gap="xs"> <Group gap="xs">
<IconMail size={18} color="white" /> <IconMail size={18} color="white" />
<Text fz="md" c={colors['white-1']}>puskesmasabiansemal3@gmail.com</Text> <Text c={colors['white-1']}>puskesmasabiansemal3@gmail.com</Text>
</Group> </Group>
</Stack> </Stack>
</Paper> </Paper>

View File

@@ -2,14 +2,13 @@
'use client' 'use client'
import pendaftaranJadwalKegiatanState from '@/app/admin/(dashboard)/_state/kesehatan/data_kesehatan_warga/pendafataranJadwalKegiatan'; import pendaftaranJadwalKegiatanState from '@/app/admin/(dashboard)/_state/kesehatan/data_kesehatan_warga/pendafataranJadwalKegiatan';
import colors from '@/con/colors'; import colors from '@/con/colors';
import { Button, Divider, Stack, Text, Textarea, TextInput } from '@mantine/core'; import { Button, Divider, Stack, Text, Textarea, TextInput, Title } from '@mantine/core';
import { useEffect } from 'react'; import { useEffect } from 'react';
import { useProxy } from 'valtio/utils'; import { useProxy } from 'valtio/utils';
function CreatePendaftaran() { function CreatePendaftaran() {
const stateCreate = useProxy(pendaftaranJadwalKegiatanState); const stateCreate = useProxy(pendaftaranJadwalKegiatanState);
useEffect(() => { useEffect(() => {
stateCreate.findMany.load(); stateCreate.findMany.load();
}, []); }, []);
@@ -32,7 +31,7 @@ useEffect(() => {
return ( return (
<Stack gap="sm"> <Stack gap="sm">
<Text fz="lg" fw="bold">Formulir Pendaftaran</Text> <Title order={2} ta="left">Formulir Pendaftaran</Title>
<Divider /> <Divider />
<Stack gap="md"> <Stack gap="md">
<TextInput <TextInput
@@ -41,6 +40,10 @@ useEffect(() => {
size="md" size="md"
value={stateCreate.create.form.name} value={stateCreate.create.form.name}
onChange={(e) => stateCreate.create.form.name = e.target.value} onChange={(e) => stateCreate.create.form.name = e.target.value}
styles={{
label: { fontSize: '14px', lineHeight: 1.4, fontWeight: 500 },
input: { fontSize: '16px', lineHeight: 1.5 },
}}
/> />
<TextInput <TextInput
type='date' type='date'
@@ -50,6 +53,10 @@ useEffect(() => {
w={{ base: '100%', md: '85%', lg: '75%', xl: '50%' }} w={{ base: '100%', md: '85%', lg: '75%', xl: '50%' }}
value={stateCreate.create.form.tanggal} value={stateCreate.create.form.tanggal}
onChange={(e) => stateCreate.create.form.tanggal = e.target.value} onChange={(e) => stateCreate.create.form.tanggal = e.target.value}
styles={{
label: { fontSize: '14px', lineHeight: 1.4, fontWeight: 500 },
input: { fontSize: '16px', lineHeight: 1.5 },
}}
/> />
<TextInput <TextInput
label="Nama Orang Tua / Wali" label="Nama Orang Tua / Wali"
@@ -57,6 +64,10 @@ useEffect(() => {
size="md" size="md"
value={stateCreate.create.form.namaOrangtua} value={stateCreate.create.form.namaOrangtua}
onChange={(e) => stateCreate.create.form.namaOrangtua = e.target.value} onChange={(e) => stateCreate.create.form.namaOrangtua = e.target.value}
styles={{
label: { fontSize: '14px', lineHeight: 1.4, fontWeight: 500 },
input: { fontSize: '16px', lineHeight: 1.5 },
}}
/> />
<TextInput <TextInput
label="Nomor Telepon" label="Nomor Telepon"
@@ -64,6 +75,10 @@ useEffect(() => {
size="md" size="md"
value={stateCreate.create.form.nomor} value={stateCreate.create.form.nomor}
onChange={(e) => stateCreate.create.form.nomor = e.target.value} onChange={(e) => stateCreate.create.form.nomor = e.target.value}
styles={{
label: { fontSize: '14px', lineHeight: 1.4, fontWeight: 500 },
input: { fontSize: '16px', lineHeight: 1.5 },
}}
/> />
<TextInput <TextInput
label="Alamat" label="Alamat"
@@ -71,6 +86,10 @@ useEffect(() => {
size="md" size="md"
value={stateCreate.create.form.alamat} value={stateCreate.create.form.alamat}
onChange={(e) => stateCreate.create.form.alamat = e.target.value} onChange={(e) => stateCreate.create.form.alamat = e.target.value}
styles={{
label: { fontSize: '14px', lineHeight: 1.4, fontWeight: 500 },
input: { fontSize: '16px', lineHeight: 1.5 },
}}
/> />
<Textarea <Textarea
label="Catatan Khusus (Opsional)" label="Catatan Khusus (Opsional)"
@@ -78,9 +97,15 @@ useEffect(() => {
size="md" size="md"
value={stateCreate.create.form.catatan} value={stateCreate.create.form.catatan}
onChange={(e) => stateCreate.create.form.catatan = e.target.value} onChange={(e) => stateCreate.create.form.catatan = e.target.value}
styles={{
label: { fontSize: '14px', lineHeight: 1.4, fontWeight: 500 },
input: { fontSize: '16px', lineHeight: 1.5 },
}}
/> />
<Button size="md" radius="lg" bg={colors['blue-button']} onClick={handleSubmit}> <Button size="md" radius="lg" bg={colors['blue-button']} onClick={handleSubmit}>
<Text fz={{ base: 'sm', md: 'md' }} fw={600} c="white">
Daftar Sekarang Daftar Sekarang
</Text>
</Button> </Button>
</Stack> </Stack>
</Stack> </Stack>

View File

@@ -1,7 +1,7 @@
'use client' 'use client'
import jadwalkegiatanState from '@/app/admin/(dashboard)/_state/kesehatan/data_kesehatan_warga/jadwalKegiatan'; import jadwalkegiatanState from '@/app/admin/(dashboard)/_state/kesehatan/data_kesehatan_warga/jadwalKegiatan';
import colors from '@/con/colors'; import colors from '@/con/colors';
import { Box, Button, Card, Divider, Group, Paper, Skeleton, Stack, Text } from '@mantine/core'; import { Box, Button, Card, Divider, Group, Paper, Skeleton, Stack, Text, Title } from '@mantine/core';
import { useShallowEffect } from '@mantine/hooks'; import { useShallowEffect } from '@mantine/hooks';
import { IconChevronRight, IconClockHour4, IconMapPin } from '@tabler/icons-react'; import { IconChevronRight, IconClockHour4, IconMapPin } from '@tabler/icons-react';
import { useRouter } from 'next/navigation'; import { useRouter } from 'next/navigation';
@@ -27,13 +27,13 @@ function JadwalKegiatanPage() {
<Box> <Box>
<Paper bg={colors['white-trans-1']} p="xl" radius="xl" shadow="md" h="auto" mih="100vh"> <Paper bg={colors['white-trans-1']} p="xl" radius="xl" shadow="md" h="auto" mih="100vh">
<Stack gap="lg"> <Stack gap="lg">
<Text ta="center" fw={700} fz="32px" c={colors['blue-button']}> <Title ta="center" order={1} c={colors['blue-button']} fw={700}>
Jadwal Kegiatan Warga Jadwal Kegiatan Warga
</Text> </Title>
<Divider size="sm" color={colors['blue-button']} /> <Divider size="sm" color={colors['blue-button']} />
{state.findMany.data.length === 0 ? ( {state.findMany.data.length === 0 ? (
<Box py="xl" ta="center"> <Box py="xl" ta="center">
<Text fz="lg" c="dimmed"> <Text fz={{ base: 'sm', sm: 'md' }} c="dimmed">
Belum ada jadwal kegiatan yang tersedia Belum ada jadwal kegiatan yang tersedia
</Text> </Text>
</Box> </Box>
@@ -48,11 +48,11 @@ function JadwalKegiatanPage() {
style={{ backdropFilter: 'blur(8px)' }} style={{ backdropFilter: 'blur(8px)' }}
> >
<Stack gap="sm"> <Stack gap="sm">
<Group justify="space-between"> <Group justify="space-between" wrap="nowrap">
<Text fw={700} fz="xl" c={colors['blue-button']}> <Title order={2} c={colors['blue-button']} fw={700} fz={{ base: 'md', sm: 'xl' }}>
{item.informasijadwalkegiatan.name} {item.informasijadwalkegiatan.name}
</Text> </Title>
<Text fw={600} fz="sm" c={colors['blue-button']}> <Text fw={600} fz={{ base: 'xs', sm: 'sm' }} c={colors['blue-button']} lh="1.4">
{new Date(item.informasijadwalkegiatan.tanggal).toLocaleDateString('id-ID', { {new Date(item.informasijadwalkegiatan.tanggal).toLocaleDateString('id-ID', {
day: '2-digit', day: '2-digit',
month: 'long', month: 'long',
@@ -63,12 +63,16 @@ function JadwalKegiatanPage() {
<Group gap="xs"> <Group gap="xs">
<IconClockHour4 size={18} /> <IconClockHour4 size={18} />
<Text fz="sm">{item.informasijadwalkegiatan.waktu}</Text> <Text fz={{ base: 'xs', sm: 'sm' }} lh="1.5">
{item.informasijadwalkegiatan.waktu}
</Text>
</Group> </Group>
<Group gap="xs"> <Group gap="xs">
<IconMapPin size={18} /> <IconMapPin size={18} />
<Text fz="sm">{item.informasijadwalkegiatan.lokasi}</Text> <Text fz={{ base: 'xs', sm: 'sm' }} lh="1.5">
{item.informasijadwalkegiatan.lokasi}
</Text>
</Group> </Group>
<Divider my="sm" /> <Divider my="sm" />

View File

@@ -74,22 +74,22 @@ function DetailInfoWabahPenyakitUser() {
)} )}
{/* Deskripsi */} {/* Deskripsi */}
<Box> <Stack gap={"xs"}>
{/* Section Title — H2 */} {/* Section Title — H2 */}
<Title order={2} fw="bold" fz={{ base: 'md', md: 'lg' }} lh="1.4"> <Title order={3} fw="bold" ta="left">
Deskripsi Deskripsi
</Title> </Title>
<Box pl={20}> <Box pl={20}>
<Text <Text
fz={{ base: 'sm', md: 'md' }} fz={{ base: 'sm', md: 'md' }}
lh="1.6" lh={{ base: '1.5', md: '1.6' }}
c="dimmed" c="dark"
ta={"justify"} ta="justify"
dangerouslySetInnerHTML={{ __html: data.deskripsiLengkap || '-' }} dangerouslySetInnerHTML={{ __html: data.deskripsiLengkap || '-' }}
style={{ wordBreak: "break-word", whiteSpace: "normal" }} style={{ wordBreak: "break-word", whiteSpace: "normal" }}
/> />
</Box> </Box>
</Box> </Stack>
</Stack> </Stack>
</Paper> </Paper>
</Box> </Box>

View File

@@ -17,7 +17,8 @@ import {
Skeleton, Skeleton,
Stack, Stack,
Text, Text,
TextInput TextInput,
Title
} from '@mantine/core'; } from '@mantine/core';
import { useDebouncedValue, useShallowEffect } from '@mantine/hooks'; import { useDebouncedValue, useShallowEffect } from '@mantine/hooks';
import { IconInfoCircle, IconSearch } from '@tabler/icons-react'; import { IconInfoCircle, IconSearch } from '@tabler/icons-react';
@@ -30,7 +31,7 @@ function Page() {
const state = useProxy(infoWabahPenyakit); const state = useProxy(infoWabahPenyakit);
const router = useTransitionRouter(); const router = useTransitionRouter();
const [search, setSearch] = useState(''); const [search, setSearch] = useState('');
const [debouncedSearch] = useDebouncedValue(search, 1000) const [debouncedSearch] = useDebouncedValue(search, 1000);
const { data, page, totalPages, loading, load } = state.findMany; const { data, page, totalPages, loading, load } = state.findMany;
useShallowEffect(() => { useShallowEffect(() => {
@@ -53,15 +54,19 @@ function Page() {
<Grid align="center" px={{ base: 'md', md: 100 }}> <Grid align="center" px={{ base: 'md', md: 100 }}>
<GridCol span={{ base: 12, md: 8 }}> <GridCol span={{ base: 12, md: 8 }}>
<Text <Title
fz={{ base: '1.8rem', md: '2.8rem' }} order={1}
c={colors['blue-button']} c={colors['blue-button']}
fw="bold" fw="bold"
lh={1.2} lh={{ base: 1.2, md: 1.2 }}
> >
Informasi Wabah & Penyakit Informasi Wabah & Penyakit
</Text> </Title>
<Text fz="md" mt={4}> <Text
fz={{ base: 'sm', md: 'md' }}
lh={{ base: 1.5, md: 1.5 }}
mt={4}
>
Dapatkan informasi terbaru mengenai wabah dan penyakit yang sedang Dapatkan informasi terbaru mengenai wabah dan penyakit yang sedang
diawasi. diawasi.
</Text> </Text>
@@ -84,9 +89,9 @@ function Page() {
<Center py="6xl"> <Center py="6xl">
<Stack align="center" gap="sm"> <Stack align="center" gap="sm">
<IconInfoCircle size={50} color={colors['blue-button']} /> <IconInfoCircle size={50} color={colors['blue-button']} />
<Text fz="lg" fw={500} > <Title order={2} fz={{ base: 'md', md: 'lg' }} fw={500}>
Tidak ada data yang cocok dengan pencarian Anda. Tidak ada data yang cocok dengan pencarian Anda.
</Text> </Title>
</Stack> </Stack>
</Center> </Center>
) : ( ) : (
@@ -131,15 +136,24 @@ function Page() {
{/* Judul dan badge */} {/* Judul dan badge */}
<Group justify="space-between" mt="sm"> <Group justify="space-between" mt="sm">
<Text fw={700} fz="lg" c={colors['blue-button']}> <Title
order={3}
c={colors['blue-button']}
fw={700}
fz={{ base: 'sm', md: 'lg' }}
>
{v.name} {v.name}
</Text> </Title>
<Badge color="blue" variant="light" radius="sm"> <Badge color="blue" variant="light" radius="sm">
Wabah Wabah
</Badge> </Badge>
</Group> </Group>
<Text fz="sm" c="dimmed"> <Text
fz={{ base: 'xs', md: 'sm' }}
c="dimmed"
lh={{ base: 1.4, md: 1.4 }}
>
Diposting:{' '} Diposting:{' '}
{new Date(v.createdAt).toLocaleDateString('id-ID', { {new Date(v.createdAt).toLocaleDateString('id-ID', {
day: '2-digit', day: '2-digit',
@@ -153,8 +167,8 @@ function Page() {
{/* Bagian deskripsi dan tombol */} {/* Bagian deskripsi dan tombol */}
<Box style={{ display: 'flex', flexDirection: 'column', flexGrow: 1 }}> <Box style={{ display: 'flex', flexDirection: 'column', flexGrow: 1 }}>
<Text <Text
fz="sm" fz={{ base: 'xs', md: 'sm' }}
lh={1.5} lh={{ base: 1.5, md: 1.5 }}
lineClamp={3} lineClamp={3}
dangerouslySetInnerHTML={{ __html: v.deskripsiSingkat }} dangerouslySetInnerHTML={{ __html: v.deskripsiSingkat }}
style={{ flexGrow: 1 }} style={{ flexGrow: 1 }}
@@ -174,14 +188,11 @@ function Page() {
</Box> </Box>
</Stack> </Stack>
</Paper> </Paper>
))} ))}
</SimpleGrid> </SimpleGrid>
)} )}
</Box> </Box>
<Center> <Center>
<Pagination <Pagination
value={page} value={page}
@@ -192,7 +203,6 @@ function Page() {
mt="lg" mt="lg"
/> />
</Center> </Center>
</Stack> </Stack>
); );
} }

View File

@@ -1,7 +1,7 @@
'use client' 'use client'
import kontakDarurat from '@/app/admin/(dashboard)/_state/kesehatan/kontak-darurat/kontakDarurat'; import kontakDarurat from '@/app/admin/(dashboard)/_state/kesehatan/kontak-darurat/kontakDarurat';
import colors from '@/con/colors'; import colors from '@/con/colors';
import { Box, Button, Group, Image, Paper, Skeleton, Stack, Text } from '@mantine/core'; import { Box, Button, Group, Image, Paper, Skeleton, Stack, Text, Title } from '@mantine/core';
import { useShallowEffect } from '@mantine/hooks'; import { useShallowEffect } from '@mantine/hooks';
import { IconArrowBack, IconBrandWhatsapp } from '@tabler/icons-react'; import { IconArrowBack, IconBrandWhatsapp } from '@tabler/icons-react';
import { useParams, useRouter } from 'next/navigation'; import { useParams, useRouter } from 'next/navigation';
@@ -34,8 +34,9 @@ function Page() {
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}
style={{ lineHeight: 1.2 }}
> >
Kembali <Text fz={{ base: 'sm', md: 'md' }} fw={500}>Kembali</Text>
</Button> </Button>
{/* Wrapper Detail */} {/* Wrapper Detail */}
@@ -48,34 +49,38 @@ function Page() {
shadow="sm" shadow="sm"
> >
<Stack gap="md"> <Stack gap="md">
<Text fz="2xl" fw="bold" c={colors['blue-button']}> <Title order={1} c={colors['blue-button']}>
Detail Kontak Darurat Detail Kontak Darurat
</Text> </Title>
<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">Judul</Text> <Title order={3}>Judul</Title>
<Text fz="md" c="dimmed">{data.name || '-'}</Text> <Text fz={{ base: 'sm', md: 'md' }} c={data.name ? 'black' : 'dimmed'}>
{data.name || '-'}
</Text>
</Box> </Box>
<Box> <Box>
<Text fz="lg" fw="bold">Whatsapp</Text> <Title order={3}>Whatsapp</Title>
<Text fz="md" c="dimmed">{data.whatsapp || '-'}</Text> <Text fz={{ base: 'sm', md: 'md' }} c={data.whatsapp ? 'black' : 'dimmed'}>
{data.whatsapp || '-'}
</Text>
</Box> </Box>
<Box> <Box>
<Text fz="lg" fw="bold">Deskripsi</Text> <Title order={3}>Deskripsi</Title>
<Text <Text
fz="md" fz={{ base: 'sm', md: 'md' }}
c="dimmed" c={data.deskripsi ? 'black' : 'dimmed'}
dangerouslySetInnerHTML={{ __html: data.deskripsi || '-' }} dangerouslySetInnerHTML={{ __html: data.deskripsi || '-' }}
style={{ wordBreak: "break-word", whiteSpace: "normal" }} style={{ wordBreak: 'break-word', whiteSpace: 'normal', lineHeight: 1.5 }}
/> />
</Box> </Box>
<Box> <Box>
<Text fz="lg" fw="bold">Gambar</Text> <Title order={3}>Gambar</Title>
{data.image?.link ? ( {data.image?.link ? (
<Image <Image
src={data.image.link} src={data.image.link}
@@ -85,9 +90,10 @@ function Page() {
loading="lazy" loading="lazy"
/> />
) : ( ) : (
<Text fz="md" c="dimmed">-</Text> <Text fz={{ base: 'sm', md: 'md' }} c="dimmed">-</Text>
)} )}
</Box> </Box>
<Group> <Group>
<Button <Button
variant="light" variant="light"
@@ -96,6 +102,7 @@ function Page() {
href={`https://wa.me/${data.whatsapp.replace(/\D/g, '')}`} href={`https://wa.me/${data.whatsapp.replace(/\D/g, '')}`}
target="_blank" target="_blank"
aria-label="Hubungi WhatsApp" aria-label="Hubungi WhatsApp"
fz={{ base: 'sm', md: 'md' }}
> >
WhatsApp WhatsApp
</Button> </Button>

View File

@@ -16,6 +16,7 @@ import {
Stack, Stack,
Text, Text,
TextInput, TextInput,
Title,
Tooltip Tooltip
} from '@mantine/core'; } from '@mantine/core';
import { useDebouncedValue, useShallowEffect } from '@mantine/hooks'; import { useDebouncedValue, useShallowEffect } from '@mantine/hooks';
@@ -52,10 +53,21 @@ function Page() {
<Grid align="center" px={{ base: 'md', md: 100 }} gutter="lg"> <Grid align="center" px={{ base: 'md', md: 100 }} gutter="lg">
<GridCol span={{ base: 12, md: 8 }}> <GridCol span={{ base: 12, md: 8 }}>
<Text fz={{ base: '2rem', md: '2.8rem' }} c={colors['blue-button']} fw={800}> <Title
order={1}
c={colors['blue-button']}
fw={800}
fz={{ base: '28px', md: '32px' }}
lh={{ base: 1.2, md: 1.25 }}
>
Kontak Darurat Kontak Darurat
</Text> </Title>
<Text fz="md" mt={4}> <Text
fz={{ base: 'sm', md: 'md' }}
lh={{ base: 1.5, md: 1.6 }}
mt={4}
c="dark.9"
>
Hubungi layanan penting dengan cepat dan mudah Hubungi layanan penting dengan cepat dan mudah
</Text> </Text>
</GridCol> </GridCol>
@@ -79,10 +91,20 @@ function Page() {
<Center mih={300}> <Center mih={300}>
<Stack align="center" gap="xs"> <Stack align="center" gap="xs">
<IconSearch size={50} color={colors['blue-button']} /> <IconSearch size={50} color={colors['blue-button']} />
<Text fz="lg" fw={600} c={colors['blue-button']}> <Title
order={2}
fw={600}
c={colors['blue-button']}
fz={{ base: '20px', md: '24px' }}
lh={{ base: 1.3, md: 1.35 }}
>
Tidak ada kontak ditemukan Tidak ada kontak ditemukan
</Text> </Title>
<Text fz="sm" c="dimmed"> <Text
fz={{ base: 'xs', md: 'sm' }}
lh={{ base: 1.4, md: 1.5 }}
c="dark.7"
>
Coba kata kunci lain untuk pencarian Coba kata kunci lain untuk pencarian
</Text> </Text>
</Stack> </Stack>
@@ -102,8 +124,8 @@ function Page() {
cursor: 'pointer', cursor: 'pointer',
display: 'flex', display: 'flex',
flexDirection: 'column', flexDirection: 'column',
justifyContent: 'space-between', // ✅ biar button selalu di bawah justifyContent: 'space-between',
height: '100%', // ✅ bikin tinggi seragam height: '100%',
}} }}
> >
<Stack align="center" gap="sm" style={{ flexGrow: 1 }}> <Stack align="center" gap="sm" style={{ flexGrow: 1 }}>
@@ -131,27 +153,24 @@ function Page() {
/> />
</Box> </Box>
<Text ta="center" fw={700} fz="lg" c={colors['blue-button']}> <Text ta="center" fw={700} fz={{ base: '18px', md: '20px' }} lh={1.3} c={colors['blue-button']}>
{v.name} {v.name}
</Text> </Text>
<Text <Text
fz="sm" fz={{ base: 'xs', md: 'sm' }}
ta="center" ta="center"
lineClamp={3} lineClamp={3}
lh={1.6} lh={{ base: 1.5, md: 1.6 }}
style={{ style={{
minHeight: '4.8em', // tinggi tetap 3 baris minHeight: '4.8em',
wordBreak: 'break-word',
whiteSpace: 'normal',
}} }}
>
<span
style={{ wordBreak: 'break-word', whiteSpace: 'normal' }}
dangerouslySetInnerHTML={{ __html: v.deskripsi }} dangerouslySetInnerHTML={{ __html: v.deskripsi }}
/> />
</Text>
</Stack> </Stack>
{/* ✅ Tombol selalu di bagian bawah card */}
<Group mt="md" justify='center'> <Group mt="md" justify='center'>
<Button <Button
bg={colors['blue-button']} bg={colors['blue-button']}
@@ -161,8 +180,6 @@ function Page() {
</Button> </Button>
</Group> </Group>
</Paper> </Paper>
))} ))}
</SimpleGrid> </SimpleGrid>
)} )}

View File

@@ -1,7 +1,7 @@
'use client'; 'use client';
import penangananDarurat from '@/app/admin/(dashboard)/_state/kesehatan/penanganan-darurat/penangananDarurat'; import penangananDarurat from '@/app/admin/(dashboard)/_state/kesehatan/penanganan-darurat/penangananDarurat';
import colors from '@/con/colors'; import colors from '@/con/colors';
import { Box, Image, Paper, Skeleton, Stack, Text } from '@mantine/core'; import { Box, Center, Image, Paper, Skeleton, Stack, Text, Title } from '@mantine/core';
import { useShallowEffect } from '@mantine/hooks'; import { useShallowEffect } from '@mantine/hooks';
import { useParams } from 'next/navigation'; import { useParams } from 'next/navigation';
import { useProxy } from 'valtio/utils'; import { useProxy } from 'valtio/utils';
@@ -35,20 +35,26 @@ function DetailPenangananDaruratUser() {
</Box> </Box>
{/* Wrapper Detail */} {/* Wrapper Detail */}
<Box pt={20} px={{ base: 'md', md: 100 }}>
<Paper <Paper
withBorder withBorder
w={{ base: '100%', md: '70%', lg: '60%' }} w={'100%'}
mx="auto"
bg={colors['white-1']} bg={colors['white-1']}
p="xl" p="xl"
radius="lg" radius="lg"
shadow="sm" shadow="sm"
> >
<Stack gap="md" align="center" ta="center"> <Stack gap="md">
<Text fz="xl" fw={700} c={colors['blue-button']}> <Title
ta={"center"}
order={1}
fw={700}
c={colors['blue-button']}
style={{ wordBreak: 'break-word' }}
>
{data.name || 'Penanganan Darurat'} {data.name || 'Penanganan Darurat'}
</Text> </Title>
<Center>
{data.image?.link && ( {data.image?.link && (
<Image <Image
src={data.image.link} src={data.image.link}
@@ -60,10 +66,10 @@ function DetailPenangananDaruratUser() {
mb="md" mb="md"
/> />
)} )}
</Center>
<Box > <Box >
<Text <Text
fz="md"
ta="justify" ta="justify"
dangerouslySetInnerHTML={{ __html: data.deskripsi }} dangerouslySetInnerHTML={{ __html: data.deskripsi }}
style={{ wordBreak: 'break-word', whiteSpace: 'normal' }} style={{ wordBreak: 'break-word', whiteSpace: 'normal' }}
@@ -72,6 +78,7 @@ function DetailPenangananDaruratUser() {
</Stack> </Stack>
</Paper> </Paper>
</Box> </Box>
</Box>
); );
} }

View File

@@ -15,6 +15,7 @@ import {
Stack, Stack,
Text, Text,
TextInput, TextInput,
Title,
Tooltip Tooltip
} from '@mantine/core' } from '@mantine/core'
import { useDebouncedValue, useShallowEffect } from '@mantine/hooks' import { useDebouncedValue, useShallowEffect } from '@mantine/hooks'
@@ -49,10 +50,19 @@ function Page() {
<Grid align="center" px={{ base: 'md', md: 100 }} mb="lg"> <Grid align="center" px={{ base: 'md', md: 100 }} mb="lg">
<GridCol span={{ base: 12, md: 9 }}> <GridCol span={{ base: 12, md: 9 }}>
<Text fz={{ base: 30, md: 40 }} c={colors['blue-button']} fw={800} lh={1.2}> <Title
order={1}
c={colors['blue-button']}
fw={800}
lh={{ base: 1.3, md: 1.2 }}
>
Penanganan Darurat Penanganan Darurat
</Text> </Title>
<Text fz="md" mt={4}> <Text
fz={{ base: 'sm', md: 'md' }}
mt={4}
lh={{ base: 1.5, md: 1.5 }}
>
Informasi cepat dan jelas untuk situasi darurat kesehatan Informasi cepat dan jelas untuk situasi darurat kesehatan
</Text> </Text>
</GridCol> </GridCol>
@@ -74,10 +84,10 @@ function Page() {
{data.length === 0 ? ( {data.length === 0 ? (
<Center py={100}> <Center py={100}>
<Stack align="center" gap="xs"> <Stack align="center" gap="xs">
<Text fz="lg" fw={600} c={colors['blue-button']}> <Title order={2} fw={600} c={colors['blue-button']}>
Tidak ada data ditemukan Tidak ada data ditemukan
</Text> </Title>
<Text fz="sm" c="dimmed"> <Text fz={{ base: 'xs', md: 'sm' }}>
Coba gunakan kata kunci lain Coba gunakan kata kunci lain
</Text> </Text>
</Stack> </Stack>
@@ -128,18 +138,21 @@ function Page() {
</Box> </Box>
<Stack gap={4} w="100%"> <Stack gap={4} w="100%">
<Text <Title
fz="lg" order={3}
fw={700} fw={700}
c={colors['blue-button']} c={colors['blue-button']}
ta="center" ta="center"
lineClamp={2} lineClamp={2}
fz={{ base: 'sm', md: 'lg' }}
lh={{ base: 1.4, md: 1.4 }}
> >
{v.name} {v.name}
</Text> </Title>
<Box> <Box>
<Text <Text
fz="md" fz={{ base: 'xs', md: 'md' }}
lh={{ base: 1.5, md: 1.5 }}
lineClamp={3} lineClamp={3}
dangerouslySetInnerHTML={{ __html: v.deskripsi }} dangerouslySetInnerHTML={{ __html: v.deskripsi }}
style={{ wordBreak: "break-word", whiteSpace: "normal" }} style={{ wordBreak: "break-word", whiteSpace: "normal" }}
@@ -177,10 +190,8 @@ function Page() {
'&:hover': { backgroundColor: colors['blue-button'], color: 'white' }, '&:hover': { backgroundColor: colors['blue-button'], color: 'white' },
}, },
}} }}
/> />
</Center> </Center>
</Stack> </Stack>
) )
} }

View File

@@ -88,7 +88,11 @@ export default function DetailPosyanduUser() {
</Center> </Center>
) : ( ) : (
<Center> <Center>
<Text fz={{ base: 'xs', md: 'sm' }} c="dimmed"> <Text
fz={{ base: 'xs', md: 'sm' }}
c="dimmed"
ta="center"
>
Tidak ada gambar Tidak ada gambar
</Text> </Text>
</Center> </Center>
@@ -99,8 +103,8 @@ export default function DetailPosyanduUser() {
<Flex align="center" gap="xs"> <Flex align="center" gap="xs">
<IconPhone size={18} stroke={1.5} /> <IconPhone size={18} stroke={1.5} />
<Text <Text
fz={{ base: 'xs', md: 'sm' }} fz={{ base: 'sm', md: 'md' }}
c="dimmed" c="black"
lh={{ base: 1.5, md: 1.6 }} lh={{ base: 1.5, md: 1.6 }}
> >
{data.nomor || 'Nomor tidak tersedia'} {data.nomor || 'Nomor tidak tersedia'}
@@ -110,8 +114,8 @@ export default function DetailPosyanduUser() {
<Flex align="center" gap="xs"> <Flex align="center" gap="xs">
<IconCalendar size={18} stroke={1.5} /> <IconCalendar size={18} stroke={1.5} />
<Text <Text
fz={{ base: 'xs', md: 'sm' }} fz={{ base: 'sm', md: 'md' }}
c="dimmed" c="black"
lh={{ base: 1.5, md: 1.6 }} lh={{ base: 1.5, md: 1.6 }}
dangerouslySetInnerHTML={{ __html: data.jadwalPelayanan || '-' }} dangerouslySetInnerHTML={{ __html: data.jadwalPelayanan || '-' }}
style={{ wordBreak: 'break-word', whiteSpace: 'normal' }} style={{ wordBreak: 'break-word', whiteSpace: 'normal' }}
@@ -121,8 +125,8 @@ export default function DetailPosyanduUser() {
<Flex align="center" gap="xs"> <Flex align="center" gap="xs">
<IconInfoCircle size={18} stroke={1.5} /> <IconInfoCircle size={18} stroke={1.5} />
<Text <Text
fz={{ base: 'xs', md: 'sm' }} fz={{ base: 'sm', md: 'md' }}
c="dimmed" c="black"
lh={{ base: 1.5, md: 1.6 }} lh={{ base: 1.5, md: 1.6 }}
dangerouslySetInnerHTML={{ __html: data.deskripsi || '-' }} dangerouslySetInnerHTML={{ __html: data.deskripsi || '-' }}
style={{ wordBreak: 'break-word', whiteSpace: 'normal' }} style={{ wordBreak: 'break-word', whiteSpace: 'normal' }}

View File

@@ -135,32 +135,36 @@ export default function Page() {
</Center> </Center>
<Flex align="flex-start" gap="xs"> <Flex align="flex-start" gap="xs">
<IconPhone size={18} stroke={1.5} style={{ marginTop: 3 }} /> <IconPhone size={18} stroke={1.5} style={{ marginTop: 3 }} />
<Box> <Text
<Text fz={{ base: "xs", md: "sm" }} c="dimmed" lh={1.4}> fz={{ base: "sm", md: "md" }}
c="black"
lh={{ base: 1.4, md: 1.5 }}
>
{v.nomor || "Tidak tersedia"} {v.nomor || "Tidak tersedia"}
</Text> </Text>
</Box>
</Flex> </Flex>
<Flex align="flex-start" gap="xs"> <Flex align="flex-start" gap="xs">
<IconCalendar size={18} stroke={1.5} style={{ marginTop: 3 }} /> <IconCalendar size={18} stroke={1.5} style={{ marginTop: 3 }} />
<Box> <Text
<Text fz={{ base: "xs", md: "sm" }} c="dimmed" lh={1.4}> fz={{ base: "sm", md: "md" }}
c="black"
lh={{ base: 1.4, md: 1.5 }}
>
<strong>Jadwal:</strong>{" "} <strong>Jadwal:</strong>{" "}
<span <span
style={{ wordBreak: "break-word", whiteSpace: "normal" }} style={{ wordBreak: "break-word", whiteSpace: "normal" }}
dangerouslySetInnerHTML={{ __html: v.jadwalPelayanan }} dangerouslySetInnerHTML={{ __html: v.jadwalPelayanan }}
/> />
</Text> </Text>
</Box>
</Flex> </Flex>
<Flex align="flex-start" gap="xs"> <Flex align="flex-start" gap="xs">
<IconInfoCircle size={18} stroke={1.5} style={{ marginTop: 3 }} /> <IconInfoCircle size={18} stroke={1.5} style={{ marginTop: 3 }} />
<Text <Text
fz={{ base: "xs", md: "sm" }} fz={{ base: "sm", md: "md" }}
lh={1.5} lh={{ base: 1.4, md: 1.5 }}
c="dimmed" c="black"
dangerouslySetInnerHTML={{ __html: v.deskripsi }} dangerouslySetInnerHTML={{ __html: v.deskripsi }}
style={{ wordBreak: "break-word", whiteSpace: "normal" }} style={{ wordBreak: "break-word", whiteSpace: "normal" }}
lineClamp={3} lineClamp={3}
@@ -196,7 +200,7 @@ export default function Page() {
Layanan Utama Posyandu Layanan Utama Posyandu
</Title> </Title>
</Flex> </Flex>
<List spacing="xs" fz={{ base: "xs", md: "sm" }} center> <List spacing="xs" fz={{ base: "sm", md: "md" }} lh={{ base: 1.4, md: 1.5 }} c="black">
<ListItem>Penimbangan bayi dan balita</ListItem> <ListItem>Penimbangan bayi dan balita</ListItem>
<ListItem>Pemantauan status gizi</ListItem> <ListItem>Pemantauan status gizi</ListItem>
<ListItem>Imunisasi dasar lengkap</ListItem> <ListItem>Imunisasi dasar lengkap</ListItem>

View File

@@ -1,7 +1,7 @@
'use client' 'use client'
import programKesehatan from '@/app/admin/(dashboard)/_state/kesehatan/program-kesehatan/programKesehatan'; import programKesehatan from '@/app/admin/(dashboard)/_state/kesehatan/program-kesehatan/programKesehatan';
import colors from '@/con/colors'; import colors from '@/con/colors';
import { Box, Center, Group, Image, Loader, Paper, Skeleton, Stack, Text, Tooltip } from '@mantine/core'; import { Box, Center, Group, Image, Loader, Paper, Skeleton, Stack, Text, Title, Tooltip } from '@mantine/core';
import { useShallowEffect } from '@mantine/hooks'; import { useShallowEffect } from '@mantine/hooks';
import { IconCalendar, IconUser } from '@tabler/icons-react'; import { IconCalendar, IconUser } from '@tabler/icons-react';
import { useParams } from 'next/navigation'; import { useParams } from 'next/navigation';
@@ -9,12 +9,12 @@ import { useProxy } from 'valtio/utils';
import BackButton from '../../../desa/layanan/_com/BackButto'; import BackButton from '../../../desa/layanan/_com/BackButto';
function Page() { function Page() {
const state = useProxy(programKesehatan) const state = useProxy(programKesehatan);
const params = useParams() const params = useParams();
useShallowEffect(() => { useShallowEffect(() => {
state.findUnique.load(params.id as string) state.findUnique.load(params.id as string);
}, [params.id]) }, [params.id]);
if (!state.findUnique.data) { if (!state.findUnique.data) {
return ( return (
@@ -24,7 +24,7 @@ function Page() {
<Text c="dimmed" fz="sm">Memuat data program kesehatan...</Text> <Text c="dimmed" fz="sm">Memuat data program kesehatan...</Text>
</Stack> </Stack>
</Center> </Center>
) );
} }
return ( return (
@@ -44,36 +44,41 @@ function Page() {
<Center> <Center>
{state.findUnique.data.image?.link ? ( {state.findUnique.data.image?.link ? (
<Image <Image
radius="xl"
src={state.findUnique.data.image?.link} src={state.findUnique.data.image?.link}
alt={state.findUnique.data.name} alt={state.findUnique.data.name}
w="100%" radius="md"
maw={800} mah={300}
fit="cover" fit="contain"
loading="lazy" loading="lazy"
/> />
) : ( ) : (
<Skeleton h={300} w="100%" radius="xl" /> <Skeleton h={300} w="100%" radius="xl" />
)} )}
</Center> </Center>
<Box> <Box pl={20}>
<Text pb="sm" c={colors["blue-button"]} fw="bold" fz={{ base: 24, md: 32 }} lh={1.2}> <Title
order={1}
pb="sm"
c={colors["blue-button"]}
fw="bold"
lh={{ base: 1.2, md: 1.15 }}
>
{state.findUnique.data.name} {state.findUnique.data.name}
</Text> </Title>
<Text <Text
ta="justify" ta="justify"
fz="md" fz={{ base: 'sm', md: 'md' }}
lh={1.6} lh={{ base: 1.5, md: 1.6 }}
dangerouslySetInnerHTML={{ __html: state.findUnique.data.deskripsi }} dangerouslySetInnerHTML={{ __html: state.findUnique.data.deskripsi }}
style={{wordBreak: "break-word", whiteSpace: "normal"}} style={{ wordBreak: 'break-word', whiteSpace: 'normal' }}
/> />
</Box> </Box>
<Group gap="xl"> <Group gap="xl">
<Group gap="xs"> <Group gap="xs">
<Tooltip label="Tanggal dibuat" withArrow> <Tooltip label="Tanggal dibuat" withArrow>
<IconCalendar color='gray' size={20} stroke={1.5} /> <IconCalendar color="gray" size={20} stroke={1.5} />
</Tooltip> </Tooltip>
<Text size="sm" c="dimmed"> <Text fz={{ base: 'xs', md: 'sm' }} c="dimmed">
{state.findUnique.data.createdAt {state.findUnique.data.createdAt
? new Date(state.findUnique.data.createdAt).toLocaleDateString('id-ID', { ? new Date(state.findUnique.data.createdAt).toLocaleDateString('id-ID', {
day: 'numeric', day: 'numeric',
@@ -85,9 +90,9 @@ function Page() {
</Group> </Group>
<Group gap="xs"> <Group gap="xs">
<Tooltip label="Dibuat oleh" withArrow> <Tooltip label="Dibuat oleh" withArrow>
<IconUser color='gray' size={20} stroke={1.5} /> <IconUser color="gray" size={20} stroke={1.5} />
</Tooltip> </Tooltip>
<Text size="sm" c="dimmed">Admin Desa</Text> <Text fz={{ base: 'xs', md: 'sm' }} c="dimmed">Admin Desa</Text>
</Group> </Group>
</Group> </Group>
</Stack> </Stack>

View File

@@ -16,6 +16,7 @@ import {
Stack, Stack,
Text, Text,
TextInput, TextInput,
Title,
Transition Transition
} from "@mantine/core"; } from "@mantine/core";
import { useDebouncedValue, useShallowEffect } from "@mantine/hooks"; import { useDebouncedValue, useShallowEffect } from "@mantine/hooks";
@@ -57,7 +58,7 @@ export default function Page() {
const state = useProxy(programKesehatan); const state = useProxy(programKesehatan);
const router = useRouter(); const router = useRouter();
const [search, setSearch] = useState(""); const [search, setSearch] = useState("");
const [debouncedSearch] = useDebouncedValue(search, 1000); // 500ms delay const [debouncedSearch] = useDebouncedValue(search, 1000);
const { data, page, totalPages, loading, load } = state.findMany; const { data, page, totalPages, loading, load } = state.findMany;
useShallowEffect(() => { useShallowEffect(() => {
@@ -80,14 +81,19 @@ export default function Page() {
<Grid px={{ base: "md", md: 100 }} align="center" gutter="lg"> <Grid px={{ base: "md", md: 100 }} align="center" gutter="lg">
<GridCol span={{ base: 12, md: 8 }}> <GridCol span={{ base: 12, md: 8 }}>
<Text <Title
fz={{ base: "2rem", md: "2.8rem" }} order={1}
c={colors["blue-button"]} c={colors["blue-button"]}
fw="bold" fw="bold"
fz={{ base: '28px', md: '32px' }}
> >
Program Kesehatan Desa Program Kesehatan Desa
</Text> </Title>
<Text fz="lg" mt="xs"> <Text
fz={{ base: '14px', md: '16px' }}
lh={{ base: '1.5', md: '1.6' }}
mt="xs"
>
Temukan berbagai program kesehatan untuk mendukung kualitas hidup Temukan berbagai program kesehatan untuk mendukung kualitas hidup
masyarakat Darmasaba. masyarakat Darmasaba.
</Text> </Text>
@@ -129,11 +135,9 @@ export default function Page() {
<Box <Box
style={{ style={{
width: '100%', width: '100%',
height: 180, // 🔥 tinggi fix biar semua seragam aspectRatio: '16/9', // thumbnail landscape aman untuk portrait/landscape
borderRadius: 12, borderRadius: 12,
overflow: 'hidden', overflow: 'hidden',
position: 'relative',
backgroundColor: '#f0f2f5', // fallback kalau gambar loading
}} }}
> >
<Image <Image
@@ -142,32 +146,28 @@ export default function Page() {
fit="cover" fit="cover"
width="100%" width="100%"
height="100%" height="100%"
style={{ objectFit: 'cover', objectPosition: 'center' }}
loading="lazy" loading="lazy"
style={{
objectFit: 'cover',
objectPosition: 'center',
transition: 'transform 0.4s ease',
}}
onMouseEnter={(e) => (e.currentTarget.style.transform = 'scale(1.05)')} onMouseEnter={(e) => (e.currentTarget.style.transform = 'scale(1.05)')}
onMouseLeave={(e) => (e.currentTarget.style.transform = 'scale(1)')} onMouseLeave={(e) => (e.currentTarget.style.transform = 'scale(1)')}
/> />
</Box> </Box>
</Center> </Center>
<Box px="lg" pb="lg"> <Box px="lg" pb="lg">
<Text <Title
fw="bold" order={3}
fz="xl"
c={colors["blue-button"]} c={colors["blue-button"]}
fw="bold"
fz={{ base: '18px', md: '20px' }}
mb="xs" mb="xs"
> >
{v.name} {v.name}
</Text> </Title>
<Text <Text
fz="sm" fz={{ base: '13px', md: '14px' }}
ta={"justify"} lh="1.6"
ta="justify"
lineClamp={3} lineClamp={3}
dangerouslySetInnerHTML={{ __html: v.deskripsi }} dangerouslySetInnerHTML={{ __html: v.deskripsi }}
style={{ wordBreak: "break-word", whiteSpace: "normal" }} style={{ wordBreak: "break-word", whiteSpace: "normal" }}
@@ -175,7 +175,10 @@ export default function Page() {
<Group justify="space-between" mt="md"> <Group justify="space-between" mt="md">
<Group gap="xs"> <Group gap="xs">
<IconCalendar size={18} /> <IconCalendar size={18} />
<Text size="sm"> <Text
fz={{ base: '12px', md: '14px' }}
lh="1.5"
>
{v.createdAt {v.createdAt
? new Date(v.createdAt).toLocaleDateString( ? new Date(v.createdAt).toLocaleDateString(
"id-ID", "id-ID",
@@ -190,7 +193,12 @@ export default function Page() {
</Group> </Group>
<Group gap="xs"> <Group gap="xs">
<IconUser size={18} /> <IconUser size={18} />
<Text size="sm">Admin Desa</Text> <Text
fz={{ base: '12px', md: '14px' }}
lh="1.5"
>
Admin Desa
</Text>
</Group> </Group>
</Group> </Group>
<Button <Button
@@ -239,14 +247,19 @@ export default function Page() {
<Box px={{ base: "md", md: 100 }} py="xl"> <Box px={{ base: "md", md: 100 }} py="xl">
<Stack gap="sm" mb="lg"> <Stack gap="sm" mb="lg">
<Text <Title
fz={{ base: "2rem", md: "2.5rem" }} order={2}
c={colors["blue-button"]} c={colors["blue-button"]}
fw="bold" fw="bold"
fz={{ base: '24px', md: '28px' }}
> >
Manfaat Program Kesehatan Manfaat Program Kesehatan
</Text> </Title>
<Text fz="lg" maw={700}> <Text
fz={{ base: '14px', md: '16px' }}
lh={{ base: '1.5', md: '1.6' }}
maw={700}
>
Program kesehatan Desa Darmasaba berperan penting dalam meningkatkan Program kesehatan Desa Darmasaba berperan penting dalam meningkatkan
kesejahteraan dan kualitas hidup warganya. kesejahteraan dan kualitas hidup warganya.
</Text> </Text>
@@ -273,10 +286,20 @@ export default function Page() {
> >
<Center>{v.icon}</Center> <Center>{v.icon}</Center>
</Paper> </Paper>
<Text ta="center" fw="bold" fz="xl" c={colors["blue-button"]}> <Title
order={3}
ta="center"
fw="bold"
c={colors["blue-button"]}
fz={{ base: '18px', md: '20px' }}
>
{v.title} {v.title}
</Text> </Title>
<Text ta="center" fz="sm"> <Text
ta="center"
fz={{ base: '13px', md: '14px' }}
lh="1.5"
>
{v.desc} {v.desc}
</Text> </Text>
</Stack> </Stack>

View File

@@ -59,12 +59,16 @@ function Page() {
left={20} left={20}
gap={6} gap={6}
> >
<Text fw="bold" fz={{ base: 'lg', md: 'h2' }} c={colors['white-1']}> <Title
order={1}
c={colors['white-1']}
fz={{ base: 'lg', md: 'xl' }}
>
{data.name} {data.name}
</Text> </Title>
<Group gap={6}> <Group gap={6}>
<IconMapPin size={20} color="white" /> <IconMapPin size={20} color="white" />
<Text fz={{ base: 'sm', md: 'md' }} c={colors['white-1']}> <Text fz={{ base: 'xs', md: 'sm' }} c={colors['white-1']}>
{data.alamat} {data.alamat}
</Text> </Text>
</Group> </Group>
@@ -75,35 +79,43 @@ function Page() {
<GridCol span={{ base: 12, md: 6 }}> <GridCol span={{ base: 12, md: 6 }}>
<Stack gap="lg"> <Stack gap="lg">
<Box> <Box>
<Title order={3} mb={10}>Informasi Kontak</Title> <Title order={2} mb="md">Informasi Kontak</Title>
<Stack gap={8}> <Stack gap={8}>
<Group gap={8}> <Group gap={8}>
<IconPhone size={18} /> <IconPhone size={18} />
<Text fz="md">{data.kontak.kontakPuskesmas || '-'}</Text> <Text fz={{ base: 'sm', md: 'md' }}>
{data.kontak.kontakPuskesmas || '-'}
</Text>
</Group> </Group>
<Group gap={8}> <Group gap={8}>
<IconMail size={18} /> <IconMail size={18} />
<Text fz="md">{data.kontak.email || '-'}</Text> <Text fz={{ base: 'sm', md: 'md' }}>
{data.kontak.email || '-'}
</Text>
</Group> </Group>
</Stack> </Stack>
</Box> </Box>
<Divider /> <Divider />
<Stack gap={"xs"}> <Stack gap="xs">
<Title order={3} mb={10}>Jam Operasional</Title> <Title order={2} mb="md">Jam Operasional</Title>
<Text fw="bold" fz="md">Senin - Jumat</Text> <Text fw="bold" fz={{ base: 'sm', md: 'md' }}>Senin - Jumat</Text>
<Group gap={8}> <Group gap={8}>
<IconClock size={18} /> <IconClock size={18} />
<Text fw="bold" fz="md">{data.jam.workDays} - {data.jam.weekDays}</Text> <Text fw="bold" fz={{ base: 'sm', md: 'md' }}>
{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>
<Text fw="bold" fz="md">Sabtu - Minggu / Hari Libur</Text> <Text fw="bold" fz={{ base: 'sm', md: 'md' }}>Sabtu Minggu / Hari Libur</Text>
<Group gap={8}> <Group gap={8}>
<IconClock size={18} /> <IconClock size={18} />
<Text fw="bold" fz="md">{data.jam.holiday}</Text> <Text fw="bold" fz={{ base: 'sm', md: 'md' }}>
{data.jam.holiday}
</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>
@@ -114,20 +126,24 @@ function Page() {
<GridCol span={{ base: 12, md: 6 }}> <GridCol span={{ base: 12, md: 6 }}>
<Paper p="xl" radius="lg" bg="linear-gradient(135deg, #EAF0FB, #BFD4F5)" shadow="sm"> <Paper p="xl" radius="lg" bg="linear-gradient(135deg, #EAF0FB, #BFD4F5)" shadow="sm">
<Title order={3} mb="lg" ta="center" c="dark">Layanan Unggulan</Title> <Title order={2} mb="lg" ta="center" c="dark">Layanan Unggulan</Title>
<SimpleGrid cols={{ base: 1, sm: 2 }} spacing="lg"> <SimpleGrid cols={{ base: 1, sm: 2 }} spacing="lg">
<Paper p="lg" radius="lg" withBorder bg={colors['white-trans-1']} shadow="xs"> <Paper p="lg" radius="lg" withBorder bg={colors['white-trans-1']} shadow="xs">
<Stack align="center" gap={8}> <Stack align="center" gap={8}>
<IconBuildingHospital size={36} color={colors['blue-button']} /> <IconBuildingHospital size={36} color={colors['blue-button']} />
<Text fw="bold" fz="lg">Poliklinik Umum</Text> <Text fw="bold" fz={{ base: 'sm', md: 'md' }}>Poliklinik Umum</Text>
<Text fz={{ base: 36, md: 48 }} fw="bold" c={colors['blue-button']}>26</Text> <Text fz={{ base: 'h1', md: 'h1' }} fw="bold" c={colors['blue-button']} lh={1}>
26
</Text>
</Stack> </Stack>
</Paper> </Paper>
<Paper p="lg" radius="lg" withBorder bg={colors['white-trans-1']} shadow="xs"> <Paper p="lg" radius="lg" withBorder bg={colors['white-trans-1']} shadow="xs">
<Stack align="center" gap={8}> <Stack align="center" gap={8}>
<IconBuildingHospital size={36} color={colors['blue-button']} /> <IconBuildingHospital size={36} color={colors['blue-button']} />
<Text fw="bold" fz="lg">Poli Gigi</Text> <Text fw="bold" fz={{ base: 'sm', md: 'md' }}>Poli Gigi</Text>
<Text fz={{ base: 36, md: 48 }} fw="bold" c={colors['blue-button']}>26</Text> <Text fz={{ base: 'h1', md: 'h1' }} fw="bold" c={colors['blue-button']} lh={1}>
26
</Text>
</Stack> </Stack>
</Paper> </Paper>
</SimpleGrid> </SimpleGrid>

View File

@@ -1,7 +1,7 @@
'use client' 'use client'
import puskesmasState from '@/app/admin/(dashboard)/_state/kesehatan/puskesmas/puskesmas'; import puskesmasState from '@/app/admin/(dashboard)/_state/kesehatan/puskesmas/puskesmas';
import colors from '@/con/colors'; import colors from '@/con/colors';
import { Anchor, Box, Center, Grid, GridCol, Image, Pagination, Paper, SimpleGrid, Skeleton, Stack, Text, TextInput, Badge, Group } from '@mantine/core'; import { Anchor, Box, Center, Grid, GridCol, Image, Pagination, Paper, SimpleGrid, Skeleton, Stack, Text, TextInput, Badge, Group, Title } from '@mantine/core';
import { useShallowEffect } from '@mantine/hooks'; import { useShallowEffect } from '@mantine/hooks';
import { IconSearch, IconMapPin, IconPhone, IconMail } from '@tabler/icons-react'; import { IconSearch, IconMapPin, IconPhone, IconMail } from '@tabler/icons-react';
import { useState } from 'react'; import { useState } from 'react';
@@ -42,10 +42,10 @@ function Page() {
<Grid align="center" px={{ base: 'md', md: 100 }} mb="md"> <Grid align="center" px={{ base: 'md', md: 100 }} mb="md">
<GridCol span={{ base: 12, md: 8 }}> <GridCol span={{ base: 12, md: 8 }}>
<Text fz={{ base: "2rem", md: "2.5rem" }} c={colors["blue-button"]} fw="bold"> <Title order={1} c={colors["blue-button"]}>
Daftar Puskesmas Daftar Puskesmas
</Text> </Title>
<Text fz="md"> <Text fz={{ base: "sm", md: "md" }} ta="start">
Temukan informasi lengkap mengenai layanan, kontak, dan lokasi Puskesmas Darmasaba Temukan informasi lengkap mengenai layanan, kontak, dan lokasi Puskesmas Darmasaba
</Text> </Text>
</GridCol> </GridCol>
@@ -65,8 +65,8 @@ function Page() {
{data.length === 0 ? ( {data.length === 0 ? (
<Center py="xl"> <Center py="xl">
<Stack align="center" gap="xs"> <Stack align="center" gap="xs">
<Text fz="lg" fw={500} c="dimmed">Tidak ada data ditemukan</Text> <Title order={2} fw={500} c="dimmed">Tidak ada data ditemukan</Title>
<Text fz="sm" c="dimmed">Coba gunakan kata kunci pencarian yang berbeda</Text> <Text fz={{ base: "xs", md: "sm" }} c="dimmed">Coba gunakan kata kunci pencarian yang berbeda</Text>
</Stack> </Stack>
</Center> </Center>
) : ( ) : (
@@ -92,29 +92,29 @@ function Page() {
loading="lazy" loading="lazy"
/> />
<Group justify="space-between"> <Group justify="space-between">
<Text fw={600} fz="lg" lineClamp={1}>{v.name}</Text> <Title order={3} fw={600} lineClamp={1}>{v.name}</Title>
<Badge color="blue" variant="light" radius="sm" fz="xs">Aktif</Badge> <Badge color="blue" variant="light" radius="sm" fz="xs">Aktif</Badge>
</Group> </Group>
<Stack gap={6}> <Stack gap={6}>
<Group gap="xs" align="flex-start" wrap="nowrap"> <Group gap="xs" align="flex-start" wrap="nowrap">
<Box pt={2}><IconMapPin size={20} /></Box> <Box pt={2}><IconMapPin size={20} /></Box>
<Text fz="sm" c="dimmed">{v.alamat}</Text> <Text fz={{ base: "sm", md: "md" }}>{v.alamat}</Text>
</Group> </Group>
<Group gap="xs" align="flex-start" wrap="nowrap"> <Group gap="xs" align="flex-start" wrap="nowrap">
<Box pt={2}><IconPhone size={20} /></Box> <Box pt={2}><IconPhone size={20} /></Box>
<Text fz="sm" c="dimmed">{v.kontak.kontakPuskesmas}</Text> <Text fz={{ base: "sm", md: "md" }}>{v.kontak.kontakPuskesmas}</Text>
</Group> </Group>
<Group gap="xs" align="flex-start" wrap="nowrap"> <Group gap="xs" align="flex-start" wrap="nowrap">
<Box pt={2}><IconMail size={20} /></Box> <Box pt={2}><IconMail size={20} /></Box>
<Text fz="sm" c="dimmed">{v.kontak.email}</Text> <Text fz={{ base: "sm", md: "md" }}>{v.kontak.email}</Text>
</Group> </Group>
</Stack> </Stack>
<Anchor <Anchor
href={`/darmasaba/kesehatan/puskesmas/${v.id}`} href={`/darmasaba/kesehatan/puskesmas/${v.id}`}
fz="sm" fz={{ base: "sm", md: "md" }}
fw={500} fw={500}
c={colors['blue-button']} c={colors['blue-button']}
> >

View File

@@ -64,14 +64,14 @@ function Page() {
</Text> </Text>
<TextInput <TextInput
radius="xl" radius="xl"
w={'30%'} w={{base: "100%", md: "30%"}}
placeholder="Cari Data Lingkungan Desa" placeholder="Cari Data Lingkungan Desa"
leftSection={<IconSearch size={20} />} leftSection={<IconSearch size={20} />}
value={search} value={search}
onChange={(e) => setSearch(e.currentTarget.value)} onChange={(e) => setSearch(e.currentTarget.value)}
/> />
</Group> </Group>
<Text fz="md" > <Text fz="md" pt={20}>
Desa Darmasaba menjaga dan mengembangkan lingkungan demi kesejahteraan warganya. Desa Darmasaba menjaga dan mengembangkan lingkungan demi kesejahteraan warganya.
</Text> </Text>
<Text fz="md"> <Text fz="md">