Compare commits

...

1 Commits

Author SHA1 Message Date
f6f77d9e35 Fix QC Kak Inno Tgl 11 Des
Fix QC Kak Ayu Tgl 11 Des
Fix font style {font size, color, line height} menu kesehatan
2025-12-12 17:06:33 +08:00
28 changed files with 802 additions and 496 deletions

View File

@@ -76,13 +76,13 @@ function Page() {
</Box>
<Flex pb={30} justify={'center'} gap={'xl'} align={'center'}>
<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>
<ColorSwatch color="#5082EE" size={30} />
</Flex>
</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>
<ColorSwatch color="#6EDF9C" size={30} />
</Flex>

View File

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

View File

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

View File

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

View File

@@ -1,20 +1,18 @@
'use client'
import CreateEditor from '@/app/admin/(dashboard)/_com/createEditor';
import ajukanIdeInovatifState from '@/app/admin/(dashboard)/_state/inovasi/ajukan-ide-inovatif';
import colors from '@/con/colors';
import { ActionIcon, Box, Button, Flex, List, ListItem, Modal, Paper, SimpleGrid, Stack, Text, TextInput, Title } from '@mantine/core';
import { useDisclosure } from '@mantine/hooks';
import { IconArrowRight, IconBulbFilled } from '@tabler/icons-react';
import { IconBulbFilled } from '@tabler/icons-react';
import { useProxy } from 'valtio/utils';
import BackButton from '../../desa/layanan/_com/BackButto';
import CreateEditor from '@/app/admin/(dashboard)/_com/createEditor';
function Page() {
const [opened, { open, close }] = useDisclosure(false);
const ideInovatif = useProxy(ajukanIdeInovatifState)
const ideInovatif = useProxy(ajukanIdeInovatifState);
const resetForm = () => {
// Reset state di valtio
ideInovatif.create.form = {
name: "",
deskripsi: "",
@@ -23,53 +21,66 @@ function Page() {
masalah: "",
benefit: "",
};
// Reset state lokal
};
const handleSubmit = async () => {
// Submit data berita
await ideInovatif.create.create();
// Reset form setelah submit
resetForm();
close();
};
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 }}>
<BackButton />
</Box>
<Box px={{ base: 'md', md: 100 }} >
<Text ta={"center"} fz={{ base: "h1", md: "2.5rem" }} c={colors["blue-button"]} fw={"bold"}>
<Box px={{ base: 'md', md: 100 }}>
<Title
order={1}
ta="center"
c={colors["blue-button"]}
fw="bold"
style={{ fontSize: 'clamp(1.75rem, 4vw, 2.25rem)' }}
>
Ajukan Ide Inovatif
</Title>
<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>
<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>
</Box>
<Box px={{ base: "md", md: 100 }}>
<Stack gap={'lg'} p={'lg'}>
<SimpleGrid
cols={{
base: 1,
md: 2,
}}
>
<Paper p={'xl'} >
<Stack gap={"xs"}>
<Text fz={'h3'} fw={'bold'} c={colors['blue-button']}>Tujuan Ide Inovatif Ini</Text>
<List>
<ListItem ta={'justify'} fz={{ base: 'h4', md: 'lg' }}>Mendorong partisipasi aktif masyarakat</ListItem>
<ListItem ta={'justify'} fz={{ base: 'h4', md: 'lg' }}>Memfasilitasi inovasi berbasis lokal</ListItem>
<ListItem ta={'justify'} fz={{ base: 'h4', md: 'lg' }}>Memecahkan tantangan komunal</ListItem>
<ListItem ta={'justify'} fz={{ base: 'h4', md: 'lg' }}>Mengembangkan potensi kreativitas warga</ListItem>
</List>
<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>
<ListItem ta="justify" fz={{ base: 'sm', md: 'md' }} lh="1.5">
Mendorong partisipasi aktif masyarakat
</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>
</Stack>
</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>
<Text fz={'h4'} fw={'bold'} c={colors['blue-button']}>Apabila Anda Ingin Mengajukan Ide Inovatif Bisa Klik Pada Gambar Di Samping</Text>
<IconArrowRight size={30} color={colors['blue-button']} />
<Title order={3} c={colors['blue-button']} fw="bold" ta={{ base: 'center', md: 'start' }}>
Apabila Anda Ingin Mengajukan Ide Inovatif Bisa Klik Pada Gambar
</Title>
</Box>
<Box px={{ base: 5, md: 10 }} py={5}>
<ActionIcon variant="transparent" size={150} onClick={open}>
@@ -88,32 +99,46 @@ function Page() {
radius={0}
transitionProps={{ transition: 'fade', duration: 200 }}
>
<Paper p={"md"} withBorder>
<Stack gap={"xs"}>
<Paper p="md" withBorder>
<Stack gap="xs">
<Title order={3}>Ajukan Ide Inovatif</Title>
<TextInput
label={<Text fz={"sm"} fw={"bold"}>Nama</Text>}
label={
<Text fz="sm" fw="bold">
Nama
</Text>
}
placeholder="masukkan nama"
onChange={(val) => {
ideInovatif.create.form.name = val.target.value
ideInovatif.create.form.name = val.target.value;
}}
/>
<TextInput
label={<Text fz={"sm"} fw={"bold"}>Alamat</Text>}
label={
<Text fz="sm" fw="bold">
Alamat
</Text>
}
placeholder="masukkan alamat"
onChange={(val) => {
ideInovatif.create.form.alamat = val.target.value
ideInovatif.create.form.alamat = val.target.value;
}}
/>
<TextInput
label={<Text fz={"sm"} fw={"bold"}>Nama Ide</Text>}
label={
<Text fz="sm" fw="bold">
Nama Ide
</Text>
}
placeholder="masukkan nama ide"
onChange={(val) => {
ideInovatif.create.form.namaIde = val.target.value
ideInovatif.create.form.namaIde = val.target.value;
}}
/>
<Box>
<Text fz={"sm"} fw={"bold"}>Deskripsi</Text>
<Text fz="sm" fw="bold">
Deskripsi
</Text>
<CreateEditor
value={ideInovatif.create.form.deskripsi}
onChange={(htmlContent) => {
@@ -122,26 +147,35 @@ function Page() {
/>
</Box>
<TextInput
label={<Text fz={"sm"} fw={"bold"}>Masalah</Text>}
label={
<Text fz="sm" fw="bold">
Masalah
</Text>
}
placeholder="masukkan masalah"
onChange={(val) => {
ideInovatif.create.form.masalah = val.target.value
ideInovatif.create.form.masalah = val.target.value;
}}
/>
<TextInput
label={<Text fz={"sm"} fw={"bold"}>Benefit</Text>}
label={
<Text fz="sm" fw="bold">
Benefit
</Text>
}
placeholder="masukkan benefit"
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>
</Paper>
</Modal>
</Stack>
);
}
export default Page;
export default Page;

View File

@@ -58,7 +58,7 @@ function Page() {
/>
</GridCol>
</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>
</Box>
<Box px={{ base: "md", md: 100 }}>

View File

@@ -1,17 +1,17 @@
'use client'
import colors from '@/con/colors';
import { Box, Center, Grid, GridCol, Image, Pagination, Paper, SimpleGrid, Skeleton, Stack, Text, TextInput } from '@mantine/core';
import BackButton from '../../desa/layanan/_com/BackButto';
import { Box, Center, Grid, GridCol, Image, Pagination, Paper, SimpleGrid, Skeleton, Stack, Text, TextInput, Title } from '@mantine/core';
import { useProxy } from 'valtio/utils';
import { useDebouncedValue, useShallowEffect } from '@mantine/hooks';
import { useState } from 'react';
import infoTeknoState from '@/app/admin/(dashboard)/_state/inovasi/info-tekno';
import { IconSearch } from '@tabler/icons-react';
import BackButton from '../../desa/layanan/_com/BackButto';
function Page() {
const [search, setSearch] = useState("")
const [debouncedSearch] = useDebouncedValue(search, 1000); // 500ms delay
const [debouncedSearch] = useDebouncedValue(search, 1000);
const state = useProxy(infoTeknoState)
const {
data,
@@ -34,17 +34,24 @@ function Page() {
</Stack>
)
}
return (
<Stack pos={"relative"} bg={colors.Bg} py={"xl"} gap={"22"}>
<Box px={{ base: 'md', md: 100 }}>
<BackButton />
</Box>
<Box px={{ base: 'md', md: 100 }} >
<Box px={{ base: 'md', md: 100 }}>
<Grid align='center'>
<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
</Text>
</Title>
</GridCol>
<GridCol span={{ base: 12, md: 3 }}>
<TextInput
@@ -53,13 +60,19 @@ function Page() {
value={search}
onChange={(e) => setSearch(e.target.value)}
leftSection={<IconSearch size={20} />}
w={{ base: "50%", md: "100%" }}
w={{ base: "100%", md: "100%" }}
/>
</GridCol>
</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 px={{ base: "md", md: 100 }}>
<Stack gap={'lg'} p={'lg'}>
<SimpleGrid
@@ -74,12 +87,14 @@ function Page() {
<Paper p={'xl'} key={k}>
<Stack gap={"xs"}>
<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}>
<Text
size="md"
fz={{ base: 'xs', md: 'sm' }}
ta="justify"
lh={1} // line height biar enak dibaca
lh={1.5}
style={{
wordBreak: "break-word",
whiteSpace: "normal",
@@ -94,10 +109,11 @@ function Page() {
</SimpleGrid>
</Stack>
</Box>
<Center>
<Pagination
value={page}
onChange={(newPage) => load(newPage)} // ini penting!
onChange={(newPage) => load(newPage)}
total={totalPages}
my="md"
/>
@@ -106,4 +122,4 @@ function Page() {
);
}
export default Page;
export default Page;

View File

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

View File

@@ -2,7 +2,7 @@
import artikelKesehatanState from '@/app/admin/(dashboard)/_state/kesehatan/data_kesehatan_warga/artikelKesehatan';
import BackButton from '@/app/darmasaba/(pages)/desa/layanan/_com/BackButto';
import colors from '@/con/colors';
import { Box, Divider, 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 { IconAlertCircle, IconCalendar, IconInfoCircle } from '@tabler/icons-react';
import { useParams } from 'next/navigation';
@@ -37,9 +37,9 @@ function Page() {
<Stack gap="lg">
<Paper radius="xl" shadow="md" withBorder>
<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'}
</Text>
</Title>
</Box>
<Box p="lg">
@@ -64,7 +64,7 @@ function Page() {
<Stack gap="lg">
<Group gap="xs">
<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', {
year: 'numeric',
month: 'long',
@@ -74,48 +74,47 @@ function Page() {
</Group>
<Stack gap="lg">
<Box>
<Text fz="h4" fw="bold">Pendahuluan</Text>
<Title order={2} fw="bold">Pendahuluan</Title>
<Divider my="xs" />
<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>
<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" />
<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>
<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" />
<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>
<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" />
<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>
<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" />
<Box pb="md">
<Table highlightOnHover withTableBorder withColumnBorders striped>
<TableThead>
<TableTr>
<TableTh fz="sm" fw="bold">Mitos</TableTh>
<TableTh fz="sm" fw="bold">Fakta</TableTh>
<TableTh fz={{ base: 'xs', md: 'sm' }} fw="bold">Mitos</TableTh>
<TableTh fz={{ base: 'xs', md: 'sm' }} fw="bold">Fakta</TableTh>
</TableTr>
</TableThead>
<TableTbody>
@@ -123,12 +122,12 @@ function Page() {
<TableTr>
<TableTd>
<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>
</TableTd>
<TableTd>
<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>
</TableTd>
</TableTr>
@@ -143,34 +142,35 @@ function Page() {
</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" />
<Flex justify={'flex-start'} gap={"xs"} align={"center"} mb="xs">
<IconAlertCircle size={18} color="red" />
<Text fz="md">Segera bawa penderita ke fasilitas kesehatan jika mengalami:</Text>
<Text fz={{ base: 'sm', md: 'md' }} lh={1.5}>Segera bawa penderita ke fasilitas kesehatan jika mengalami:</Text>
</Flex>
<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>
<Paper p="lg" radius="md" bg={colors['blue-button-trans']} withBorder>
<Group gap="xs" mb="sm">
<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>
<Stack gap={4}>
<Text fz="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="sm" c={colors['white-1']}>Email: <b>p2p@dinkes.badungkab.go.id</b></Text>
<Text fz={{ base: 'xs', md: 'sm' }} c={colors['white-1']}>Hotline DBD: <b>(0361) 123456</b></Text>
<Text fz={{ base: 'xs', md: 'sm' }} c={colors['white-1']}>WhatsApp Center: <b>081234567890</b></Text>
<Text fz={{ base: 'xs', md: 'sm' }} c={colors['white-1']}>Email: <b>p2p@dinkes.badungkab.go.id</b></Text>
</Stack>
</Paper>
</Box>
<Box>
<Text fz="h4" fw="bold">Referensi</Text>
<Title order={2} fw="bold">Referensi</Title>
<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>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>
@@ -186,4 +186,4 @@ function Page() {
);
}
export default Page;
export default Page;

View File

@@ -1,7 +1,7 @@
'use client'
import artikelKesehatanState from '@/app/admin/(dashboard)/_state/kesehatan/data_kesehatan_warga/artikelKesehatan';
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 { IconCalendar, IconChevronRight } from '@tabler/icons-react';
import { useRouter } from 'next/navigation';
@@ -27,13 +27,13 @@ function ArtikelKesehatanPage() {
<Box>
<Paper p="xl" bg={colors['white-trans-1']} radius="xl" shadow="md">
<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
</Text>
</Title>
<Divider size="sm" color={colors['blue-button']} />
{state.findMany.data.length === 0 ? (
<Box py="xl" ta="center">
<Text fz="lg" c="dimmed">
<Text fz={{ base: 'sm', sm: 'md' }} c="dimmed">
Belum ada artikel kesehatan yang tersedia
</Text>
</Box>
@@ -50,17 +50,26 @@ function ArtikelKesehatanPage() {
onMouseLeave={(e) => (e.currentTarget.style.transform = 'translateY(0)')}
>
<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>
<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">
<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
</Text>
</Group>
<Text fz="md" lineClamp={3}>
<Text fz={{ base: 'sm', sm: 'md' }} lh={{ base: 'sm', sm: 'md' }} lineClamp={3}>
{item.content}
</Text>
<Group justify="flex-start">
@@ -84,4 +93,4 @@ function ArtikelKesehatanPage() {
);
}
export default ArtikelKesehatanPage;
export default ArtikelKesehatanPage;

View File

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

View File

@@ -40,7 +40,11 @@ function FasilitasKesehatanPage() {
<Stack gap="lg">
{state.findMany.data.length === 0 ? (
<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
</Text>
</Box>
@@ -67,20 +71,36 @@ function FasilitasKesehatanPage() {
>
<Stack gap="sm">
<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">
Aktif
</Badge>
</Group>
<Group gap="xs">
<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}
</Text>
</Group>
<Group gap="xs">
<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}
</Text>
</Group>

View File

@@ -11,7 +11,8 @@ import {
Paper,
Skeleton,
Stack,
Text
Text,
Title
} from '@mantine/core';
import { useDisclosure, useShallowEffect } from '@mantine/hooks';
import { IconMail, IconPhone, IconUser } from '@tabler/icons-react';
@@ -51,55 +52,97 @@ function Page() {
style={{ borderTopLeftRadius: 16, borderTopRightRadius: 16 }}
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
</Text>
</Title>
</Box>
<Box p="lg">
<Stack gap="xl">
<Stack gap="sm">
<Text fz="lg" fw="bold">Informasi Kegiatan</Text>
<Title order={2} fw="bold">Informasi Kegiatan</Title>
<Divider />
<Text fz="md" fw="bold">Nama Kegiatan: <Text span>{state.findUnique.data.informasijadwalkegiatan.name}</Text></Text>
<Text fz="md" fw="bold">Tanggal: <Text span>{state.findUnique.data.informasijadwalkegiatan.tanggal}</Text></Text>
<Text fz="md" fw="bold">Waktu: <Text span>{state.findUnique.data.informasijadwalkegiatan.waktu}</Text></Text>
<Text fz="md" fw="bold">Lokasi: <Text span>{state.findUnique.data.informasijadwalkegiatan.lokasi}</Text></Text>
<Text fw="bold">
Nama Kegiatan:&nbsp;
<Text span fw="normal">
{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 gap="sm">
<Text fz="lg" fw="bold">Deskripsi Kegiatan</Text>
<Title order={2} fw="bold">Deskripsi Kegiatan</Title>
<Divider />
<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>
</Stack>
<Stack gap="sm">
<Text fz="lg" fw="bold">Layanan yang Tersedia</Text>
<Title order={2} fw="bold">Layanan yang Tersedia</Title>
<Divider />
<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>
</Stack>
<Stack gap="sm">
<Text fz="lg" fw="bold">Syarat & Ketentuan</Text>
<Title order={2} fw="bold">Syarat & Ketentuan</Title>
<Divider />
<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>
</Stack>
<Stack gap="sm">
<Text fz="lg" fw="bold">Dokumen yang Perlu Dibawa</Text>
<Title order={2} fw="bold">Dokumen yang Perlu Dibawa</Title>
<Divider />
<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>
</Stack>
<Stack gap="sm">
<Text fz="lg" fw="bold">Pendaftaran Kegiatan</Text>
<Title order={2} fw="bold">Pendaftaran Kegiatan</Title>
<Divider />
<Group>
<Button onClick={open}>Buat Pendaftaran</Button>
@@ -112,18 +155,21 @@ function Page() {
<Paper p="lg" radius="md" bg={colors['blue-button-trans']} shadow="sm">
<Stack gap="xs">
<Text fz="lg" c={colors['white-1']} fw="bold">Informasi Kontak</Text>
<Group gap="xs">
<Title order={3} c={colors['white-1']} fw="bold">Informasi Kontak</Title>
<Group gap="xs" justify="flex-start">
<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 gap="xs">
<IconPhone size={18} color="white" />
<Text fz="md" c={colors['white-1']}>081234567890</Text>
<Text c={colors['white-1']}>081234567890</Text>
</Group>
<Group gap="xs">
<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>
</Stack>
</Paper>
@@ -136,4 +182,4 @@ function Page() {
);
}
export default Page;
export default Page;

View File

@@ -2,15 +2,14 @@
'use client'
import pendaftaranJadwalKegiatanState from '@/app/admin/(dashboard)/_state/kesehatan/data_kesehatan_warga/pendafataranJadwalKegiatan';
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 { useProxy } from 'valtio/utils';
function CreatePendaftaran() {
const stateCreate = useProxy(pendaftaranJadwalKegiatanState);
useEffect(() => {
useEffect(() => {
stateCreate.findMany.load();
}, []);
@@ -32,15 +31,19 @@ useEffect(() => {
return (
<Stack gap="sm">
<Text fz="lg" fw="bold">Formulir Pendaftaran</Text>
<Title order={2} ta="left">Formulir Pendaftaran</Title>
<Divider />
<Stack gap="md">
<TextInput
label="Nama Balita"
placeholder="Masukkan nama balita"
size="md"
value={stateCreate.create.form.name}
onChange={(e) => stateCreate.create.form.name = e.target.value}
label="Nama Balita"
placeholder="Masukkan nama balita"
size="md"
value={stateCreate.create.form.name}
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
type='date'
@@ -50,41 +53,63 @@ useEffect(() => {
w={{ base: '100%', md: '85%', lg: '75%', xl: '50%' }}
value={stateCreate.create.form.tanggal}
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
label="Nama Orang Tua / Wali"
placeholder="Masukkan nama orang tua / wali"
size="md"
value={stateCreate.create.form.namaOrangtua}
onChange={(e) => stateCreate.create.form.namaOrangtua = e.target.value}
label="Nama Orang Tua / Wali"
placeholder="Masukkan nama orang tua / wali"
size="md"
value={stateCreate.create.form.namaOrangtua}
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
label="Nomor Telepon"
placeholder="Masukkan nomor telepon"
size="md"
value={stateCreate.create.form.nomor}
onChange={(e) => stateCreate.create.form.nomor = e.target.value}
label="Nomor Telepon"
placeholder="Masukkan nomor telepon"
size="md"
value={stateCreate.create.form.nomor}
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
label="Alamat"
placeholder="Masukkan alamat lengkap"
size="md"
value={stateCreate.create.form.alamat}
onChange={(e) => stateCreate.create.form.alamat = e.target.value}
label="Alamat"
placeholder="Masukkan alamat lengkap"
size="md"
value={stateCreate.create.form.alamat}
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
label="Catatan Khusus (Opsional)"
placeholder="Masukkan catatan jika ada"
size="md"
value={stateCreate.create.form.catatan}
onChange={(e) => stateCreate.create.form.catatan = e.target.value}
label="Catatan Khusus (Opsional)"
placeholder="Masukkan catatan jika ada"
size="md"
value={stateCreate.create.form.catatan}
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}>
Daftar Sekarang
<Text fz={{ base: 'sm', md: 'md' }} fw={600} c="white">
Daftar Sekarang
</Text>
</Button>
</Stack>
</Stack>
);
}
export default CreatePendaftaran;
export default CreatePendaftaran;

View File

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

View File

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

View File

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

View File

@@ -1,7 +1,7 @@
'use client'
import kontakDarurat from '@/app/admin/(dashboard)/_state/kesehatan/kontak-darurat/kontakDarurat';
import colors from '@/con/colors';
import { Box, Button, Group, Image, Paper, Skeleton, Stack, Text } from '@mantine/core';
import { Box, Button, Group, Image, Paper, Skeleton, Stack, Text, Title } from '@mantine/core';
import { useShallowEffect } from '@mantine/hooks';
import { IconArrowBack, IconBrandWhatsapp } from '@tabler/icons-react';
import { useParams, useRouter } from 'next/navigation';
@@ -27,15 +27,16 @@ function Page() {
const data = state.findUnique.data;
return (
<Box px={{base: 'md', md: 100}} py={10}>
<Box px={{ base: 'md', md: 100 }} py={10}>
{/* Tombol Back */}
<Button
variant="subtle"
onClick={() => router.back()}
leftSection={<IconArrowBack size={24} color={colors['blue-button']} />}
mb={15}
style={{ lineHeight: 1.2 }}
>
Kembali
<Text fz={{ base: 'sm', md: 'md' }} fw={500}>Kembali</Text>
</Button>
{/* Wrapper Detail */}
@@ -48,34 +49,38 @@ function Page() {
shadow="sm"
>
<Stack gap="md">
<Text fz="2xl" fw="bold" c={colors['blue-button']}>
<Title order={1} c={colors['blue-button']}>
Detail Kontak Darurat
</Text>
</Title>
<Paper bg="#ECEEF8" p="md" radius="md" shadow="xs">
<Stack gap="sm">
<Box>
<Text fz="lg" fw="bold">Judul</Text>
<Text fz="md" c="dimmed">{data.name || '-'}</Text>
<Title order={3}>Judul</Title>
<Text fz={{ base: 'sm', md: 'md' }} c={data.name ? 'black' : 'dimmed'}>
{data.name || '-'}
</Text>
</Box>
<Box>
<Text fz="lg" fw="bold">Whatsapp</Text>
<Text fz="md" c="dimmed">{data.whatsapp || '-'}</Text>
<Title order={3}>Whatsapp</Title>
<Text fz={{ base: 'sm', md: 'md' }} c={data.whatsapp ? 'black' : 'dimmed'}>
{data.whatsapp || '-'}
</Text>
</Box>
<Box>
<Text fz="lg" fw="bold">Deskripsi</Text>
<Title order={3}>Deskripsi</Title>
<Text
fz="md"
c="dimmed"
fz={{ base: 'sm', md: 'md' }}
c={data.deskripsi ? 'black' : 'dimmed'}
dangerouslySetInnerHTML={{ __html: data.deskripsi || '-' }}
style={{ wordBreak: "break-word", whiteSpace: "normal" }}
style={{ wordBreak: 'break-word', whiteSpace: 'normal', lineHeight: 1.5 }}
/>
</Box>
<Box>
<Text fz="lg" fw="bold">Gambar</Text>
<Title order={3}>Gambar</Title>
{data.image?.link ? (
<Image
src={data.image.link}
@@ -85,9 +90,10 @@ function Page() {
loading="lazy"
/>
) : (
<Text fz="md" c="dimmed">-</Text>
<Text fz={{ base: 'sm', md: 'md' }} c="dimmed">-</Text>
)}
</Box>
<Group>
<Button
variant="light"
@@ -96,6 +102,7 @@ function Page() {
href={`https://wa.me/${data.whatsapp.replace(/\D/g, '')}`}
target="_blank"
aria-label="Hubungi WhatsApp"
fz={{ base: 'sm', md: 'md' }}
>
WhatsApp
</Button>
@@ -108,4 +115,4 @@ function Page() {
);
}
export default Page;
export default Page;

View File

@@ -16,6 +16,7 @@ import {
Stack,
Text,
TextInput,
Title,
Tooltip
} from '@mantine/core';
import { useDebouncedValue, useShallowEffect } from '@mantine/hooks';
@@ -52,10 +53,21 @@ function Page() {
<Grid align="center" px={{ base: 'md', md: 100 }} gutter="lg">
<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
</Text>
<Text fz="md" mt={4}>
</Title>
<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
</Text>
</GridCol>
@@ -79,10 +91,20 @@ function Page() {
<Center mih={300}>
<Stack align="center" gap="xs">
<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
</Text>
<Text fz="sm" c="dimmed">
</Title>
<Text
fz={{ base: 'xs', md: 'sm' }}
lh={{ base: 1.4, md: 1.5 }}
c="dark.7"
>
Coba kata kunci lain untuk pencarian
</Text>
</Stack>
@@ -102,8 +124,8 @@ function Page() {
cursor: 'pointer',
display: 'flex',
flexDirection: 'column',
justifyContent: 'space-between', // ✅ biar button selalu di bawah
height: '100%', // ✅ bikin tinggi seragam
justifyContent: 'space-between',
height: '100%',
}}
>
<Stack align="center" gap="sm" style={{ flexGrow: 1 }}>
@@ -131,27 +153,24 @@ function Page() {
/>
</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}
</Text>
<Text
fz="sm"
fz={{ base: 'xs', md: 'sm' }}
ta="center"
lineClamp={3}
lh={1.6}
lh={{ base: 1.5, md: 1.6 }}
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 }}
/>
</Text>
dangerouslySetInnerHTML={{ __html: v.deskripsi }}
/>
</Stack>
{/* ✅ Tombol selalu di bagian bawah card */}
<Group mt="md" justify='center'>
<Button
bg={colors['blue-button']}
@@ -161,8 +180,6 @@ function Page() {
</Button>
</Group>
</Paper>
))}
</SimpleGrid>
)}
@@ -186,4 +203,4 @@ function Page() {
);
}
export default Page;
export default Page;

View File

@@ -1,7 +1,7 @@
'use client';
import penangananDarurat from '@/app/admin/(dashboard)/_state/kesehatan/penanganan-darurat/penangananDarurat';
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 { useParams } from 'next/navigation';
import { useProxy } from 'valtio/utils';
@@ -31,48 +31,55 @@ function DetailPenangananDaruratUser() {
<Box py={20}>
{/* Tombol Back */}
<Box px={{ base: 'md', md: 100 }}>
<BackButton/>
<BackButton />
</Box>
{/* Wrapper Detail */}
<Paper
withBorder
w={{ base: '100%', md: '70%', lg: '60%' }}
mx="auto"
bg={colors['white-1']}
p="xl"
radius="lg"
shadow="sm"
>
<Stack gap="md" align="center" ta="center">
<Text fz="xl" fw={700} c={colors['blue-button']}>
{data.name || 'Penanganan Darurat'}
</Text>
<Box pt={20} px={{ base: 'md', md: 100 }}>
<Paper
withBorder
w={'100%'}
bg={colors['white-1']}
p="xl"
radius="lg"
shadow="sm"
>
<Stack gap="md">
<Title
ta={"center"}
order={1}
fw={700}
c={colors['blue-button']}
style={{ wordBreak: 'break-word' }}
>
{data.name || 'Penanganan Darurat'}
</Title>
<Center>
{data.image?.link && (
<Image
src={data.image.link}
alt={data.name}
radius="md"
mah={300}
fit="contain"
loading="lazy"
mb="md"
/>
)}
</Center>
{data.image?.link && (
<Image
src={data.image.link}
alt={data.name}
radius="md"
mah={300}
fit="contain"
loading="lazy"
mb="md"
/>
)}
<Box>
<Text
fz="md"
ta="justify"
dangerouslySetInnerHTML={{ __html: data.deskripsi }}
style={{ wordBreak: 'break-word', whiteSpace: 'normal' }}
/>
</Box>
</Stack>
</Paper>
<Box >
<Text
ta="justify"
dangerouslySetInnerHTML={{ __html: data.deskripsi }}
style={{ wordBreak: 'break-word', whiteSpace: 'normal' }}
/>
</Box>
</Stack>
</Paper>
</Box>
</Box>
);
}
export default DetailPenangananDaruratUser;
export default DetailPenangananDaruratUser;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -59,12 +59,16 @@ function Page() {
left={20}
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}
</Text>
</Title>
<Group gap={6}>
<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}
</Text>
</Group>
@@ -75,37 +79,45 @@ function Page() {
<GridCol span={{ base: 12, md: 6 }}>
<Stack gap="lg">
<Box>
<Title order={3} mb={10}>Informasi Kontak</Title>
<Title order={2} mb="md">Informasi Kontak</Title>
<Stack gap={8}>
<Group gap={8}>
<IconPhone size={18} />
<Text fz="md">{data.kontak.kontakPuskesmas || '-'}</Text>
<Text fz={{ base: 'sm', md: 'md' }}>
{data.kontak.kontakPuskesmas || '-'}
</Text>
</Group>
<Group gap={8}>
<IconMail size={18} />
<Text fz="md">{data.kontak.email || '-'}</Text>
<Text fz={{ base: 'sm', md: 'md' }}>
{data.kontak.email || '-'}
</Text>
</Group>
</Stack>
</Box>
<Divider />
<Stack gap={"xs"}>
<Title order={3} mb={10}>Jam Operasional</Title>
<Text fw="bold" fz="md">Senin - Jumat</Text>
<Stack gap="xs">
<Title order={2} mb="md">Jam Operasional</Title>
<Text fw="bold" fz={{ base: 'sm', md: 'md' }}>Senin - Jumat</Text>
<Group gap={8}>
<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>
<Badge size="sm" variant="light" color="blue">Aktif</Badge>
</Tooltip>
</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}>
<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>
<Badge size="sm" variant="light" color="blue">Aktif</Badge>
<Badge size="sm" variant="light" color="blue">Aktif</Badge>
</Tooltip>
</Group>
</Stack>
@@ -114,20 +126,24 @@ function Page() {
<GridCol span={{ base: 12, md: 6 }}>
<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">
<Paper p="lg" radius="lg" withBorder bg={colors['white-trans-1']} shadow="xs">
<Stack align="center" gap={8}>
<IconBuildingHospital size={36} color={colors['blue-button']} />
<Text fw="bold" fz="lg">Poliklinik Umum</Text>
<Text fz={{ base: 36, md: 48 }} fw="bold" c={colors['blue-button']}>26</Text>
<Text fw="bold" fz={{ base: 'sm', md: 'md' }}>Poliklinik Umum</Text>
<Text fz={{ base: 'h1', md: 'h1' }} fw="bold" c={colors['blue-button']} lh={1}>
26
</Text>
</Stack>
</Paper>
<Paper p="lg" radius="lg" withBorder bg={colors['white-trans-1']} shadow="xs">
<Stack align="center" gap={8}>
<IconBuildingHospital size={36} color={colors['blue-button']} />
<Text fw="bold" fz="lg">Poli Gigi</Text>
<Text fz={{ base: 36, md: 48 }} fw="bold" c={colors['blue-button']}>26</Text>
<Text fw="bold" fz={{ base: 'sm', md: 'md' }}>Poli Gigi</Text>
<Text fz={{ base: 'h1', md: 'h1' }} fw="bold" c={colors['blue-button']} lh={1}>
26
</Text>
</Stack>
</Paper>
</SimpleGrid>
@@ -141,4 +157,4 @@ function Page() {
);
}
export default Page;
export default Page;

View File

@@ -1,7 +1,7 @@
'use client'
import puskesmasState from '@/app/admin/(dashboard)/_state/kesehatan/puskesmas/puskesmas';
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 { IconSearch, IconMapPin, IconPhone, IconMail } from '@tabler/icons-react';
import { useState } from 'react';
@@ -42,10 +42,10 @@ function Page() {
<Grid align="center" px={{ base: 'md', md: 100 }} mb="md">
<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
</Text>
<Text fz="md">
</Title>
<Text fz={{ base: "sm", md: "md" }} ta="start">
Temukan informasi lengkap mengenai layanan, kontak, dan lokasi Puskesmas Darmasaba
</Text>
</GridCol>
@@ -65,8 +65,8 @@ function Page() {
{data.length === 0 ? (
<Center py="xl">
<Stack align="center" gap="xs">
<Text fz="lg" fw={500} c="dimmed">Tidak ada data ditemukan</Text>
<Text fz="sm" c="dimmed">Coba gunakan kata kunci pencarian yang berbeda</Text>
<Title order={2} fw={500} c="dimmed">Tidak ada data ditemukan</Title>
<Text fz={{ base: "xs", md: "sm" }} c="dimmed">Coba gunakan kata kunci pencarian yang berbeda</Text>
</Stack>
</Center>
) : (
@@ -92,29 +92,29 @@ function Page() {
loading="lazy"
/>
<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>
</Group>
<Stack gap={6}>
<Group gap="xs" align="flex-start" wrap="nowrap">
<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 gap="xs" align="flex-start" wrap="nowrap">
<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 gap="xs" align="flex-start" wrap="nowrap">
<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>
</Stack>
<Anchor
href={`/darmasaba/kesehatan/puskesmas/${v.id}`}
fz="sm"
fz={{ base: "sm", md: "md" }}
fw={500}
c={colors['blue-button']}
>
@@ -143,4 +143,4 @@ function Page() {
);
}
export default Page;
export default Page;

View File

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