Fix UI User Menu PPID & Kesehatan
This commit is contained in:
@@ -1,62 +1,95 @@
|
||||
/* eslint-disable react-hooks/exhaustive-deps */
|
||||
"use client";
|
||||
|
||||
import stateLayananDesa from '@/app/admin/(dashboard)/_state/desa/layananDesa';
|
||||
import colors from '@/con/colors';
|
||||
import { ActionIcon, Box, Divider, Flex, Skeleton, Text } from '@mantine/core';
|
||||
import { ActionIcon, Box, Divider, Flex, Group, Skeleton, Stack, Text, Tooltip } from '@mantine/core';
|
||||
import { IconBrandFacebook, IconBrandInstagram, IconBrandTwitter, IconBrandWhatsapp } from '@tabler/icons-react';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { useProxy } from 'valtio/utils';
|
||||
|
||||
function PelayananPendudukNonPermanent() {
|
||||
const state = useProxy(stateLayananDesa)
|
||||
const [loading, setLoading] = useState(false)
|
||||
const state = useProxy(stateLayananDesa);
|
||||
const [loading, setLoading] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
const loadData = async () => {
|
||||
try {
|
||||
setLoading(true)
|
||||
await state.pelayananPendudukNonPermanen.findById.load('1')
|
||||
setLoading(true);
|
||||
await state.pelayananPendudukNonPermanen.findById.load('1');
|
||||
} catch (error) {
|
||||
console.error('Error loading data:', error);
|
||||
console.error('Gagal memuat data:', error);
|
||||
} finally {
|
||||
setLoading(false)
|
||||
setLoading(false);
|
||||
}
|
||||
}
|
||||
loadData()
|
||||
}, [])
|
||||
};
|
||||
loadData();
|
||||
}, []);
|
||||
|
||||
const data = state.pelayananPendudukNonPermanen.findById.data;
|
||||
|
||||
const data = state.pelayananPendudukNonPermanen.findById.data
|
||||
return (
|
||||
<Box>
|
||||
<Box py="lg">
|
||||
{loading ? (
|
||||
<Skeleton h={500} />
|
||||
<Stack gap="lg">
|
||||
<Skeleton height={40} radius="md" />
|
||||
<Skeleton height={200} radius="md" />
|
||||
<Skeleton height={30} radius="md" />
|
||||
</Stack>
|
||||
) : (
|
||||
<Box>
|
||||
<Box py={15}>
|
||||
<Text fz={{ base: "h4", md: "h3" }} fw={"bold"}>{data?.name}</Text>
|
||||
<Stack gap="xl">
|
||||
<Box>
|
||||
<Text fz={{ base: "xl", md: "2xl" }} fw={700} lh={1.3} c="dark">
|
||||
{data?.name || "Judul belum tersedia"}
|
||||
</Text>
|
||||
</Box>
|
||||
<Text pb={20} fz={{ base: "sm", md: 'h3' }} ta={"justify"} dangerouslySetInnerHTML={{__html: data?.deskripsi || ''}} />
|
||||
<Divider color={colors["blue-button"]} />
|
||||
<Flex justify={"space-between"} py={20}>
|
||||
<Text fz={{ base: "sm", md: 'h3' }}>25 May 2021 . Darmasaba</Text>
|
||||
<Box>
|
||||
<Flex gap={"lg"}>
|
||||
<ActionIcon variant='transparent'>
|
||||
<IconBrandFacebook color={colors["blue-button"]} size={"30"} />
|
||||
|
||||
<Box>
|
||||
{data?.deskripsi ? (
|
||||
<Text
|
||||
fz={{ base: "sm", md: "md" }}
|
||||
lh={1.7}
|
||||
ta="justify"
|
||||
c="dimmed"
|
||||
dangerouslySetInnerHTML={{ __html: data?.deskripsi }}
|
||||
/>
|
||||
) : (
|
||||
<Text fz="sm" c="gray">Deskripsi belum tersedia.</Text>
|
||||
)}
|
||||
</Box>
|
||||
|
||||
<Divider color={colors["blue-button"]} size="sm" />
|
||||
|
||||
<Flex justify="space-between" align="center" wrap="wrap" gap="md">
|
||||
<Text fz={{ base: "xs", md: "sm" }} c="dimmed">
|
||||
25 Mei 2021 • Darmasaba
|
||||
</Text>
|
||||
<Group gap="md">
|
||||
<Tooltip label="Bagikan ke Facebook" withArrow>
|
||||
<ActionIcon size="lg" radius="xl" variant="subtle" color="blue">
|
||||
<IconBrandFacebook size={24} />
|
||||
</ActionIcon>
|
||||
<ActionIcon variant='transparent'>
|
||||
<IconBrandInstagram color={colors["blue-button"]} size={"30"} />
|
||||
</Tooltip>
|
||||
<Tooltip label="Bagikan ke Instagram" withArrow>
|
||||
<ActionIcon size="lg" radius="xl" variant="subtle" color="pink">
|
||||
<IconBrandInstagram size={24} />
|
||||
</ActionIcon>
|
||||
<ActionIcon variant='transparent'>
|
||||
<IconBrandTwitter color={colors["blue-button"]} size={"30"} />
|
||||
</Tooltip>
|
||||
<Tooltip label="Bagikan ke Twitter" withArrow>
|
||||
<ActionIcon size="lg" radius="xl" variant="subtle" color="blue">
|
||||
<IconBrandTwitter size={24} />
|
||||
</ActionIcon>
|
||||
<ActionIcon variant='transparent'>
|
||||
<IconBrandWhatsapp color={colors["blue-button"]} size={"30"} />
|
||||
</Tooltip>
|
||||
<Tooltip label="Bagikan ke WhatsApp" withArrow>
|
||||
<ActionIcon size="lg" radius="xl" variant="subtle" color="green">
|
||||
<IconBrandWhatsapp size={24} />
|
||||
</ActionIcon>
|
||||
</Flex>
|
||||
</Box>
|
||||
</Tooltip>
|
||||
</Group>
|
||||
</Flex>
|
||||
<Divider color={colors["blue-button"]} pb={50} />
|
||||
</Box>
|
||||
|
||||
<Divider color={colors["blue-button"]} size="sm" />
|
||||
</Stack>
|
||||
)}
|
||||
</Box>
|
||||
);
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
/* eslint-disable react-hooks/exhaustive-deps */
|
||||
'use client'
|
||||
import stateLayananDesa from '@/app/admin/(dashboard)/_state/desa/layananDesa';
|
||||
import { Box, Button, Center, Group, Skeleton, Stepper, StepperCompleted, StepperStep, Text } from '@mantine/core';
|
||||
import { Box, Button, Center, Group, Loader, Stack, Stepper, StepperCompleted, StepperStep, Text, Title } from '@mantine/core';
|
||||
import { IconArrowLeft, IconArrowRight, IconCheck } from '@tabler/icons-react';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { useProxy } from 'valtio/utils';
|
||||
|
||||
@@ -18,7 +19,7 @@ function PelayananPerizinanBerusaha() {
|
||||
setLoading(true);
|
||||
await state.pelayananPerizinanBerusaha.findById.load('1')
|
||||
} catch (error) {
|
||||
console.error('Error loading data:', error);
|
||||
console.error('Gagal memuat data:', error);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
@@ -28,76 +29,87 @@ function PelayananPerizinanBerusaha() {
|
||||
|
||||
const data = state.pelayananPerizinanBerusaha.findById.data;
|
||||
|
||||
if (!data) {
|
||||
if (!data && !loading) {
|
||||
return (
|
||||
<Center>
|
||||
<Text>Data tidak tersedia</Text>
|
||||
<Center mih={300}>
|
||||
<Stack align="center" gap="sm">
|
||||
<Text fz="lg" fw={500} c="dimmed">Belum ada informasi layanan yang tersedia</Text>
|
||||
<Button component="a" href="https://oss.go.id" target="_blank" radius="xl">Kunjungi OSS</Button>
|
||||
</Stack>
|
||||
</Center>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Box>
|
||||
<Box px={{ base: 'md', md: 'xl' }} py="lg">
|
||||
{loading ? (
|
||||
<Center>
|
||||
<Skeleton h={250} />
|
||||
<Center mih={300}>
|
||||
<Loader size="lg" color="blue" />
|
||||
</Center>
|
||||
) : (
|
||||
<Box>
|
||||
<Box py={15}>
|
||||
<Text fz={{ base: "h4", md: 'h2' }} fw={"bold"}>Pelayanan Perizinan Berusaha Berbasis Risiko Melalui Sistem ONLINE SINGLE SUBMISSION (OSS)</Text>
|
||||
</Box>
|
||||
<Text
|
||||
py={10}
|
||||
ta={"justify"}
|
||||
fz={{ base: "sm", md: 'h3' }}
|
||||
dangerouslySetInnerHTML={{ __html: data.deskripsi || '' }}
|
||||
/>
|
||||
<Text py={10} fz={{ base: "sm", md: 'h3' }}>Proses pendaftaran NIB melalui OSS mencakup beberapa langkah umum, seperti:</Text>
|
||||
<Box p={"xl"} w={{ base: "100%", md: "100%" }}>
|
||||
<Stepper active={active} onStepClick={setActive} orientation="vertical"
|
||||
styles={{
|
||||
separator: {
|
||||
marginLeft: 25
|
||||
},
|
||||
step: {
|
||||
padding: '12px 0'
|
||||
}
|
||||
}}>
|
||||
<StepperStep label="Langkah Pertama" description="Pendaftaran Akun">
|
||||
Pendaftaran akun pada portal OSS
|
||||
</StepperStep>
|
||||
<StepperStep label="Langkah Kedua" description="Pengisian Data Perusahaan">
|
||||
Mengisi informasi perusahaan, termasuk data pemegang saham, alamat perusahaan, dan lainnya
|
||||
</StepperStep>
|
||||
<StepperStep label="Langkah Ketiga" description="Pemilihan KBLI">
|
||||
Memilih KBLI dengan jenis usaha yang akan didaftarkan
|
||||
</StepperStep>
|
||||
<StepperStep label="Langkah Keempat" description="Pengunggahan Dokumen">
|
||||
Mengunggah dokumen-dokumen yang diperlukan, seperti akta pendirian perusahaan, surat izin usaha, dan dokumen lainnya sesuai dengan ketentuan yang berlaku
|
||||
</StepperStep>
|
||||
<StepperStep label="Langkah Kelima" description="Verifikasi dan Persetujuan">
|
||||
Proses verifikasi dan persetujuan oleh instansi terkait
|
||||
</StepperStep>
|
||||
<StepperStep label="Langkah Keenam" description="Penerimaan NIB">
|
||||
Jika proses sebelumnya berhasil, perusahaan akan menerima NIB sebagai identitas resmi usaha anda
|
||||
</StepperStep>
|
||||
<StepperCompleted>
|
||||
Selesai, anda telah mengikuti proses pendaftaran NIB melalui OSS
|
||||
</StepperCompleted>
|
||||
</Stepper>
|
||||
<Stack gap="lg">
|
||||
<Box>
|
||||
<Title order={2} fw={700} fz={{ base: 22, md: 32 }} mb="sm">
|
||||
Perizinan Berusaha Berbasis Risiko melalui OSS
|
||||
</Title>
|
||||
<Text fz={{ base: 'sm', md: 'md' }} c="dimmed">
|
||||
Sistem Online Single Submission (OSS) untuk pendaftaran NIB
|
||||
</Text>
|
||||
</Box>
|
||||
|
||||
<Group justify="center" mt="xl">
|
||||
<Button variant="default" onClick={prevStep}>Back</Button>
|
||||
<Button onClick={nextStep}>Next step</Button>
|
||||
</Group>
|
||||
<Text py={35} ta={"justify"} fz={{ base: "sm", md: 'h3' }}>
|
||||
Penting untuk diingat bahwa prosedur dan persyaratan dapat berubah
|
||||
seiring waktu. Untuk informasi yang lebih akurat dan terkini, saya sarankan untuk mengunjungi situs
|
||||
resmi OSS <a href="https://oss.go.id/" target="_blank" rel="noopener noreferrer">(https://oss.go.id/)</a> atau menghubungi instansi terkait di pemerintah Indonesia yang bertanggung jawab atas urusan perizinan usaha.
|
||||
<Text fz={{ base: 'sm', md: 'md' }} ta="justify" dangerouslySetInnerHTML={{ __html: data?.deskripsi || '' }} />
|
||||
|
||||
<Box>
|
||||
<Text fw={600} mb="sm" fz={{ base: 'sm', md: 'lg' }}>Alur pendaftaran NIB:</Text>
|
||||
<Stepper active={active} onStepClick={setActive} orientation="vertical" color="blue" radius="md"
|
||||
styles={{
|
||||
step: { padding: '14px 0' },
|
||||
stepBody: { marginLeft: 8 }
|
||||
}}
|
||||
>
|
||||
<StepperStep label="Langkah 1" description="Daftar Akun">
|
||||
<Text fz="sm">Membuat akun di portal OSS</Text>
|
||||
</StepperStep>
|
||||
<StepperStep label="Langkah 2" description="Isi Data Perusahaan">
|
||||
<Text fz="sm">Lengkapi informasi perusahaan, data pemegang saham, dan alamat</Text>
|
||||
</StepperStep>
|
||||
<StepperStep label="Langkah 3" description="Pilih KBLI">
|
||||
<Text fz="sm">Menentukan kode KBLI sesuai jenis usaha</Text>
|
||||
</StepperStep>
|
||||
<StepperStep label="Langkah 4" description="Unggah Dokumen">
|
||||
<Text fz="sm">Unggah akta pendirian, surat izin, dan dokumen wajib lainnya</Text>
|
||||
</StepperStep>
|
||||
<StepperStep label="Langkah 5" description="Verifikasi Instansi">
|
||||
<Text fz="sm">Menunggu verifikasi dan persetujuan dari pihak berwenang</Text>
|
||||
</StepperStep>
|
||||
<StepperStep label="Langkah 6" description="Terbit NIB">
|
||||
<Text fz="sm">Menerima NIB sebagai identitas resmi usaha</Text>
|
||||
</StepperStep>
|
||||
<StepperCompleted>
|
||||
<Center>
|
||||
<Stack align="center" gap="xs">
|
||||
<IconCheck size={40} color="green" />
|
||||
<Text fz="sm" fw={500}>Proses pendaftaran selesai</Text>
|
||||
</Stack>
|
||||
</Center>
|
||||
</StepperCompleted>
|
||||
</Stepper>
|
||||
|
||||
<Group justify="center" mt="lg">
|
||||
<Button variant="light" leftSection={<IconArrowLeft size={18} />} onClick={prevStep} disabled={active === 0}>
|
||||
Kembali
|
||||
</Button>
|
||||
<Button rightSection={<IconArrowRight size={18} />} onClick={nextStep}>
|
||||
Lanjut
|
||||
</Button>
|
||||
</Group>
|
||||
</Box>
|
||||
|
||||
<Text fz="sm" ta="justify" c="dimmed" mt="md">
|
||||
Catatan: Persyaratan dan prosedur dapat berubah sewaktu-waktu. Untuk informasi resmi terbaru, silakan kunjungi situs{" "}
|
||||
<a href="https://oss.go.id/" target="_blank" rel="noopener noreferrer">oss.go.id</a> atau hubungi instansi pemerintah terkait.
|
||||
</Text>
|
||||
</Box>
|
||||
</Box>
|
||||
</Stack>
|
||||
)}
|
||||
</Box>
|
||||
);
|
||||
|
||||
@@ -1,96 +1,124 @@
|
||||
/* eslint-disable react-hooks/exhaustive-deps */
|
||||
"use client";
|
||||
|
||||
import stateLayananDesa from '@/app/admin/(dashboard)/_state/desa/layananDesa';
|
||||
import colors from '@/con/colors';
|
||||
import { BackgroundImage, Box, Button, Center, Group, SimpleGrid, Skeleton, Stack, Text } from '@mantine/core';
|
||||
import { BackgroundImage, Box, Button, Center, Group, SimpleGrid, Skeleton, Stack, Text, Tooltip } from '@mantine/core';
|
||||
import { IconFileDescription, IconInfoCircle } from '@tabler/icons-react';
|
||||
import { useRouter } from 'next/navigation';
|
||||
import React, { useEffect, useMemo, useState } from 'react';
|
||||
|
||||
import { useProxy } from 'valtio/utils';
|
||||
|
||||
function PelayananSuratKeterangan({ search }: { search: string }) {
|
||||
const [loading, setLoading] = useState(false);
|
||||
const router = useRouter()
|
||||
const state = useProxy(stateLayananDesa)
|
||||
const router = useRouter();
|
||||
const state = useProxy(stateLayananDesa);
|
||||
|
||||
const filteredData = useMemo(() => {
|
||||
if (!state.suratKeterangan.findMany.data) return [];
|
||||
return state.suratKeterangan.findMany.data.filter(item => {
|
||||
return state.suratKeterangan.findMany.data.filter((item) => {
|
||||
const keyword = search.toLowerCase();
|
||||
return (
|
||||
item.name?.toLowerCase().includes(keyword)
|
||||
);
|
||||
})
|
||||
return item.name?.toLowerCase().includes(keyword);
|
||||
});
|
||||
}, [state.suratKeterangan.findMany.data, search]);
|
||||
|
||||
useEffect(() => {
|
||||
const loadData = async () => {
|
||||
try {
|
||||
setLoading(true);
|
||||
await state.suratKeterangan.findMany.load()
|
||||
await state.suratKeterangan.findMany.load();
|
||||
} catch (error) {
|
||||
console.error('Error loading data:', error);
|
||||
console.error('Gagal memuat data:', error);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
}
|
||||
loadData()
|
||||
}, [])
|
||||
};
|
||||
loadData();
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<Box pb={10}>
|
||||
<Text fz={{ base: "h4", md: 'h2' }} fw={"bold"}>Pelayanan Surat Keterangan</Text>
|
||||
<Box pb="xl">
|
||||
<Group justify="space-between" align="center" mb="md">
|
||||
<Group gap="xs">
|
||||
<IconFileDescription size={28} stroke={1.8} color={colors["blue-button"]} />
|
||||
<Text fz={{ base: "h4", md: "h2" }} fw={700}>
|
||||
Layanan Surat Keterangan
|
||||
</Text>
|
||||
</Group>
|
||||
<Tooltip label="Pilih layanan surat keterangan sesuai kebutuhan Anda" withArrow>
|
||||
<IconInfoCircle size={22} stroke={1.8} color={colors["blue-button"]} />
|
||||
</Tooltip>
|
||||
</Group>
|
||||
|
||||
<SimpleGrid
|
||||
py={20}
|
||||
cols={{
|
||||
base: 1,
|
||||
sm: 3
|
||||
}}
|
||||
py="lg"
|
||||
cols={{ base: 1, sm: 2, md: 3 }}
|
||||
spacing="lg"
|
||||
>
|
||||
{loading ? (
|
||||
<Center>
|
||||
<Skeleton h={250} />
|
||||
Array.from({ length: 3 }).map((_, i) => (
|
||||
<Skeleton key={i} h={250} radius="lg" />
|
||||
))
|
||||
) : filteredData.length === 0 ? (
|
||||
<Center py="xl">
|
||||
<Stack align="center" gap="xs">
|
||||
<IconFileDescription size={40} stroke={1.5} color={colors["blue-button"]} />
|
||||
<Text c="dimmed" ta="center">
|
||||
Tidak ada layanan surat keterangan yang ditemukan
|
||||
</Text>
|
||||
</Stack>
|
||||
</Center>
|
||||
) : (
|
||||
filteredData.map((v, k) => {
|
||||
return (
|
||||
<BackgroundImage
|
||||
key={k}
|
||||
src={v.image?.link || ''}
|
||||
h={250}
|
||||
radius={16}
|
||||
pos={"relative"}
|
||||
>
|
||||
<Box
|
||||
style={{
|
||||
borderRadius: 16,
|
||||
zIndex: 0
|
||||
}}
|
||||
pos={"absolute"}
|
||||
w={"100%"}
|
||||
h={"100%"}
|
||||
bg={colors.trans.dark[2]}
|
||||
/>
|
||||
<Stack justify='space-between' h={"100%"} gap={0} p={"lg"} pos={"relative"}>
|
||||
<Box p={"lg"}>
|
||||
<Text
|
||||
c={"white"}
|
||||
size={"1.5rem"}
|
||||
style={{
|
||||
textAlign: "center",
|
||||
}}>{v.name}</Text>
|
||||
</Box>
|
||||
<Group justify="center">
|
||||
<Button px={20} radius={"100"} size="md" bg={colors["blue-button"]}
|
||||
onClick={() => router.push(`/darmasaba/desa/layanan/${v.id}`)}>
|
||||
Detail
|
||||
</Button>
|
||||
</Group>
|
||||
</Stack>
|
||||
</BackgroundImage>
|
||||
)
|
||||
})
|
||||
filteredData.map((v, k) => (
|
||||
<BackgroundImage
|
||||
key={k}
|
||||
src={v.image?.link || ''}
|
||||
h={250}
|
||||
radius="lg"
|
||||
pos="relative"
|
||||
style={{
|
||||
boxShadow: "0 4px 20px rgba(0,0,0,0.1)",
|
||||
overflow: "hidden",
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
pos="absolute"
|
||||
w="100%"
|
||||
h="100%"
|
||||
bg="rgba(0,0,0,0.45)"
|
||||
style={{ borderRadius: 16 }}
|
||||
/>
|
||||
<Stack justify="space-between" h="100%" gap="md" p="lg" pos="relative">
|
||||
<Text
|
||||
c="white"
|
||||
fw={600}
|
||||
fz="lg"
|
||||
ta="center"
|
||||
lineClamp={2}
|
||||
>
|
||||
{v.name}
|
||||
</Text>
|
||||
<Group justify="center">
|
||||
<Button
|
||||
size="md"
|
||||
radius="xl"
|
||||
bg={colors["blue-button"]}
|
||||
px="lg"
|
||||
onClick={() => router.push(`/darmasaba/desa/layanan/${v.id}`)}
|
||||
style={{
|
||||
boxShadow: "0 0 12px rgba(59,130,246,0.6)",
|
||||
transition: "all 0.2s ease",
|
||||
}}
|
||||
>
|
||||
Lihat Detail
|
||||
</Button>
|
||||
</Group>
|
||||
</Stack>
|
||||
</BackgroundImage>
|
||||
))
|
||||
)}
|
||||
</SimpleGrid>
|
||||
</Box>
|
||||
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/* eslint-disable react-hooks/exhaustive-deps */
|
||||
import stateLayananDesa from '@/app/admin/(dashboard)/_state/desa/layananDesa';
|
||||
import { Box, Flex, Skeleton, Text, Title } from '@mantine/core';
|
||||
import { Box, Card, Flex, Grid, Skeleton, Stack, Text, Title } from '@mantine/core';
|
||||
import { IconExternalLink } from '@tabler/icons-react';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { useProxy } from 'valtio/utils';
|
||||
|
||||
@@ -11,22 +12,22 @@ interface ServiceItem {
|
||||
}
|
||||
|
||||
function PelayananTelunjukSaktiDesa() {
|
||||
const state = useProxy(stateLayananDesa)
|
||||
const [loading, setLoading] = useState(false)
|
||||
const state = useProxy(stateLayananDesa);
|
||||
const [loading, setLoading] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
const loadData = async () => {
|
||||
try {
|
||||
setLoading(true)
|
||||
await state.pelayananTelunjukSaktiDesa.findMany.load()
|
||||
setLoading(true);
|
||||
await state.pelayananTelunjukSaktiDesa.findMany.load();
|
||||
} catch (error) {
|
||||
console.error('Error loading data:', error);
|
||||
console.error('Gagal memuat data:', error);
|
||||
} finally {
|
||||
setLoading(false)
|
||||
setLoading(false);
|
||||
}
|
||||
}
|
||||
loadData()
|
||||
}, [])
|
||||
};
|
||||
loadData();
|
||||
}, []);
|
||||
|
||||
const data = (state.pelayananTelunjukSaktiDesa.findMany.data || []) as Array<{
|
||||
name: string;
|
||||
@@ -37,28 +38,63 @@ function PelayananTelunjukSaktiDesa() {
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
deletedAt: Date | null;
|
||||
}>
|
||||
}>;
|
||||
|
||||
return (
|
||||
<Box>
|
||||
<Title fz="h2" py={10} mb="md">Terwujudnya Layanan umum bertajuk Sistim administrasi Kependudukan Terintegrasi di Desa berbasi Elektronik, Smart dan Aman. Layanan Telunjuk Sakti Desa meliputi :</Title>
|
||||
<Title order={2} mb="lg" fz={{ base: 22, md: 28 }} fw={700} style={{ lineHeight: 1.4 }}>
|
||||
Layanan Telunjuk Sakti Desa <br />
|
||||
<Text span c="dimmed" fz="lg" fw={400}>
|
||||
Terwujudnya sistem administrasi kependudukan terintegrasi berbasis elektronik, cerdas, dan aman
|
||||
</Text>
|
||||
</Title>
|
||||
|
||||
{loading ? (
|
||||
<Skeleton h={500} />
|
||||
<Skeleton h={400} radius="lg" />
|
||||
) : data.length === 0 ? (
|
||||
<Card shadow="sm" radius="lg" withBorder>
|
||||
<Text c="dimmed" ta="center" py="xl">
|
||||
Belum ada layanan tersedia untuk saat ini
|
||||
</Text>
|
||||
</Card>
|
||||
) : (
|
||||
data.map((v, k) => {
|
||||
return (
|
||||
<Box key={k}>
|
||||
<Box py={10}>
|
||||
<Flex gap={"3"} align={"center"}>
|
||||
<Text fz={{ base: "h4", md: "h3" }} fw={"bold"}>{v.name}
|
||||
<Grid gutter="lg">
|
||||
{data.map((v, k) => (
|
||||
<Grid.Col span={{ base: 12, sm: 6, lg: 4 }} key={k}>
|
||||
<Card
|
||||
shadow="md"
|
||||
radius="xl"
|
||||
withBorder
|
||||
p="lg"
|
||||
style={{
|
||||
transition: 'all 0.3s ease',
|
||||
background: 'linear-gradient(145deg, #ffffff, #f8f9fa)',
|
||||
}}
|
||||
>
|
||||
<Stack gap="sm">
|
||||
<Text fw={700} fz="lg" lh={1.4}>
|
||||
{v.name}
|
||||
</Text>
|
||||
<Text span fz={{ base: "h4", md: "h3" }}>
|
||||
<a href={v.link} target="_blank" rel="noopener noreferrer" style={{ color: '#228be6' }}>{v.deskripsi}</a>
|
||||
</Text>
|
||||
</Flex>
|
||||
</Box>
|
||||
</Box>
|
||||
)
|
||||
})
|
||||
<Flex gap="xs" align="center">
|
||||
<IconExternalLink size={18} stroke={1.5} />
|
||||
<Text
|
||||
component="a"
|
||||
href={v.link}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
fz="sm"
|
||||
c="blue"
|
||||
td="underline"
|
||||
style={{ cursor: 'pointer' }}
|
||||
>
|
||||
{v.deskripsi}
|
||||
</Text>
|
||||
</Flex>
|
||||
</Stack>
|
||||
</Card>
|
||||
</Grid.Col>
|
||||
))}
|
||||
</Grid>
|
||||
)}
|
||||
</Box>
|
||||
);
|
||||
|
||||
@@ -12,7 +12,7 @@ import PelayananPendudukNonPermanent from "./_com/pelayananPendudukNonPermanent"
|
||||
|
||||
export default function Page() {
|
||||
const [search, setSearch] = useState("")
|
||||
|
||||
|
||||
|
||||
return (
|
||||
<Stack pos={"relative"} bg={colors.Bg} py={"xl"} gap={"22"}>
|
||||
@@ -40,14 +40,16 @@ export default function Page() {
|
||||
</Stack>
|
||||
</Container>
|
||||
<Box px={{ base: "md", md: 100 }}>
|
||||
{/* Bagian Pelayanan Surat Keterangan */}
|
||||
<PelayananSuratKeterangan search={search} />
|
||||
{/* Bagian Pelayanan Perizinan Berusaha */}
|
||||
<PelayananPerizinanBerusaha/>
|
||||
{/* Bagian Pelayanan Telunjuk Sakti Desa */}
|
||||
<PelayananTelunjukSaktiDesa/>
|
||||
{/* Bagian Pelayanan Penduduk Non Permanent */}
|
||||
<PelayananPendudukNonPermanent/>
|
||||
<Stack gap={"xl"}>
|
||||
{/* Bagian Pelayanan Surat Keterangan */}
|
||||
<PelayananSuratKeterangan search={search} />
|
||||
{/* Bagian Pelayanan Perizinan Berusaha */}
|
||||
<PelayananPerizinanBerusaha />
|
||||
{/* Bagian Pelayanan Telunjuk Sakti Desa */}
|
||||
<PelayananTelunjukSaktiDesa />
|
||||
{/* Bagian Pelayanan Penduduk Non Permanent */}
|
||||
<PelayananPendudukNonPermanent />
|
||||
</Stack>
|
||||
</Box>
|
||||
</Stack>
|
||||
)
|
||||
|
||||
@@ -2,18 +2,18 @@
|
||||
'use client'
|
||||
import potensiDesaState from '@/app/admin/(dashboard)/_state/desa/potensi';
|
||||
import colors from '@/con/colors';
|
||||
import { Box, Center, Container, Image, Skeleton, Stack, Text } from '@mantine/core';
|
||||
import { Box, Center, Container, Image, Loader, Paper, Stack, Text, Title } from '@mantine/core';
|
||||
import { IconMoodSad } from '@tabler/icons-react';
|
||||
import { useParams } from 'next/navigation';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { useProxy } from 'valtio/utils';
|
||||
import BackButton from '../../layanan/_com/BackButto';
|
||||
|
||||
|
||||
function Page() {
|
||||
const params = useParams<{ id: string }>();
|
||||
const id = Array.isArray(params.id) ? params.id[0] : params.id;
|
||||
const state = useProxy(potensiDesaState.potensiDesa)
|
||||
const [loading, setLoading] = useState(true)
|
||||
const state = useProxy(potensiDesaState.potensiDesa);
|
||||
const [loading, setLoading] = useState(true);
|
||||
|
||||
useEffect(() => {
|
||||
const loadData = async () => {
|
||||
@@ -22,54 +22,66 @@ function Page() {
|
||||
setLoading(true);
|
||||
await state.findUnique.load(id);
|
||||
} catch (error) {
|
||||
console.error('Error loading data:', error);
|
||||
console.error('Gagal memuat data:', error);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
}
|
||||
loadData()
|
||||
}, [id])
|
||||
};
|
||||
loadData();
|
||||
}, [id]);
|
||||
|
||||
if (loading) {
|
||||
return (
|
||||
<Center>
|
||||
<Skeleton height={500} />
|
||||
<Center h="80vh">
|
||||
<Stack align="center" gap="md">
|
||||
<Loader size="lg" color="blue" />
|
||||
<Text c="dimmed" fz="sm">Sedang memuat informasi...</Text>
|
||||
</Stack>
|
||||
</Center>
|
||||
);
|
||||
}
|
||||
|
||||
if (!state.findUnique.data) {
|
||||
return (
|
||||
<Center>
|
||||
<Text>Data tidak ditemukan</Text>
|
||||
<Center h="80vh">
|
||||
<Stack align="center" gap="sm">
|
||||
<IconMoodSad size={64} stroke={1.5} color="var(--mantine-color-blue-6)" />
|
||||
<Title order={3}>Data Tidak Ditemukan</Title>
|
||||
<Text c="dimmed" fz="sm">Mohon periksa kembali atau coba beberapa saat lagi</Text>
|
||||
</Stack>
|
||||
</Center>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
return (
|
||||
<Stack pos={"relative"} bg={colors.Bg} py={"xl"} gap={"22"} px={{ base: "md", md: 0 }}>
|
||||
<Box px={{ base: "md", md: 100 }}><BackButton /></Box>
|
||||
<Container w={{ base: "100%", md: "50%" }} >
|
||||
<Box pb={20}>
|
||||
<Text ta={"center"} fz={"3.4rem"} c={colors["blue-button"]} fw={"bold"}>
|
||||
{state.findUnique.data?.name}
|
||||
</Text>
|
||||
<Text
|
||||
ta={"center"}
|
||||
fw={"bold"}
|
||||
fz={"1.5rem"}
|
||||
>
|
||||
Informasi dan Pelayanan Administrasi Digital
|
||||
</Text>
|
||||
</Box>
|
||||
<Image src={state.findUnique.data?.image?.link || ''} alt='' w={"100%"} />
|
||||
</Container>
|
||||
<Stack pos="relative" bg={colors.Bg} py="xl" gap="xl" px={{ base: "md", md: 0 }}>
|
||||
<Box px={{ base: "md", md: 100 }}>
|
||||
<Text py={20} fz={{ base: "sm", md: "lg" }} ta={"justify"}>
|
||||
{state.findUnique.data?.deskripsi || ''}
|
||||
</Text>
|
||||
<BackButton />
|
||||
</Box>
|
||||
<Container w={{ base: "100%", md: "60%" }}>
|
||||
<Paper radius="2xl" shadow="lg" p="xl" withBorder>
|
||||
<Stack gap="lg" align="center">
|
||||
<Title ta="center" fz={{ base: "2rem", md: "3rem" }} c={colors["blue-button"]} fw={800}>
|
||||
{state.findUnique.data?.name}
|
||||
</Title>
|
||||
<Text ta="center" fw={600} fz={{ base: "md", md: "lg" }} c="dimmed">
|
||||
Informasi & Pelayanan Potensi Desa Digital
|
||||
</Text>
|
||||
<Image
|
||||
src={state.findUnique.data?.image?.link || ''}
|
||||
alt={state.findUnique.data?.name || 'Potensi Desa'}
|
||||
radius="lg"
|
||||
fit="cover"
|
||||
w="100%"
|
||||
h={{ base: 220, md: 400 }}
|
||||
fallbackSrc="https://placehold.co/800x400?text=Gambar+tidak+tersedia"
|
||||
/>
|
||||
<Text py="md" fz={{ base: "sm", md: "md" }} ta="justify" lh={1.8}>
|
||||
{state.findUnique.data?.deskripsi || 'Belum ada deskripsi untuk potensi desa ini.'}
|
||||
</Text>
|
||||
</Stack>
|
||||
</Paper>
|
||||
</Container>
|
||||
</Stack>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,27 +1,27 @@
|
||||
/* eslint-disable react-hooks/exhaustive-deps */
|
||||
'use client'
|
||||
import potensiDesaState from '@/app/admin/(dashboard)/_state/desa/potensi';
|
||||
import colors from '@/con/colors';
|
||||
import { BackgroundImage, Box, Button, Center, Flex, Group, Paper, SimpleGrid, Skeleton, Stack, Text } from '@mantine/core';
|
||||
import { BackgroundImage, Box, Button, Center, Flex, Group, Paper, SimpleGrid, Skeleton, Stack, Text, Tooltip } from '@mantine/core';
|
||||
import { IconEye } from '@tabler/icons-react';
|
||||
import { useTransitionRouter } from 'next-view-transitions';
|
||||
import BackButton from '../layanan/_com/BackButto';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { useProxy } from 'valtio/utils';
|
||||
import potensiDesaState from '@/app/admin/(dashboard)/_state/desa/potensi';
|
||||
|
||||
import BackButton from '../layanan/_com/BackButto';
|
||||
|
||||
function Page() {
|
||||
const router = useTransitionRouter()
|
||||
const [loading, setLoading] = useState(false)
|
||||
const state = useProxy(potensiDesaState)
|
||||
|
||||
useEffect(()=> {
|
||||
useEffect(() => {
|
||||
state.kategoriPotensi.findMany.load()
|
||||
const loadData = async () => {
|
||||
try {
|
||||
setLoading(true)
|
||||
await state.potensiDesa.findMany.load()
|
||||
} catch (error) {
|
||||
console.error('Error loading data:', error);
|
||||
console.error('Gagal memuat data:', error);
|
||||
} finally {
|
||||
setLoading(false)
|
||||
}
|
||||
@@ -30,104 +30,121 @@ function Page() {
|
||||
}, [])
|
||||
|
||||
const data = state.potensiDesa.findMany.data
|
||||
// const kategoriData = state.kategoriPotensi.findMany.data
|
||||
|
||||
return (
|
||||
<Stack pos={"relative"} bg={colors.Bg} py={"xl"} gap={"22"} >
|
||||
<Stack pos="relative" bg={colors.Bg} py="xl" gap={48}>
|
||||
<Box px={{ base: "md", md: 100 }}>
|
||||
<BackButton />
|
||||
</Box>
|
||||
|
||||
<Box px={{ base: "md", md: 100 }}>
|
||||
<Box>
|
||||
<Stack gap={0}>
|
||||
<Flex justify={"space-between"} align={"center"} >
|
||||
<Flex justify="space-between" align="center" direction={{ base: "column", md: "row" }} gap="lg">
|
||||
<Stack gap="sm" maw={600}>
|
||||
<Text fz={{ base: "2rem", md: "3rem" }} fw={900} c={colors["blue-button"]} lh={1.2}>
|
||||
Potensi Desa Darmasaba
|
||||
</Text>
|
||||
<Text fz="lg" c="dimmed" ta="justify">
|
||||
Temukan berbagai potensi unggulan, peluang, dan daya tarik yang menjadikan Desa Darmasaba istimewa.
|
||||
</Text>
|
||||
</Stack>
|
||||
<Paper
|
||||
radius="2xl"
|
||||
px="xl"
|
||||
py="md"
|
||||
bg={colors["blue-button"]}
|
||||
shadow="xl"
|
||||
withBorder
|
||||
>
|
||||
<Flex justify="center" align="center" gap="xl">
|
||||
<Box>
|
||||
<Text fz={"3.4rem"} c={colors["blue-button"]} fw={"bold"}>
|
||||
Potensi Desa
|
||||
<Text ta="center" fz="2rem" fw={800} c="white">
|
||||
{data?.filter(item => item.kategori?.nama.toLowerCase() !== 'wisata').length || 0}
|
||||
</Text>
|
||||
<Text ta={"justify"} >
|
||||
Temukan berbagai potensi dan keunggulan yang dimiliki Desa Darmasaba.
|
||||
<Text ta="center" fz="sm" c="white" fw={500}>
|
||||
Potensi
|
||||
</Text>
|
||||
</Box>
|
||||
<Box>
|
||||
<Text ta="center" fz="2rem" fw={800} c="white">
|
||||
{data?.filter(item => item.kategori?.nama.toLowerCase() === 'wisata').length || 0}
|
||||
</Text>
|
||||
<Text ta="center" fz="sm" c="white" fw={500}>
|
||||
Wisata
|
||||
</Text>
|
||||
</Box>
|
||||
<Paper radius={"md"} px={"xl"} py={5} bg={colors["blue-button"]} >
|
||||
<Flex justify={"space-between"} align={"center"} gap={"xl"}>
|
||||
<Box>
|
||||
<Text ta={"center"} fz={"h2"} fw={"bold"} c={"white"}>
|
||||
{data?.filter(item => item.kategori?.nama.toLowerCase() !== 'wisata' ).length || 0}
|
||||
</Text>
|
||||
<Text ta={"center"} fz={"sm"} c={"white"}>Potensi</Text>
|
||||
</Box>
|
||||
<Box>
|
||||
<Text ta={"center"} fz={"h2"} fw={"bold"} c={"white"}>
|
||||
{data?.filter(item => item.kategori?.nama.toLowerCase() === 'wisata' ).length || 0}
|
||||
</Text>
|
||||
<Text ta={"center"} fz={"sm"} c={"white"}>Wisata</Text>
|
||||
</Box>
|
||||
</Flex>
|
||||
</Paper>
|
||||
</Flex>
|
||||
</Stack>
|
||||
</Box>
|
||||
</Paper>
|
||||
</Flex>
|
||||
|
||||
<SimpleGrid
|
||||
py={20}
|
||||
cols={{
|
||||
base: 1,
|
||||
sm: 3
|
||||
}}
|
||||
>
|
||||
<SimpleGrid py={48} cols={{ base: 1, sm: 2, lg: 3 }} spacing="2xl">
|
||||
{loading ? (
|
||||
<Center>
|
||||
<Skeleton h={250} />
|
||||
</Center>
|
||||
) : (
|
||||
data?.map((v, k) => {
|
||||
return (
|
||||
Array.from({ length: 6 }).map((_, i) => (
|
||||
<Skeleton key={i} h={360} radius="xl" />
|
||||
))
|
||||
) : data && data.length > 0 ? (
|
||||
data.map((v, k) => (
|
||||
<BackgroundImage
|
||||
key={k}
|
||||
src={v.image?.link || ''}
|
||||
h={350}
|
||||
radius={16}
|
||||
pos={"relative"}
|
||||
h={360}
|
||||
radius="xl"
|
||||
style={{ overflow: 'hidden', position: 'relative' }}
|
||||
>
|
||||
<Box
|
||||
style={{
|
||||
borderRadius: 16,
|
||||
zIndex: 0
|
||||
}}
|
||||
pos={"absolute"}
|
||||
w={"100%"}
|
||||
h={"100%"}
|
||||
bg={colors.trans.dark[2]}
|
||||
pos="absolute"
|
||||
inset={0}
|
||||
bg="linear-gradient(180deg, rgba(0,0,0,0.25) 0%, rgba(0,0,0,0.7) 100%)"
|
||||
/>
|
||||
<Stack justify='space-between' h={"100%"} gap={0} p={"lg"} pos={"relative"}>
|
||||
<Stack justify="space-between" h="100%" gap="md" p="lg" pos="relative">
|
||||
<Group>
|
||||
<Paper radius={"lg"} py={7} px={10}>
|
||||
<Text>{v.kategori?.nama}</Text>
|
||||
<Paper radius="lg" py={6} px={12} shadow="md" withBorder bg="rgba(255,255,255,0.85)">
|
||||
<Text fz="sm" fw={600}>{v.kategori?.nama}</Text>
|
||||
</Paper>
|
||||
</Group>
|
||||
<Box p={"lg"}>
|
||||
<Box>
|
||||
<Text
|
||||
fw={"bold"}
|
||||
c={"white"}
|
||||
size={"1.8rem"}
|
||||
style={{
|
||||
textAlign: "center",
|
||||
}}>{v.name}</Text>
|
||||
fw={800}
|
||||
c="white"
|
||||
fz="xl"
|
||||
ta="center"
|
||||
lineClamp={2}
|
||||
lh={1.3}
|
||||
>
|
||||
{v.name}
|
||||
</Text>
|
||||
</Box>
|
||||
<Group justify="center">
|
||||
<Button px={20} radius={"100"} size="md" bg={colors["blue-button"]}
|
||||
onClick={() => router.push(`/darmasaba/desa/potensi/${v.id}`)}>
|
||||
Detail
|
||||
</Button>
|
||||
<Tooltip label="Lihat detail potensi" withArrow>
|
||||
<Button
|
||||
radius="xl"
|
||||
size="md"
|
||||
leftSection={<IconEye size={18} />}
|
||||
bg={colors["blue-button"]}
|
||||
variant="gradient"
|
||||
gradient={{ from: colors["blue-button"], to: "#4dabf7", deg: 45 }}
|
||||
onClick={() => router.push(`/darmasaba/desa/potensi/${v.id}`)}
|
||||
>
|
||||
Lihat Detail
|
||||
</Button>
|
||||
</Tooltip>
|
||||
</Group>
|
||||
</Stack>
|
||||
</BackgroundImage>
|
||||
)
|
||||
})
|
||||
)}
|
||||
))
|
||||
) : (
|
||||
<Center h={240}>
|
||||
<Stack align="center" gap="xs">
|
||||
<Text fz="lg" fw={600} c="dimmed">
|
||||
Belum ada potensi desa
|
||||
</Text>
|
||||
<Text fz="sm" c="dimmed">
|
||||
Data potensi akan tampil di sini setelah tersedia.
|
||||
</Text>
|
||||
</Stack>
|
||||
</Center>
|
||||
)}
|
||||
</SimpleGrid>
|
||||
</Box>
|
||||
|
||||
</Stack>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
/* eslint-disable react-hooks/exhaustive-deps */
|
||||
'use client'
|
||||
import colors from '@/con/colors';
|
||||
import { Box, Stack, Paper, Image, Text, Center, Skeleton } from '@mantine/core';
|
||||
import React, { useEffect } from 'react';
|
||||
import { useProxy } from 'valtio/utils';
|
||||
import stateProfileDesa from '@/app/admin/(dashboard)/_state/desa/profile';
|
||||
import stateProfileDesa from '@/app/admin/(dashboard)/_state/desa/profile'
|
||||
import colors from '@/con/colors'
|
||||
import { Box, Center, Image, Paper, Skeleton, Stack, Text, Tooltip } from '@mantine/core'
|
||||
import { useEffect } from 'react'
|
||||
import { useProxy } from 'valtio/utils'
|
||||
|
||||
function LambangDesa() {
|
||||
const state = useProxy(stateProfileDesa.lambangDesa)
|
||||
@@ -17,26 +17,60 @@ function LambangDesa() {
|
||||
|
||||
if (loading || !data) {
|
||||
return (
|
||||
<Box py={10}>
|
||||
<Skeleton h={500} />
|
||||
<Box py="lg">
|
||||
<Skeleton h={420} radius="xl" />
|
||||
</Box>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<Box pb={70}>
|
||||
<Stack align='center' gap={0}>
|
||||
<Box pb={30}>
|
||||
<Box pb={90}>
|
||||
<Stack align="center" gap="lg">
|
||||
<Box pb="lg">
|
||||
<Center>
|
||||
<Image src={"/darmasaba-icon.png"} alt="" w={{ base: 200, md: 300 }} />
|
||||
<Image
|
||||
src={"/darmasaba-icon.png"}
|
||||
alt="Lambang resmi desa"
|
||||
w={{ base: 180, md: 280 }}
|
||||
radius="md"
|
||||
/>
|
||||
</Center>
|
||||
<Text c={colors['blue-button']} ta={"center"} fw={"bold"} fz={"2.5rem"}>Lambang Desa</Text>
|
||||
<Text
|
||||
c={colors['blue-button']}
|
||||
ta="center"
|
||||
fw={800}
|
||||
fz={{ base: 28, md: 40 }}
|
||||
mt="sm"
|
||||
style={{ letterSpacing: '-0.5px' }}
|
||||
>
|
||||
Lambang Desa
|
||||
</Text>
|
||||
</Box>
|
||||
<Paper p={"xl"} bg={colors['white-trans-1']} w={{ base: "100%", md: "100%" }}>
|
||||
<Text fz={{ base: "md", md: "h3"}} ta={"justify"} dangerouslySetInnerHTML={{__html: data.deskripsi}} />
|
||||
<Paper
|
||||
p="xl"
|
||||
radius="xl"
|
||||
withBorder
|
||||
shadow="sm"
|
||||
w="100%"
|
||||
style={{
|
||||
background: 'linear-gradient(135deg, #ffffff 0%, #f3f7ff 100%)',
|
||||
borderColor: '#e0e9ff',
|
||||
}}
|
||||
>
|
||||
<Tooltip label="Deskripsi lambang desa" position="top-start" withArrow>
|
||||
<Text
|
||||
fz={{ base: 'md', md: 'lg' }}
|
||||
lh={1.8}
|
||||
c="dark"
|
||||
ta="justify"
|
||||
style={{ fontWeight: 400 }}
|
||||
dangerouslySetInnerHTML={{ __html: data.deskripsi }}
|
||||
/>
|
||||
</Tooltip>
|
||||
</Paper>
|
||||
</Stack>
|
||||
</Box >
|
||||
);
|
||||
</Box>
|
||||
)
|
||||
}
|
||||
|
||||
export default LambangDesa;
|
||||
export default LambangDesa
|
||||
|
||||
@@ -1,59 +1,95 @@
|
||||
/* eslint-disable react-hooks/exhaustive-deps */
|
||||
'use client'
|
||||
import stateProfileDesa from '@/app/admin/(dashboard)/_state/desa/profile';
|
||||
import colors from '@/con/colors';
|
||||
import { Box, Card, Center, Group, Image, Paper, Skeleton, Stack, Text } from '@mantine/core';
|
||||
import { Box, Card, Center, Group, Image, Loader, Paper, Stack, Text, Tooltip } from '@mantine/core';
|
||||
import { useEffect } from 'react';
|
||||
import { useProxy } from 'valtio/utils';
|
||||
import { IconPhoto } from '@tabler/icons-react';
|
||||
import colors from '@/con/colors';
|
||||
|
||||
function MaskotDesa() {
|
||||
const state = useProxy(stateProfileDesa.maskotDesa)
|
||||
const state = useProxy(stateProfileDesa.maskotDesa);
|
||||
|
||||
useEffect(() => {
|
||||
state.findUnique.load("edit")
|
||||
}, [])
|
||||
state.findUnique.load('edit');
|
||||
}, []);
|
||||
|
||||
const { data, loading } = state.findUnique
|
||||
const { data, loading } = state.findUnique;
|
||||
|
||||
if (loading || !data) {
|
||||
return (
|
||||
<Box py={10}>
|
||||
<Skeleton h={500} />
|
||||
</Box>
|
||||
)
|
||||
<Center mih={500}>
|
||||
<Stack align="center" gap="sm">
|
||||
<Loader size="lg" color="blue" />
|
||||
<Text c="dimmed" fz="sm">Sedang memuat data maskot desa...</Text>
|
||||
</Stack>
|
||||
</Center>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Box pb={70}>
|
||||
<Stack align='center' gap={0}>
|
||||
<Box pb={30}>
|
||||
<Center>
|
||||
<Image src={"/pudak-icon.png"} alt="" w={{ base: 200, md: 300 }} />
|
||||
</Center>
|
||||
<Text c={colors['blue-button']} ta={"center"} fw={"bold"} fz={"2.5rem"}>Maskot Desa</Text>
|
||||
</Box>
|
||||
<Paper p={"xl"} bg={colors['white-trans-1']}>
|
||||
<Text fz={{ base: "md", md: "h3" }} ta={"justify"} dangerouslySetInnerHTML={{ __html: data.deskripsi }} />
|
||||
<Group wrap="wrap" gap="md">
|
||||
{data.images.map((img, index) => (
|
||||
<Card key={index} p="xs" w={220}>
|
||||
<Image
|
||||
src={img.image.link}
|
||||
alt={img.label}
|
||||
w={200}
|
||||
h={200}
|
||||
fit="cover"
|
||||
radius="md"
|
||||
style={{ border: '1px solid #ccc', objectFit: 'cover' }}
|
||||
/>
|
||||
<Text ta="center" mt="xs" fw="bold">{img.label}</Text>
|
||||
</Card>
|
||||
))}
|
||||
<Box pb={80}>
|
||||
<Stack align="center" gap="xl">
|
||||
<Stack align="center" gap={10}>
|
||||
<Image src="/pudak-icon.png" alt="Ikon Desa" w={{ base: 160, md: 240 }} />
|
||||
<Text c={colors['blue-button']} ta="center" fw={700} fz={{ base: 28, md: 36 }}>Maskot Desa</Text>
|
||||
</Stack>
|
||||
|
||||
<Paper
|
||||
p={{ base: 'md', md: 'xl' }}
|
||||
radius="lg"
|
||||
shadow="sm"
|
||||
withBorder
|
||||
style={{ background: 'linear-gradient(145deg, #ffffff, #f8f9fa)' }}
|
||||
>
|
||||
<Text
|
||||
fz={{ base: 'sm', md: 'lg' }}
|
||||
lh={1.7}
|
||||
ta="justify"
|
||||
c="dark"
|
||||
dangerouslySetInnerHTML={{ __html: data.deskripsi }}
|
||||
/>
|
||||
|
||||
<Group justify="center" gap="lg" mt="lg">
|
||||
{data.images.length > 0 ? (
|
||||
data.images.map((img, index) => (
|
||||
<Tooltip key={index} label={img.label} position="bottom" withArrow>
|
||||
<Card
|
||||
radius="lg"
|
||||
shadow="md"
|
||||
withBorder
|
||||
w={220}
|
||||
p="sm"
|
||||
style={{
|
||||
transition: 'transform 200ms ease, box-shadow 200ms ease',
|
||||
}}
|
||||
className="hover:scale-105 hover:shadow-lg"
|
||||
>
|
||||
<Image
|
||||
src={img.image.link}
|
||||
alt={img.label}
|
||||
w="100%"
|
||||
h={200}
|
||||
fit="cover"
|
||||
radius="md"
|
||||
/>
|
||||
<Text ta="center" mt="sm" fw={600} fz="sm" c="dark">
|
||||
{img.label}
|
||||
</Text>
|
||||
</Card>
|
||||
</Tooltip>
|
||||
))
|
||||
) : (
|
||||
<Stack align="center" gap="xs" mt="lg">
|
||||
<IconPhoto size={48} stroke={1.5} color="gray" />
|
||||
<Text c="dimmed" fz="sm">Belum ada gambar maskot yang ditambahkan</Text>
|
||||
</Stack>
|
||||
)}
|
||||
</Group>
|
||||
</Paper>
|
||||
</Stack>
|
||||
</Box >
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
export default MaskotDesa;
|
||||
|
||||
@@ -1,75 +1,133 @@
|
||||
import colors from '@/con/colors';
|
||||
'use client'
|
||||
import { ActionIcon, Box, Flex, Paper, SimpleGrid, Stack, Text } from '@mantine/core';
|
||||
import { motion } from 'framer-motion';
|
||||
import { IconSparkles } from '@tabler/icons-react';
|
||||
import colors from '@/con/colors';
|
||||
|
||||
const dataText = [
|
||||
{
|
||||
id: 1,
|
||||
title: "SANTUN",
|
||||
description: "Memberikan pelayanan yang baik, penuh rasa empati, sopan, dan beretika"
|
||||
title: "Santun",
|
||||
description: "Pelayanan ramah, penuh empati, sopan, dan beretika."
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
title: "ADAPTIF",
|
||||
description: "Cepat menyesuaikan diri menghadapi perubahan dan bertindak proaktif"
|
||||
title: "Adaptif",
|
||||
description: "Cepat menyesuaikan diri terhadap perubahan dan selalu proaktif."
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
title: "INOVATIF",
|
||||
description: "Selalu berusaha menciptakan pembaruan atau kreasi baru"
|
||||
title: "Inovatif",
|
||||
description: "Berani menciptakan pembaruan dan ide-ide kreatif."
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
title: "PROFESIONAL",
|
||||
description: "Memiliki pengetahuan, terampil dan bertanggung jawab"
|
||||
title: "Profesional",
|
||||
description: "Berpengetahuan luas, terampil, dan bertanggung jawab."
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
title: "GESIT",
|
||||
description: "Inisiatif dan cekatan dalam bekerja"
|
||||
title: "Gesit",
|
||||
description: "Cekatan, sigap, dan penuh inisiatif dalam bekerja."
|
||||
},
|
||||
]
|
||||
];
|
||||
|
||||
const letters = ["S", "I", "G", "A", "P"];
|
||||
|
||||
function MotoDesa() {
|
||||
return (
|
||||
<Box pb={70}>
|
||||
<Stack align='center' gap={0} >
|
||||
<Box pb={30}>
|
||||
<Text c={colors['blue-button']} ta={"center"} fw={"bold"} fz={{ base: "h1", md: "2.5rem" }}>Moto Desa Darmasaba</Text>
|
||||
</Box>
|
||||
<Flex gap={50} pb={50} pt={20} justify={"space-evenly"} align={"center"} >
|
||||
<ActionIcon bg={colors['blue-button']} radius={150} p={{ base: "lg", md: "xl" }}>
|
||||
<Text c={colors['white-1']} ta={"center"} fw={"bold"} fz={{ base: "h2", md: "h1" }}>S</Text>
|
||||
</ActionIcon>
|
||||
<ActionIcon bg={colors['blue-button']} radius={150} p={{ base: "lg", md: "xl" }}>
|
||||
<Text c={colors['white-1']} ta={"center"} fw={"bold"} fz={{ base: "h2", md: "h1" }}>I</Text>
|
||||
</ActionIcon>
|
||||
<ActionIcon bg={colors['blue-button']} radius={150} p={{ base: "lg", md: "xl" }}>
|
||||
<Text c={colors['white-1']} ta={"center"} fw={"bold"} fz={{ base: "h2", md: "h1" }}>G</Text>
|
||||
</ActionIcon>
|
||||
<ActionIcon bg={colors['blue-button']} radius={150} p={{ base: "lg", md: "xl" }}>
|
||||
<Text c={colors['white-1']} ta={"center"} fw={"bold"} fz={{ base: "h2", md: "h1" }}>A</Text>
|
||||
</ActionIcon>
|
||||
<ActionIcon bg={colors['blue-button']} radius={150} p={{ base: "lg", md: "xl" }}>
|
||||
<Text c={colors['white-1']} ta={"center"} fw={"bold"} fz={{ base: "h2", md: "h1" }}>P</Text>
|
||||
</ActionIcon>
|
||||
</Flex>
|
||||
<Paper mb={50} p={"xl"} bg={colors['white-trans-1']} w={{ base: "100%", md: "100%" }}>
|
||||
<SimpleGrid
|
||||
cols={{
|
||||
base: 1,
|
||||
md: 2,
|
||||
<Box pb={80} px={{ base: "md", md: "xl" }}>
|
||||
<Stack align="center" gap="lg">
|
||||
<Box>
|
||||
<Text
|
||||
ta="center"
|
||||
fw={800}
|
||||
fz={{ base: "2rem", md: "2.8rem" }}
|
||||
style={{
|
||||
background: "linear-gradient(90deg, #0D5594FF, #094678FF)",
|
||||
WebkitBackgroundClip: "text",
|
||||
WebkitTextFillColor: "transparent",
|
||||
}}
|
||||
>
|
||||
{dataText.map((v, k) => {
|
||||
return (
|
||||
<Box key={k}>
|
||||
<Text fw={"bold"} fz={{ base: "lg", md: "h3" }}>{v.title}</Text>
|
||||
<Text fz={{ base: "sm", md: "md" }}>{v.description}</Text>
|
||||
</Box>
|
||||
)
|
||||
})}
|
||||
Moto Desa Darmasaba
|
||||
</Text>
|
||||
</Box>
|
||||
|
||||
<Flex gap={30} pb={40} pt={10} wrap="wrap" justify="center">
|
||||
{letters.map((letter, i) => (
|
||||
<motion.div
|
||||
key={i}
|
||||
whileHover={{ scale: 1.15, rotate: 5 }}
|
||||
whileTap={{ scale: 0.95 }}
|
||||
transition={{ type: "spring", stiffness: 300 }}
|
||||
>
|
||||
<ActionIcon
|
||||
radius="xl"
|
||||
size={90}
|
||||
variant="gradient"
|
||||
gradient={{ from: "blue", to: "cyan" }}
|
||||
style={{
|
||||
boxShadow: `0 0 18px ${colors['blue-button']}`,
|
||||
backdropFilter: "blur(6px)",
|
||||
}}
|
||||
>
|
||||
<Text c="white" fw={800} fz="xl">
|
||||
{letter}
|
||||
</Text>
|
||||
</ActionIcon>
|
||||
</motion.div>
|
||||
))}
|
||||
</Flex>
|
||||
|
||||
<Paper
|
||||
radius="lg"
|
||||
p="xl"
|
||||
withBorder
|
||||
style={{
|
||||
background: "linear-gradient(145deg, #ffffffcc, #f5faffcc)",
|
||||
boxShadow: "0 8px 24px rgba(0,0,0,0.08)",
|
||||
}}
|
||||
>
|
||||
<SimpleGrid cols={{ base: 1, md: 2 }} spacing="xl">
|
||||
{dataText.map((v) => (
|
||||
<motion.div
|
||||
key={v.id}
|
||||
whileHover={{ scale: 1.02 }}
|
||||
transition={{ duration: 0.2 }}
|
||||
>
|
||||
<Stack gap={4}>
|
||||
<Flex align="center" gap="sm">
|
||||
<IconSparkles size={20} color={colors['blue-button']} />
|
||||
<Text fw={700} fz={{ base: "lg", md: "xl" }} c={colors['blue-button']}>
|
||||
{v.title}
|
||||
</Text>
|
||||
</Flex>
|
||||
<Text fz={{ base: "sm", md: "md" }} c="gray.7">
|
||||
{v.description}
|
||||
</Text>
|
||||
</Stack>
|
||||
</motion.div>
|
||||
))}
|
||||
</SimpleGrid>
|
||||
</Paper>
|
||||
<Text mb={40} c={colors['blue-button']} ta={"center"} fw={"bold"} fz={{ base: "h4", md: "h3" }}>"Berkomitmen memberikan pelayanan terbaik dengan prinsip SIGAP untuk masyarakat Desa Darmasaba"</Text>
|
||||
|
||||
<Text
|
||||
ta="center"
|
||||
fw={700}
|
||||
fz={{ base: "md", md: "xl" }}
|
||||
c="blue.8"
|
||||
mt="md"
|
||||
style={{
|
||||
maxWidth: 720,
|
||||
lineHeight: 1.6,
|
||||
}}
|
||||
>
|
||||
"Berkomitmen menghadirkan pelayanan terbaik dengan semangat{" "}
|
||||
<Text span fw={800} c="cyan.6">
|
||||
SIGAP
|
||||
</Text>{" "}
|
||||
untuk masyarakat Desa Darmasaba."
|
||||
</Text>
|
||||
</Stack>
|
||||
</Box>
|
||||
);
|
||||
|
||||
@@ -2,9 +2,10 @@
|
||||
'use client'
|
||||
import stateProfileDesa from '@/app/admin/(dashboard)/_state/desa/profile';
|
||||
import colors from '@/con/colors';
|
||||
import { Box, Image, Paper, SimpleGrid, Skeleton, Stack, Text } from '@mantine/core';
|
||||
import { Box, Image, Paper, SimpleGrid, Skeleton, Stack, Text, Divider, Tooltip } from '@mantine/core';
|
||||
import { useEffect } from 'react';
|
||||
import { useProxy } from 'valtio/utils';
|
||||
import { IconUser, IconBriefcase, IconUsers, IconTargetArrow } from '@tabler/icons-react';
|
||||
|
||||
function ProfilPerbekel() {
|
||||
const state = useProxy(stateProfileDesa.profilPerbekel)
|
||||
@@ -17,77 +18,155 @@ function ProfilPerbekel() {
|
||||
|
||||
if (loading || !data) {
|
||||
return (
|
||||
<Box py={10}>
|
||||
<Skeleton h={500} />
|
||||
<Box py={20} px="md">
|
||||
<Skeleton h={500} radius="lg" />
|
||||
</Box>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<Box pb={70}>
|
||||
<Stack align='center' gap={0}>
|
||||
<Box pb={30}>
|
||||
<Text c={colors['blue-button']} ta={"center"} fw={"bold"} fz={"2.5rem"}>Profil Perbekel</Text>
|
||||
</Box>
|
||||
<Box pb={80} px="md">
|
||||
<Stack align="center" gap={0} mb={40}>
|
||||
<Text
|
||||
c={colors['blue-button']}
|
||||
ta="center"
|
||||
fw="bold"
|
||||
fz={{ base: "2rem", md: "2.8rem" }}
|
||||
style={{ letterSpacing: "0.5px" }}
|
||||
>
|
||||
Profil Perbekel
|
||||
</Text>
|
||||
<Divider w={120} size="sm" color={colors['blue-button']} mt={10} />
|
||||
</Stack>
|
||||
<SimpleGrid
|
||||
cols={{
|
||||
base: 1,
|
||||
md: 2,
|
||||
}}
|
||||
pb={50}
|
||||
>
|
||||
|
||||
<SimpleGrid cols={{ base: 1, md: 2 }} spacing="xl" pb={50}>
|
||||
<Box>
|
||||
<Paper bg={colors['white-trans-1']} w={{ base: "100%", md: "100%" }}>
|
||||
<Paper
|
||||
bg={colors['white-trans-1']}
|
||||
w="100%"
|
||||
radius="xl"
|
||||
shadow="md"
|
||||
withBorder
|
||||
>
|
||||
<Stack gap={0}>
|
||||
<Image
|
||||
pt={{ base: 0, md: 120 }}
|
||||
px={"lg"}
|
||||
pt={{ base: 0, md: 100 }}
|
||||
px="lg"
|
||||
src={data.image?.link || "/perbekel.png"}
|
||||
sizes='100%'
|
||||
alt=''
|
||||
alt="Foto Perbekel"
|
||||
radius="lg"
|
||||
onError={(e) => {
|
||||
e.currentTarget.src = "/perbekel.png";
|
||||
}}
|
||||
/>
|
||||
<Paper
|
||||
bg={colors['blue-button']}
|
||||
px={"lg"}
|
||||
px="lg"
|
||||
radius="0 0 var(--mantine-radius-xl) var(--mantine-radius-xl)"
|
||||
className="glass3"
|
||||
py={{ base: 20, md: 50 }}
|
||||
|
||||
>
|
||||
<Text c={colors['white-1']} fz={{ base: "md", md: "h3" }}>Perbekel Desa Darmasaba</Text>
|
||||
<Text c={colors['white-1']} fw={"bolder"} fz={{ base: "md", md: "h2" }}>
|
||||
I.B. Surya Prabhawa Manuaba, S.H.,M.H.,NL.P.
|
||||
<Text c={colors['white-1']} fz={{ base: "lg", md: "h3" }}>
|
||||
Perbekel Desa Darmasaba
|
||||
</Text>
|
||||
<Text
|
||||
c={colors['white-1']}
|
||||
fw="bolder"
|
||||
fz={{ base: "xl", md: "h2" }}
|
||||
mt={8}
|
||||
>
|
||||
{"I.B. Surya Prabhawa Manuaba, S.H.,M.H.,NL.P."}
|
||||
</Text>
|
||||
</Paper>
|
||||
</Stack>
|
||||
</Paper>
|
||||
</Box>
|
||||
<Paper p={"xl"} bg={colors['white-trans-1']} w={{ base: "100%", md: "100%" }}>
|
||||
<Box>
|
||||
<Text fz={{ base: "1.125rem", md: "1.6rem" }} fw={'bold'}>Biodata</Text>
|
||||
<Text fz={{ base: "1rem", md: "1.5rem" }} ta={"justify"} dangerouslySetInnerHTML={{ __html: data.biodata }} />
|
||||
</Box>
|
||||
<Box>
|
||||
<Text fz={{ base: "1.125rem", md: "1.6rem" }} fw={'bold'}>Pengalaman</Text>
|
||||
<Text fz={{ base: "1rem", md: "1.5rem" }} dangerouslySetInnerHTML={{ __html: data.pengalaman }} />
|
||||
</Box>
|
||||
|
||||
<Paper
|
||||
p="xl"
|
||||
bg={colors['white-trans-1']}
|
||||
w="100%"
|
||||
radius="xl"
|
||||
shadow="md"
|
||||
withBorder
|
||||
>
|
||||
<Stack gap="xl">
|
||||
<Box>
|
||||
<Tooltip label="Informasi pribadi perbekel" withArrow>
|
||||
<Stack gap={6}>
|
||||
<Stack align="center" gap={6}>
|
||||
<IconUser size={22} color={colors['blue-button']} />
|
||||
<Text fz={{ base: "1.2rem", md: "1.5rem" }} fw="bold">Biodata</Text>
|
||||
</Stack>
|
||||
<Text
|
||||
fz={{ base: "1rem", md: "1.2rem" }}
|
||||
ta="justify"
|
||||
lh={1.6}
|
||||
dangerouslySetInnerHTML={{ __html: data.biodata }}
|
||||
/>
|
||||
</Stack>
|
||||
</Tooltip>
|
||||
</Box>
|
||||
|
||||
<Box>
|
||||
<Tooltip label="Pengalaman kerja perbekel" withArrow>
|
||||
<Stack gap={6}>
|
||||
<Stack align="center" gap={6}>
|
||||
<IconBriefcase size={22} color={colors['blue-button']} />
|
||||
<Text fz={{ base: "1.2rem", md: "1.5rem" }} fw="bold">Pengalaman</Text>
|
||||
</Stack>
|
||||
<Text
|
||||
fz={{ base: "1rem", md: "1.2rem" }}
|
||||
ta="justify"
|
||||
lh={1.6}
|
||||
dangerouslySetInnerHTML={{ __html: data.pengalaman }}
|
||||
/>
|
||||
</Stack>
|
||||
</Tooltip>
|
||||
</Box>
|
||||
</Stack>
|
||||
</Paper>
|
||||
</SimpleGrid >
|
||||
<Paper p={"xl"} bg={colors['white-trans-1']} w={{ base: "100%", md: "100%" }}>
|
||||
<Box>
|
||||
<Text fz={{ base: "1.125rem", md: "1.6rem" }} fw={'bold'}>Pengalaman Organisasi</Text>
|
||||
<Text fz={{ base: "1rem", md: "1.5rem" }} ta={"justify"} dangerouslySetInnerHTML={{ __html: data.pengalamanOrganisasi }} />
|
||||
</Box>
|
||||
<Box pb={20}>
|
||||
<Text fz={{ base: "1.125rem", md: "1.6rem" }} fw={'bold'}>Program Kerja Unggulan</Text>
|
||||
<Box px={20}>
|
||||
<Text fz={{ base: "1rem", md: "1.5rem" }} ta={"justify"} dangerouslySetInnerHTML={{ __html: data.programUnggulan }} />
|
||||
</SimpleGrid>
|
||||
|
||||
<Paper
|
||||
p="xl"
|
||||
bg={colors['white-trans-1']}
|
||||
w="100%"
|
||||
radius="xl"
|
||||
shadow="md"
|
||||
withBorder
|
||||
>
|
||||
<Stack gap="xl">
|
||||
<Box>
|
||||
<Stack align="center" gap={6} >
|
||||
<IconUsers size={22} color={colors['blue-button']} />
|
||||
<Text fz={{ base: "1.2rem", md: "1.5rem" }} fw="bold">Pengalaman Organisasi</Text>
|
||||
</Stack>
|
||||
<Text
|
||||
fz={{ base: "1rem", md: "1.2rem" }}
|
||||
ta="justify"
|
||||
lh={1.6}
|
||||
dangerouslySetInnerHTML={{ __html: data.pengalamanOrganisasi }}
|
||||
/>
|
||||
</Box>
|
||||
</Box>
|
||||
|
||||
<Box>
|
||||
<Stack align="center" gap={6} mb={6}>
|
||||
<IconTargetArrow size={22} color={colors['blue-button']} />
|
||||
<Text fz={{ base: "1.2rem", md: "1.5rem" }} fw="bold">Program Kerja Unggulan</Text>
|
||||
</Stack>
|
||||
<Box px={10}>
|
||||
<Text
|
||||
fz={{ base: "1rem", md: "1.2rem" }}
|
||||
ta="justify"
|
||||
lh={1.6}
|
||||
dangerouslySetInnerHTML={{ __html: data.programUnggulan }}
|
||||
/>
|
||||
</Box>
|
||||
</Box>
|
||||
</Stack>
|
||||
</Paper>
|
||||
</Box >
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -7,39 +7,69 @@ import { useEffect } from 'react';
|
||||
import { useProxy } from 'valtio/utils';
|
||||
|
||||
function SejarahDesa() {
|
||||
const state = useProxy(stateProfileDesa.sejarahDesa)
|
||||
const state = useProxy(stateProfileDesa.sejarahDesa);
|
||||
|
||||
useEffect(() => {
|
||||
state.findUnique.load("edit")
|
||||
}, [])
|
||||
state.findUnique.load('edit');
|
||||
}, []);
|
||||
|
||||
const { data, loading } = state.findUnique
|
||||
const { data, loading } = state.findUnique;
|
||||
|
||||
if (loading || !data) {
|
||||
return (
|
||||
<Box py={10}>
|
||||
<Skeleton h={500} />
|
||||
<Box py="lg">
|
||||
<Skeleton h={500} radius="lg" />
|
||||
</Box>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<Box pb={70}>
|
||||
<Stack align='center' gap={0}>
|
||||
<Box pb={30}>
|
||||
<Center>
|
||||
<Image src={"/darmasaba-icon.png"} alt="" w={{ base: 200, md: 300 }} />
|
||||
</Center>
|
||||
<Text c={colors['blue-button']} ta={"center"} fw={"bold"} fz={"2.5rem"}>Sejarah Desa</Text>
|
||||
</Box>
|
||||
<Paper p={"xl"} bg={colors['white-trans-1']}>
|
||||
<Text fz={{ base: "md", md: "h3" }} ta={"justify"} dangerouslySetInnerHTML={{ __html: data.deskripsi }} />
|
||||
</Paper>
|
||||
|
||||
<Box py="xl">
|
||||
<Stack align="center" gap="xl">
|
||||
<Stack align="center" gap="sm">
|
||||
<Center>
|
||||
<Image
|
||||
src="/darmasaba-icon.png"
|
||||
alt="Ikon Desa Darmasaba"
|
||||
w={{ base: 180, md: 260 }}
|
||||
radius="md"
|
||||
style={{ filter: 'drop-shadow(0 4px 12px rgba(0,0,0,0.15))' }}
|
||||
/>
|
||||
</Center>
|
||||
<Center>
|
||||
<Text
|
||||
c={colors['blue-button']}
|
||||
ta="center"
|
||||
fw={700}
|
||||
fz={{ base: '2rem', md: '2.8rem' }}
|
||||
style={{ letterSpacing: '-0.5px' }}
|
||||
>
|
||||
Sejarah Desa
|
||||
</Text>
|
||||
</Center>
|
||||
</Stack>
|
||||
</Box >
|
||||
</>
|
||||
<Paper
|
||||
p="xl"
|
||||
radius="lg"
|
||||
bg="white"
|
||||
shadow="sm"
|
||||
style={{
|
||||
background: 'linear-gradient(135deg, #ffffff 0%, #f9fbfd 100%)',
|
||||
border: `1px solid ${colors['blue-button']}20`,
|
||||
}}
|
||||
>
|
||||
<Stack gap="md">
|
||||
<Text
|
||||
fz={{ base: 'md', md: 'lg' }}
|
||||
lh={1.8}
|
||||
ta="justify"
|
||||
style={{ color: '#2a2a2a' }}
|
||||
dangerouslySetInnerHTML={{ __html: data.deskripsi }}
|
||||
/>
|
||||
</Stack>
|
||||
</Paper>
|
||||
</Stack>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,59 +1,102 @@
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
'use client'
|
||||
import colors from '@/con/colors';
|
||||
import { Box, Center, Image, Paper, SimpleGrid, Skeleton, Stack, Text } from '@mantine/core';
|
||||
import stateProfileDesa from '@/app/admin/(dashboard)/_state/desa/profile';
|
||||
import { useProxy } from 'valtio/utils';
|
||||
import { Box, Center, Image, Paper, SimpleGrid, Skeleton, Stack, Text, Title, Tooltip } from '@mantine/core';
|
||||
import { useShallowEffect } from '@mantine/hooks';
|
||||
import { IconUser } from '@tabler/icons-react';
|
||||
import { useProxy } from 'valtio/utils';
|
||||
|
||||
function SemuaPerbekel() {
|
||||
const state = useProxy(stateProfileDesa.mantanPerbekel)
|
||||
const state = useProxy(stateProfileDesa.mantanPerbekel);
|
||||
|
||||
useShallowEffect(() => {
|
||||
state.findMany.load()
|
||||
}, [])
|
||||
useShallowEffect(() => {
|
||||
state.findMany.load();
|
||||
}, []);
|
||||
|
||||
const {data, loading} = state.findMany
|
||||
const { data, loading } = state.findMany;
|
||||
|
||||
if (loading || !data) {
|
||||
return (
|
||||
<Box py={10}>
|
||||
<Skeleton h={500} />
|
||||
</Box>
|
||||
)
|
||||
}
|
||||
if (loading || !data) {
|
||||
return (
|
||||
<Box py="xl">
|
||||
<Skeleton h={500} radius="xl" />
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
if (data.length === 0) {
|
||||
return (
|
||||
<Center py="xl">
|
||||
<Stack align="center" gap="sm">
|
||||
<IconUser size={48} stroke={1.5} />
|
||||
<Title fw="bold" order={2}>Belum ada data Perbekel</Title>
|
||||
<Text c="dimmed" fz="sm" ta="center">Data mantan Perbekel akan muncul di sini ketika sudah tersedia</Text>
|
||||
</Stack>
|
||||
</Center>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Box pb={50}>
|
||||
<Stack align='center'>
|
||||
<Box pb={30}>
|
||||
<Text c={colors['blue-button']} ta={"center"} fw={"bold"} fz={{ base: "h1", md: "2.5rem" }}>Perbekel Dari Masa Ke Masa</Text>
|
||||
<Box pb={80}>
|
||||
<Stack align="center" gap="lg">
|
||||
<Box>
|
||||
<Text
|
||||
ta="center"
|
||||
fw={900}
|
||||
fz={{ base: "2rem", md: "2.5rem" }}
|
||||
variant="gradient"
|
||||
gradient={{ from: "blue", to: "cyan", deg: 45 }}
|
||||
>
|
||||
Perbekel Dari Masa ke Masa
|
||||
</Text>
|
||||
</Box>
|
||||
<SimpleGrid
|
||||
cols={{
|
||||
base: 1,
|
||||
md: 3,
|
||||
}}
|
||||
>
|
||||
{data.map((v, k) => {
|
||||
return (
|
||||
<Box key={k}>
|
||||
<Paper h={620} mb={50} radius={26} bg={colors['white-trans-1']} w={{ base: "100%", md: "100%" }}>
|
||||
<Box>
|
||||
<Center>
|
||||
<Image src={v.image?.link} alt='' />
|
||||
</Center>
|
||||
</Box>
|
||||
<Box>
|
||||
<Stack gap={"sm"} py={10}>
|
||||
<Text ta={"center"} fw={"bold"} fz={{ base: "h3", md: "h3" }}>{v.nama}</Text>
|
||||
<Text ta={"center"} fz={{ base: "h5", md: "h4" }}>{v.daerah}</Text>
|
||||
<Text ta={"center"} fz={{ base: "h5", md: "h4" }}>{v.periode}</Text>
|
||||
</Stack>
|
||||
</Box>
|
||||
</Paper>
|
||||
</Box>
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
<SimpleGrid cols={{ base: 1, sm: 2, md: 3 }} spacing="xl" w="100%">
|
||||
{data.map((v: any, k: number) => (
|
||||
<Paper
|
||||
key={k}
|
||||
radius="2xl"
|
||||
shadow="md"
|
||||
withBorder
|
||||
p="lg"
|
||||
bg="white"
|
||||
style={{
|
||||
transition: "all 250ms ease",
|
||||
}}
|
||||
className="hover:shadow-xl hover:scale-[1.02]"
|
||||
>
|
||||
<Stack gap="md" align="center">
|
||||
<Box w="100%" h={300} style={{ overflow: "hidden", borderRadius: "1rem" }}>
|
||||
<Image
|
||||
src={v.image?.link}
|
||||
alt={v.nama || "Foto Perbekel"}
|
||||
fit="cover"
|
||||
h="100%"
|
||||
w="100%"
|
||||
/>
|
||||
</Box>
|
||||
|
||||
<Stack gap={4} align="center">
|
||||
<Tooltip label="Nama Perbekel" withArrow>
|
||||
<Text fw={700} fz="lg" ta="center">
|
||||
{v.nama}
|
||||
</Text>
|
||||
</Tooltip>
|
||||
|
||||
<Tooltip label="Wilayah menjabat" withArrow>
|
||||
<Text c="dimmed" fz="sm" ta="center">
|
||||
{v.daerah}
|
||||
</Text>
|
||||
</Tooltip>
|
||||
|
||||
<Tooltip label="Periode jabatan" withArrow>
|
||||
<Text c="blue" fw={600} fz="sm" ta="center">
|
||||
{v.periode}
|
||||
</Text>
|
||||
</Tooltip>
|
||||
</Stack>
|
||||
</Stack>
|
||||
</Paper>
|
||||
))}
|
||||
</SimpleGrid>
|
||||
</Stack>
|
||||
</Box>
|
||||
|
||||
@@ -6,43 +6,90 @@ import { Box, Image, Paper, Skeleton, Stack, Text } from '@mantine/core';
|
||||
import { useEffect } from 'react';
|
||||
import { useProxy } from 'valtio/utils';
|
||||
|
||||
function VisimisiDesa() {
|
||||
const state = useProxy(stateProfileDesa.visiMisiDesa)
|
||||
function VisiMisiDesa() {
|
||||
const state = useProxy(stateProfileDesa.visiMisiDesa);
|
||||
|
||||
useEffect(() => {
|
||||
state.findUnique.load("edit")
|
||||
}, [])
|
||||
useEffect(() => {
|
||||
state.findUnique.load('edit');
|
||||
}, []);
|
||||
|
||||
const { data, loading } = state.findUnique
|
||||
const { data, loading } = state.findUnique;
|
||||
|
||||
if (loading || !data) {
|
||||
return (
|
||||
<Box py={10}>
|
||||
<Skeleton h={500} />
|
||||
</Box>
|
||||
)
|
||||
}
|
||||
if (loading || !data) {
|
||||
return (
|
||||
<>
|
||||
<Box pb={30}>
|
||||
<Stack align='center' gap={0}>
|
||||
<Box pb={30}>
|
||||
<Image src={"/darmasaba-icon.png"} alt="" w={{ base: 200, md: 300 }} />
|
||||
</Box>
|
||||
<Paper p={"xl"} bg={colors['white-trans-1']} w={{ base: "100%", md: "100%" }}>
|
||||
<Text c={colors['blue-button']} ta={"center"} fw={"lighter"} fz={"2.5rem"}>Visi Desa</Text>
|
||||
<Text fz={"1.5rem"} ta={"center"} fw={"bold"} dangerouslySetInnerHTML={{ __html: data.visi }} />
|
||||
</Paper>
|
||||
<Paper my={20} p={"xl"} bg={colors['white-trans-1']} w={{ base: "100%", md: "100%" }}>
|
||||
<Text c={colors['blue-button']} ta={"center"} fw={"lighter"} fz={"2.5rem"}>Misi Desa</Text>
|
||||
<Box>
|
||||
<Text fz={"1.5rem"} fw={"bold"} dangerouslySetInnerHTML={{ __html: data.misi }} />
|
||||
</Box>
|
||||
</Paper>
|
||||
</Stack>
|
||||
</Box >
|
||||
</>
|
||||
<Box py="xl">
|
||||
<Skeleton h={500} radius="lg" />
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Box py="xl">
|
||||
<Stack align="center" gap="xl">
|
||||
<Image
|
||||
src="/darmasaba-icon.png"
|
||||
alt="Lambang Desa Darmasaba"
|
||||
w={{ base: 160, md: 240 }}
|
||||
radius="md"
|
||||
/>
|
||||
|
||||
<Paper
|
||||
p="xl"
|
||||
radius="lg"
|
||||
shadow="md"
|
||||
withBorder
|
||||
w="100%"
|
||||
style={{
|
||||
background: 'linear-gradient(145deg, #ffffff, #f5f7fa)',
|
||||
}}
|
||||
>
|
||||
<Text
|
||||
c={colors['blue-button']}
|
||||
ta="center"
|
||||
fw={700}
|
||||
fz={{ base: '2rem', md: '2.5rem' }}
|
||||
mb="md"
|
||||
>
|
||||
Visi Desa
|
||||
</Text>
|
||||
<Text
|
||||
fz={{ base: '1.125rem', md: '1.375rem' }}
|
||||
ta="center"
|
||||
fw={500}
|
||||
lh={1.6}
|
||||
dangerouslySetInnerHTML={{ __html: data.visi }}
|
||||
/>
|
||||
</Paper>
|
||||
|
||||
<Paper
|
||||
p="xl"
|
||||
radius="lg"
|
||||
shadow="md"
|
||||
withBorder
|
||||
w="100%"
|
||||
style={{
|
||||
background: 'linear-gradient(145deg, #ffffff, #f5f7fa)',
|
||||
}}
|
||||
>
|
||||
<Text
|
||||
c={colors['blue-button']}
|
||||
ta="center"
|
||||
fw={700}
|
||||
fz={{ base: '2rem', md: '2.5rem' }}
|
||||
mb="md"
|
||||
>
|
||||
Misi Desa
|
||||
</Text>
|
||||
<Text
|
||||
fz={{ base: '1.125rem', md: '1.375rem' }}
|
||||
fw={500}
|
||||
lh={1.6}
|
||||
dangerouslySetInnerHTML={{ __html: data.misi }}
|
||||
/>
|
||||
</Paper>
|
||||
</Stack>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
export default VisimisiDesa;
|
||||
export default VisiMisiDesa;
|
||||
|
||||
@@ -2,158 +2,155 @@
|
||||
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, Button, Center, Divider, Group, Image, List, ListItem, Paper, Skeleton, Stack, Table, TableTbody, TableTd, TableTh, TableThead, TableTr, Text } from '@mantine/core';
|
||||
import { Box, Divider, Group, List, ListItem, Paper, Skeleton, Stack, Table, TableTbody, TableTd, TableTh, TableThead, TableTr, Text } from '@mantine/core';
|
||||
import { useShallowEffect } from '@mantine/hooks';
|
||||
import { IconAlertCircle, IconCalendar, IconInfoCircle } from '@tabler/icons-react';
|
||||
import { useParams } from 'next/navigation';
|
||||
import { useProxy } from 'valtio/utils';
|
||||
|
||||
function Page() {
|
||||
const state = useProxy(artikelKesehatanState)
|
||||
const params = useParams()
|
||||
const state = useProxy(artikelKesehatanState);
|
||||
const params = useParams();
|
||||
|
||||
useShallowEffect(() => {
|
||||
state.findUnique.load(params?.id as string)
|
||||
}, [])
|
||||
state.findUnique.load(params?.id as string);
|
||||
}, []);
|
||||
|
||||
if (!state.findUnique.data) {
|
||||
return (
|
||||
<Stack py={10}>
|
||||
<Skeleton h={500} />
|
||||
<Stack py="xl" px="md">
|
||||
<Skeleton h={420} radius="lg" />
|
||||
<Skeleton h={20} mt="md" w="60%" />
|
||||
<Skeleton h={20} w="40%" />
|
||||
<Skeleton h={200} radius="md" />
|
||||
</Stack>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Stack pos={"relative"} bg={colors.Bg} py={"xl"} gap={"22"}>
|
||||
<Stack pos="relative" bg={colors.Bg} py="xl" gap="xl">
|
||||
<Box px={{ base: 'md', md: 100 }}>
|
||||
<BackButton />
|
||||
</Box>
|
||||
<Box px={{ base: "md", md: 100 }}>
|
||||
<Stack gap={'lg'}>
|
||||
<Paper radius={10}>
|
||||
<Box style={{ borderTopLeftRadius: 10, borderTopRightRadius: 10 }} bg={colors['blue-button']}>
|
||||
<Text p={'md'} fz={{ base: "h3", md: "h2" }} c={colors['white-1']} fw={"bold"}>
|
||||
Detail Lengkap Fasilitas Kesehatan
|
||||
|
||||
<Box px={{ base: 'md', md: 100 }}>
|
||||
<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">
|
||||
{state.findUnique.data.title || 'Detail Artikel Kesehatan'}
|
||||
</Text>
|
||||
</Box>
|
||||
<Box p={'md'} >
|
||||
<Stack gap={'xs'}>
|
||||
<Center bg={'#DEE3E3FF'}>
|
||||
<Image
|
||||
w={'100%'}
|
||||
src={'/api/img/dbd.png'}
|
||||
alt='' />
|
||||
</Center>
|
||||
<Box>
|
||||
<Text c={'#9A9D9DFF'} fz={{ base: 'h6', md: 'h5' }}>
|
||||
{new Date(state.findUnique.data.createdAt).toLocaleDateString('id-ID', { year: 'numeric', month: 'long', day: 'numeric' })}
|
||||
</Text>
|
||||
</Box>
|
||||
{/* Pendahuluan */}
|
||||
<Text fz={'h4'} fw={"bold"}>
|
||||
Pendahuluan
|
||||
</Text>
|
||||
<Divider />
|
||||
<Text pb={10} fz={'h4'} ta={'justify'}>
|
||||
{state.findUnique.data.introduction?.content}
|
||||
</Text>
|
||||
{/* Kenali Gejala DBD */}
|
||||
<Text fz={'h4'} fw={"bold"}>
|
||||
Kenali Gejala DBD
|
||||
</Text>
|
||||
<Divider />
|
||||
<Text fz={'h4'}>
|
||||
{state.findUnique.data.symptom?.title}
|
||||
</Text>
|
||||
<Text fz={'h4'} dangerouslySetInnerHTML={{ __html: state.findUnique.data.symptom?.content }} />
|
||||
{/* Cara Mencegah DBD */}
|
||||
<Text fz={'h4'} fw={"bold"}>
|
||||
{state.findUnique.data.prevention?.title}
|
||||
</Text>
|
||||
<Divider />
|
||||
<Text fz={'h4'} dangerouslySetInnerHTML={{ __html: state.findUnique.data.prevention?.content }} />
|
||||
{/* Pertolongan Pertama Pada Penderita DBD */}
|
||||
<Text fz={'h4'} fw={"bold"}>
|
||||
{state.findUnique.data.firstaid?.title}
|
||||
</Text>
|
||||
<Divider />
|
||||
<Text fz={'h4'} dangerouslySetInnerHTML={{ __html: state.findUnique.data.firstaid?.content }} />
|
||||
{/* Mitos dan Fakta tentang DBD */}
|
||||
<Text fz={'h4'} fw={"bold"}>
|
||||
{state.findUnique.data.mythvsfact?.title}
|
||||
</Text>
|
||||
<Divider />
|
||||
<Box pb={10}>
|
||||
<Table highlightOnHover withTableBorder withColumnBorders>
|
||||
<TableThead>
|
||||
<TableTr>
|
||||
<TableTh fz={'h4'}>Mitos</TableTh>
|
||||
<TableTh fz={'h4'}>Fakta</TableTh>
|
||||
</TableTr>
|
||||
</TableThead>
|
||||
<TableTbody>
|
||||
{state.findUnique.data?.mythvsfact ? (
|
||||
<TableTr>
|
||||
<TableTd>
|
||||
<Text fz={'h4'} dangerouslySetInnerHTML={{ __html: state.findUnique.data.mythvsfact.mitos }} />
|
||||
</TableTd>
|
||||
<TableTd>
|
||||
<Text fz={'h4'} dangerouslySetInnerHTML={{ __html: state.findUnique.data.mythvsfact.fakta }} />
|
||||
</TableTd>
|
||||
</TableTr>
|
||||
) : (
|
||||
<TableTr>
|
||||
<TableTd colSpan={3} style={{ textAlign: 'center' }}>Tidak ada data mitos dan fakta</TableTd>
|
||||
</TableTr>
|
||||
)}
|
||||
</TableTbody>
|
||||
</Table>
|
||||
</Box>
|
||||
{/* Kapan Harus ke Dokter */}
|
||||
<Text fz={'h4'} fw={"bold"}>
|
||||
Kapan Harus ke Dokter?
|
||||
</Text>
|
||||
<Divider />
|
||||
<Text fz={'h4'}>
|
||||
Segera bawa penderita ke fasilitas kesehatan jika mengalami:
|
||||
</Text>
|
||||
<Text fz={'h4'} dangerouslySetInnerHTML={{ __html: state.findUnique.data.doctorsign.content }} />
|
||||
{/* Kasus DBD di Wilayah Abiansemal */}
|
||||
<Text fz={'h4'} fw={"bold"}>
|
||||
Kasus DBD di Wilayah Abiansemal
|
||||
</Text>
|
||||
<Divider />
|
||||
|
||||
<Paper p={'lg'} bg={colors['blue-button-trans']}>
|
||||
<Text fz={'h3'} c={colors['white-1']} fw={'bold'}>Informasi Lebih Lanjut</Text>
|
||||
<Text fz={'h4'} c={colors['white-1']} fw={"bold"}>
|
||||
Hotline DBD : <Text span fz={'h4'}>(0361) 123456</Text>
|
||||
<Box p="lg">
|
||||
<Stack gap="lg">
|
||||
<Group gap="xs">
|
||||
<IconCalendar size={18} color={colors['blue-button']} />
|
||||
<Text c="dimmed" fz="sm">
|
||||
{new Date(state.findUnique.data.createdAt).toLocaleDateString('id-ID', {
|
||||
year: 'numeric',
|
||||
month: 'long',
|
||||
day: 'numeric',
|
||||
})}
|
||||
</Text>
|
||||
<Text fz={'h4'} c={colors['white-1']} fw={"bold"}>
|
||||
WhatsApp Center : <Text span fz={'h4'}>081234567890</Text>
|
||||
</Text>
|
||||
<Text fz={'h4'} c={colors['white-1']} fw={"bold"}>
|
||||
Email : <Text span fz={'h4'}>
|
||||
p2p@dinkes.badungkab.go.id</Text>
|
||||
</Text>
|
||||
</Paper>
|
||||
{/* Referensi */}
|
||||
<Text fz={'h4'} fw={"bold"}>
|
||||
Referensi
|
||||
</Text>
|
||||
<Divider />
|
||||
<List pb={10} type='ordered'>
|
||||
<ListItem fz={'h4'}>Kementerian Kesehatan RI. (2024). Pedoman Pencegahan dan Pengendalian DBD.</ListItem>
|
||||
<ListItem fz={'h4'}>World Health Organization. (2024). Dengue Guidelines for Diagnosis, Treatment, Prevention and Control.</ListItem>
|
||||
<ListItem fz={'h4'}>Dinas Kesehatan Kabupaten Badung. (2025). Laporan Surveilans DBD Triwulan I 2025.</ListItem>
|
||||
</List>
|
||||
<Group>
|
||||
<Button fz={'lg'} bg={colors['blue-button']}>
|
||||
Download Infografis Pencegahan DBD (PDF)
|
||||
</Button>
|
||||
<Button fz={'lg'} bg={'green'}>
|
||||
Bagikan Artikel Ini
|
||||
</Button>
|
||||
</Group>
|
||||
|
||||
<Stack gap="lg">
|
||||
<Box>
|
||||
<Text fz="h4" fw="bold">Pendahuluan</Text>
|
||||
<Divider my="xs" />
|
||||
<Text fz="md" lh={1.6} ta="justify">
|
||||
{state.findUnique.data.introduction?.content}
|
||||
</Text>
|
||||
</Box>
|
||||
|
||||
<Box>
|
||||
<Text fz="h4" fw="bold">Kenali Gejala DBD</Text>
|
||||
<Divider my="xs" />
|
||||
<Text fz="md" fw="semibold">{state.findUnique.data.symptom?.title}</Text>
|
||||
<Text fz="md" lh={1.6} ta="justify" dangerouslySetInnerHTML={{ __html: state.findUnique.data.symptom?.content }} />
|
||||
</Box>
|
||||
|
||||
<Box>
|
||||
<Text fz="h4" fw="bold">{state.findUnique.data.prevention?.title}</Text>
|
||||
<Divider my="xs" />
|
||||
<Text fz="md" lh={1.6} ta="justify" dangerouslySetInnerHTML={{ __html: state.findUnique.data.prevention?.content }} />
|
||||
</Box>
|
||||
|
||||
<Box>
|
||||
<Text fz="h4" fw="bold">{state.findUnique.data.firstaid?.title}</Text>
|
||||
<Divider my="xs" />
|
||||
<Text fz="md" lh={1.6} ta="justify" dangerouslySetInnerHTML={{ __html: state.findUnique.data.firstaid?.content }} />
|
||||
</Box>
|
||||
|
||||
<Box>
|
||||
<Text fz="h4" fw="bold">{state.findUnique.data.mythvsfact?.title}</Text>
|
||||
<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>
|
||||
</TableTr>
|
||||
</TableThead>
|
||||
<TableTbody>
|
||||
{state.findUnique.data?.mythvsfact ? (
|
||||
<TableTr>
|
||||
<TableTd>
|
||||
<Text fz="sm" lh={1.6} dangerouslySetInnerHTML={{ __html: state.findUnique.data.mythvsfact.mitos }} />
|
||||
</TableTd>
|
||||
<TableTd>
|
||||
<Text fz="sm" lh={1.6} dangerouslySetInnerHTML={{ __html: state.findUnique.data.mythvsfact.fakta }} />
|
||||
</TableTd>
|
||||
</TableTr>
|
||||
) : (
|
||||
<TableTr>
|
||||
<TableTd colSpan={2} ta="center" c="dimmed">Belum ada data mitos dan fakta</TableTd>
|
||||
</TableTr>
|
||||
)}
|
||||
</TableTbody>
|
||||
</Table>
|
||||
</Box>
|
||||
</Box>
|
||||
|
||||
<Box>
|
||||
<Text fz="h4" fw="bold">Kapan Harus ke Dokter?</Text>
|
||||
<Divider my="xs" />
|
||||
<Group gap="xs" mb="xs">
|
||||
<IconAlertCircle size={18} color="red" />
|
||||
<Text fz="md">Segera bawa penderita ke fasilitas kesehatan jika mengalami:</Text>
|
||||
</Group>
|
||||
<Text fz="md" lh={1.6} dangerouslySetInnerHTML={{ __html: state.findUnique.data.doctorsign.content }} />
|
||||
</Box>
|
||||
|
||||
<Box>
|
||||
<Text fz="h4" fw="bold">Kasus DBD di Wilayah Abiansemal</Text>
|
||||
<Divider my="xs" />
|
||||
|
||||
<Paper p="lg" radius="md" bg={colors['blue-button-trans']} withBorder>
|
||||
<Group gap="xs" mb="sm">
|
||||
<IconInfoCircle size={20} color={colors['white-1']} />
|
||||
<Text fz="h4" c={colors['white-1']} fw="bold">Informasi Lebih Lanjut</Text>
|
||||
</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>
|
||||
</Stack>
|
||||
</Paper>
|
||||
</Box>
|
||||
|
||||
<Box>
|
||||
<Text fz="h4" fw="bold">Referensi</Text>
|
||||
<Divider my="xs" />
|
||||
<List spacing="xs" size="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>
|
||||
</List>
|
||||
</Box>
|
||||
</Stack>
|
||||
</Stack>
|
||||
</Box>
|
||||
</Paper>
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
'use client'
|
||||
import artikelKesehatanState from '@/app/admin/(dashboard)/_state/kesehatan/data_kesehatan_warga/artikelKesehatan';
|
||||
import colors from '@/con/colors';
|
||||
import { Anchor, Box, Divider, Image, Paper, Skeleton, Stack, Text } from '@mantine/core';
|
||||
import { Anchor, Box, Card, Divider, Group, Image, Loader, Paper, Stack, Text, Title, Tooltip } from '@mantine/core';
|
||||
import { useShallowEffect } from '@mantine/hooks';
|
||||
import { IconCalendar, IconChevronRight } from '@tabler/icons-react';
|
||||
import { useRouter } from 'next/navigation';
|
||||
import { useProxy } from 'valtio/utils';
|
||||
|
||||
@@ -16,36 +17,71 @@ function ArtikelKesehatanPage() {
|
||||
|
||||
if(!state.findMany.data){
|
||||
return (
|
||||
<Box py={10}>
|
||||
<Skeleton h={500}/>
|
||||
<Box py="xl" ta="center">
|
||||
<Loader size="lg" color={colors['blue-button']} />
|
||||
<Text mt="md" c="dimmed" fz="md">Memuat artikel kesehatan...</Text>
|
||||
</Box>
|
||||
)
|
||||
}
|
||||
|
||||
if(state.findMany.data.length === 0){
|
||||
return (
|
||||
<Box py="xl" ta="center">
|
||||
<Image src="/empty-state.svg" alt="Tidak ada data" w={220} mx="auto" />
|
||||
<Text mt="md" fw="bold" fz="lg">Belum ada artikel kesehatan</Text>
|
||||
<Text c="dimmed" fz="sm">Artikel akan tampil di sini setelah tersedia.</Text>
|
||||
</Box>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<Box>
|
||||
<Paper p={'xl'} h={'112vh'} bg={colors['white-trans-1']}>
|
||||
<Stack gap={'xs'}>
|
||||
<Text ta={'center'} fw={"bold"} fz={'h3'} c={colors['blue-button']}>Artikel Kesehatan</Text>
|
||||
{state.findMany.data.map((item) => (
|
||||
<Box key={item.id}>
|
||||
<Image pt={5} src={'/api/img/dbd.png'} alt="" />
|
||||
<Text fz={'h4'} fw={'bold'} >
|
||||
{item.title}
|
||||
</Text>
|
||||
<Text fz={'h6'} pb={10}>
|
||||
Diposting: {new Date(item.createdAt).toLocaleDateString('id-ID', { year: 'numeric', month: 'long', day: 'numeric' })} | Dinas Kesehatan
|
||||
</Text>
|
||||
<Text fz={'h4'} pb={10} lineClamp={2}>
|
||||
{item.content}
|
||||
</Text>
|
||||
<Anchor c={'black'} onClick={()=> router.push(`/darmasaba/kesehatan/data-kesehatan-warga/artikel-kesehatan-page/${item.id}`)} variant='transparent'>
|
||||
<Text c={colors['blue-button']} fz={'h4'} >
|
||||
Baca Selengkapnya {'>>'}
|
||||
</Text>
|
||||
</Anchor>
|
||||
</Box>
|
||||
))}
|
||||
<Divider color={colors['blue-button']} px={'xl'} />
|
||||
<Paper p="xl" bg={colors['white-trans-1']} radius="xl" shadow="md">
|
||||
<Stack gap="xl">
|
||||
<Title order={2} ta="center" c={colors['blue-button']}>Artikel Kesehatan</Title>
|
||||
<Divider color={colors['blue-button']} />
|
||||
<Stack gap="lg">
|
||||
{state.findMany.data.map((item) => (
|
||||
<Card
|
||||
key={item.id}
|
||||
withBorder
|
||||
radius="lg"
|
||||
shadow="sm"
|
||||
p="lg"
|
||||
style={{ transition: 'transform 200ms ease' }}
|
||||
onMouseEnter={(e) => (e.currentTarget.style.transform = 'translateY(-4px)')}
|
||||
onMouseLeave={(e) => (e.currentTarget.style.transform = 'translateY(0)')}
|
||||
>
|
||||
<Card.Section>
|
||||
<Image src={'/api/img/dbd.png'} alt={item.title} height={200} fit="cover" />
|
||||
</Card.Section>
|
||||
<Stack gap="xs" mt="md">
|
||||
<Text fw="bold" fz="xl" c="dark">{item.title}</Text>
|
||||
<Group gap="xs">
|
||||
<IconCalendar size={16} color={colors['blue-button']} />
|
||||
<Text fz="sm" c="dimmed">
|
||||
{new Date(item.createdAt).toLocaleDateString('id-ID', { year: 'numeric', month: 'long', day: 'numeric' })} • Dinas Kesehatan
|
||||
</Text>
|
||||
</Group>
|
||||
<Text fz="md" c="dark" lineClamp={3}>
|
||||
{item.content}
|
||||
</Text>
|
||||
<Tooltip label="Baca artikel lengkap">
|
||||
<Anchor
|
||||
onClick={()=> router.push(`/darmasaba/kesehatan/data-kesehatan-warga/artikel-kesehatan-page/${item.id}`)}
|
||||
variant="light"
|
||||
c={colors['blue-button']}
|
||||
>
|
||||
<Group gap="xs">
|
||||
<Text fw="bold" fz="md">Baca Selengkapnya</Text>
|
||||
<IconChevronRight size={18} />
|
||||
</Group>
|
||||
</Anchor>
|
||||
</Tooltip>
|
||||
</Stack>
|
||||
</Card>
|
||||
))}
|
||||
</Stack>
|
||||
</Stack>
|
||||
</Paper>
|
||||
</Box>
|
||||
|
||||
@@ -1,160 +1,353 @@
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
'use client'
|
||||
import fasilitasKesehatanState from '@/app/admin/(dashboard)/_state/kesehatan/data_kesehatan_warga/fasilitasKesehatan';
|
||||
import BackButton from '@/app/darmasaba/(pages)/desa/layanan/_com/BackButto';
|
||||
import colors from '@/con/colors';
|
||||
import { Box, Divider, List, ListItem, Paper, Skeleton, Stack, Table, TableTbody, TableTd, TableTh, TableThead, TableTr, Text } from '@mantine/core';
|
||||
import { ActionIcon, Anchor, AspectRatio, Badge, Box, Button, Card, Chip, CopyButton, Divider, Grid, Group, List, ListItem, Paper, Skeleton, Stack, Table, TableTbody, TableTd, TableTh, TableThead, TableTr, Text, ThemeIcon, Title, Tooltip } from '@mantine/core';
|
||||
import { useShallowEffect } from '@mantine/hooks';
|
||||
import { IconArrowRight, IconBrandWhatsapp, IconCheck, IconCopy, IconDeviceLandlinePhone, IconFileDownload, IconHeart, IconInfoCircle, IconMail, IconMapPin, IconMoodEmpty, IconSearch, IconStethoscope, IconUser, IconUsersGroup, IconWallet } from '@tabler/icons-react';
|
||||
import { useParams } from 'next/navigation';
|
||||
import { useMemo } from 'react';
|
||||
import { useProxy } from 'valtio/utils';
|
||||
|
||||
interface Kontak {
|
||||
telepon: string;
|
||||
whatsapp: string;
|
||||
email: string;
|
||||
}
|
||||
|
||||
interface LayananItem {
|
||||
nama: string;
|
||||
keterangan?: string;
|
||||
}
|
||||
|
||||
interface LayananUnggulan {
|
||||
items: LayananItem[];
|
||||
}
|
||||
|
||||
interface Lokasi {
|
||||
mapsEmbed: string;
|
||||
}
|
||||
|
||||
interface TarifDanLayanan {
|
||||
layanan: string;
|
||||
tarif: string | number;
|
||||
gratisBpjs?: boolean;
|
||||
}
|
||||
|
||||
function Page() {
|
||||
const state = useProxy(fasilitasKesehatanState.fasilitasKesehatan)
|
||||
const params = useParams()
|
||||
const state = useProxy(fasilitasKesehatanState.fasilitasKesehatan);
|
||||
const params = useParams();
|
||||
|
||||
useShallowEffect(() => {
|
||||
state.findUnique.load(params?.id as string)
|
||||
}, [])
|
||||
state.findUnique.load(params?.id as string);
|
||||
}, []);
|
||||
|
||||
if (!state.findUnique.data) {
|
||||
const data = state.findUnique.data as any; // Temporary any to fix type issues
|
||||
|
||||
const nama = data?.name || 'Fasilitas Kesehatan';
|
||||
const alamat = data?.informasiumum?.alamat || '-';
|
||||
const jam = data?.informasiumum?.jamOperasional || '-';
|
||||
const layananUnggulan = (data?.layananunggulan as LayananUnggulan)?.items || [];
|
||||
const tenaga = data?.dokterdantenagamedis || null;
|
||||
const fasilitasPendukungHtml = data?.fasilitaspendukung?.content || '';
|
||||
const tarif = (data?.tarifdanlayanan as TarifDanLayanan) || null;
|
||||
const kontak = (data?.kontak as Kontak) || {
|
||||
telepon: '(0361) 123456',
|
||||
whatsapp: '081234567890',
|
||||
email: 'info@fasilitas-kesehatan.id'
|
||||
};
|
||||
const lokasi = (data?.lokasi as Lokasi) || {
|
||||
mapsEmbed: 'https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d3945.272172359321!2d115.21836257533302!3d-8.569807186941553!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x2dd23e9d99b9395f%3A0xb002795fdcb33b30!2sUPTD%20Puskesmas%20Abiansemal%20III!5e0!3m2!1sid!2sid!4v1744792682341!5m2!1sid!2sid'
|
||||
};
|
||||
|
||||
const gratisBpjs = (data?.tarifdanlayanan as TarifDanLayanan)?.gratisBpjs ?? true;
|
||||
|
||||
const formatRupiah = useMemo(
|
||||
() => (v?: number | string) => {
|
||||
if (v === null || v === undefined || v === '') return '-';
|
||||
const n = typeof v === 'string' ? Number(v) : v;
|
||||
if (Number.isNaN(n as number)) return String(v);
|
||||
return new Intl.NumberFormat('id-ID', { style: 'currency', currency: 'IDR', maximumFractionDigits: 0 }).format(n as number);
|
||||
},
|
||||
[]
|
||||
);
|
||||
|
||||
if (state.findUnique.loading || !data) {
|
||||
return (
|
||||
<Stack py={10}>
|
||||
<Skeleton h={500} />
|
||||
<Stack bg={colors.Bg} mih="100vh" p="lg" gap="lg">
|
||||
<Box px={{ base: 'md', md: 100 }}>
|
||||
<Skeleton h={32} w={220} />
|
||||
</Box>
|
||||
<Box px={{ base: 'md', md: 100 }}>
|
||||
<Skeleton h={64} radius="lg" />
|
||||
</Box>
|
||||
<Box px={{ base: 'md', md: 100 }}>
|
||||
<Grid gutter="lg">
|
||||
<Grid.Col span={{ base: 12, md: 8 }}>
|
||||
<Skeleton h={320} radius="lg" />
|
||||
</Grid.Col>
|
||||
<Grid.Col span={{ base: 12, md: 4 }}>
|
||||
<Skeleton h={320} radius="lg" />
|
||||
</Grid.Col>
|
||||
</Grid>
|
||||
</Box>
|
||||
<Box px={{ base: 'md', md: 100 }}>
|
||||
<Skeleton h={420} radius="lg" />
|
||||
</Box>
|
||||
</Stack>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Stack pos={"relative"} bg={colors.Bg} py={"xl"} gap={"22"}>
|
||||
<Stack bg={colors.Bg} py="xl" gap="xl">
|
||||
<Box px={{ base: 'md', md: 100 }}>
|
||||
<BackButton />
|
||||
<Group justify="space-between">
|
||||
<Group gap="xs">
|
||||
<BackButton />
|
||||
</Group>
|
||||
<Group gap="xs">
|
||||
<Badge variant="gradient" gradient={{ from: 'blue', to: 'cyan' }} radius="xl" size="lg" leftSection={<IconHeart size={16} />}>Pelayanan Aktif</Badge>
|
||||
<Badge variant="light" radius="xl" size="lg" leftSection={<IconInfoCircle size={16} />}>Jam: {jam}</Badge>
|
||||
</Group>
|
||||
</Group>
|
||||
</Box>
|
||||
<Box px={{ base: "md", md: 100 }}>
|
||||
<Stack gap={'lg'}>
|
||||
<Paper radius={10}>
|
||||
<Box style={{ borderTopLeftRadius: 10, borderTopRightRadius: 10 }} bg={colors['blue-button']}>
|
||||
<Text p={'md'} fz={{ base: "h3", md: "h2" }} c={colors['white-1']} fw={"bold"}>
|
||||
Detail Lengkap Fasilitas Kesehatan
|
||||
</Text>
|
||||
</Box>
|
||||
<Box p={'md'} >
|
||||
<Stack gap={'xs'}>
|
||||
{/* Informasi Umum */}
|
||||
<Text fz={'h4'} fw={"bold"}>
|
||||
Informasi Umum
|
||||
</Text>
|
||||
<Divider />
|
||||
<Text fz={'h4'} fw={"bold"}>
|
||||
Nama Fasilitas : <Text span fz={'h4'}>{state.findUnique.data?.name}</Text>
|
||||
</Text>
|
||||
<Text fz={'h4'} fw={"bold"}>
|
||||
Alamat : <Text span fz={'h4'}>{state.findUnique.data?.informasiumum.alamat}</Text>
|
||||
</Text>
|
||||
<Text pb={10} fz={'h4'} fw={"bold"}>
|
||||
Jam Operasional: : <Text span fz={'h4'}>{state.findUnique.data?.informasiumum.jamOperasional}</Text>
|
||||
</Text>
|
||||
{/* Layanan Unggulan */}
|
||||
<Text fz={'h4'} fw={"bold"}>
|
||||
Layanan Unggulan
|
||||
</Text>
|
||||
<Divider />
|
||||
|
||||
{/* Tenaga Medis */}
|
||||
<Text fz={'h4'} fw={"bold"}>
|
||||
Dokter & Tenaga Medis
|
||||
</Text>
|
||||
<Box px={{ base: 'md', md: 100 }}>
|
||||
<Card radius="xl" p="lg" withBorder style={{ backdropFilter: 'blur(6px)' }}>
|
||||
<Stack gap="sm">
|
||||
<Title order={2}>{nama}</Title>
|
||||
<Group gap="md" wrap="wrap">
|
||||
<Group gap="xs">
|
||||
<ThemeIcon variant="light" radius="xl"><IconMapPin size={18} /></ThemeIcon>
|
||||
<Text>{alamat}</Text>
|
||||
</Group>
|
||||
<Group gap="xs">
|
||||
<ThemeIcon variant="light" radius="xl"><IconDeviceLandlinePhone size={18} /></ThemeIcon>
|
||||
<Text>{kontak.telepon}</Text>
|
||||
<CopyButton value={kontak.telepon}>
|
||||
{({ copied, copy }) => (
|
||||
<Tooltip label={copied ? 'Disalin' : 'Salin nomor'}>
|
||||
<ActionIcon variant="subtle" onClick={copy}>{copied ? <IconCheck size={18} /> : <IconCopy size={18} />}</ActionIcon>
|
||||
</Tooltip>
|
||||
)}
|
||||
</CopyButton>
|
||||
</Group>
|
||||
<Group gap="xs">
|
||||
<ThemeIcon variant="light" radius="xl"><IconBrandWhatsapp size={18} /></ThemeIcon>
|
||||
<Text>{kontak.whatsapp}</Text>
|
||||
<CopyButton value={kontak.whatsapp}>
|
||||
{({ copied, copy }) => (
|
||||
<Tooltip label={copied ? 'Disalin' : 'Salin WhatsApp'}>
|
||||
<ActionIcon variant="subtle" onClick={copy}>{copied ? <IconCheck size={18} /> : <IconCopy size={18} />}</ActionIcon>
|
||||
</Tooltip>
|
||||
)}
|
||||
</CopyButton>
|
||||
</Group>
|
||||
<Group gap="xs">
|
||||
<ThemeIcon variant="light" radius="xl"><IconMail size={18} /></ThemeIcon>
|
||||
<Text>{kontak.email}</Text>
|
||||
<CopyButton value={kontak.email}>
|
||||
{({ copied, copy }) => (
|
||||
<Tooltip label={copied ? 'Disalin' : 'Salin email'}>
|
||||
<ActionIcon variant="subtle" onClick={copy}>{copied ? <IconCheck size={18} /> : <IconCopy size={18} />}</ActionIcon>
|
||||
</Tooltip>
|
||||
)}
|
||||
</CopyButton>
|
||||
</Group>
|
||||
</Group>
|
||||
<Group gap="xs" mt="sm" wrap="wrap">
|
||||
<Chip defaultChecked radius="xl" variant="light" icon={<IconStethoscope size={16} />}>Layanan Medis</Chip>
|
||||
<Chip radius="xl" variant="light" icon={<IconUsersGroup size={16} />}>Ramah Keluarga</Chip>
|
||||
<Chip radius="xl" variant="light" icon={<IconWallet size={16} />}>Pembayaran Non-Tunai</Chip>
|
||||
</Group>
|
||||
</Stack>
|
||||
</Card>
|
||||
</Box>
|
||||
|
||||
<Box px={{ base: 'md', md: 100 }}>
|
||||
<Grid gutter="lg">
|
||||
<Grid.Col span={{ base: 12, md: 8 }}>
|
||||
<Card radius="xl" p="lg" withBorder>
|
||||
<Stack gap="md">
|
||||
<Group justify="space-between" align="center">
|
||||
<Title order={3}>Informasi Umum</Title>
|
||||
<Badge variant="gradient" gradient={{ from: 'cyan', to: 'blue' }} radius="xl">Terverifikasi</Badge>
|
||||
</Group>
|
||||
<Divider />
|
||||
<Box pb={10}>
|
||||
<Table highlightOnHover withTableBorder withColumnBorders>
|
||||
<Group gap="xl" align="start">
|
||||
<Stack gap={2}>
|
||||
<Text c="dimmed" fz="sm">Nama Fasilitas</Text>
|
||||
<Text fw={600}>{nama}</Text>
|
||||
</Stack>
|
||||
<Stack gap={2}>
|
||||
<Text c="dimmed" fz="sm">Jam Operasional</Text>
|
||||
<Text fw={600}>{jam}</Text>
|
||||
</Stack>
|
||||
</Group>
|
||||
<Divider />
|
||||
<Title order={4}>Layanan Unggulan</Title>
|
||||
{Array.isArray(layananUnggulan) && layananUnggulan.length > 0 ? (
|
||||
<List spacing="xs" icon={<ThemeIcon variant="light" radius="xl"><IconArrowRight size={16} /></ThemeIcon>}>
|
||||
{layananUnggulan.map((x: any, idx: number) => (
|
||||
<ListItem key={idx}>
|
||||
<Group gap="xs" wrap="wrap">
|
||||
<Text fw={600}>{x?.nama || 'Layanan'}</Text>
|
||||
{x?.keterangan && <Badge variant="light" radius="sm">{x.keterangan}</Badge>}
|
||||
</Group>
|
||||
</ListItem>
|
||||
))}
|
||||
</List>
|
||||
) : (
|
||||
<Paper withBorder radius="md" p="md">
|
||||
<Group gap="sm">
|
||||
<IconMoodEmpty />
|
||||
<Text>Tidak ada layanan unggulan yang tercatat.</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" />
|
||||
</AspectRatio>
|
||||
</Stack>
|
||||
</Card>
|
||||
</Grid.Col>
|
||||
|
||||
<Grid.Col span={{ base: 12, md: 4 }}>
|
||||
<Stack gap="lg">
|
||||
<Card radius="xl" p="lg" withBorder>
|
||||
<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>
|
||||
</Group>
|
||||
<Anchor target="_blank" underline="hover">Kunjungi situs resmi</Anchor>
|
||||
</Stack>
|
||||
</Card>
|
||||
|
||||
<Card radius="xl" p="lg" withBorder>
|
||||
<Stack gap="md">
|
||||
<Title order={4}>Dokter & Tenaga Medis</Title>
|
||||
<Table highlightOnHover withTableBorder withColumnBorders stickyHeader stickyHeaderOffset={0} aria-label="Tabel Dokter">
|
||||
<TableThead>
|
||||
<TableTr>
|
||||
<TableTh fz={'h4'}>Nama</TableTh>
|
||||
<TableTh fz={'h4'}>Spesialisasi</TableTh>
|
||||
<TableTh fz={'h4'}>Jadwal</TableTh>
|
||||
<TableTh>Nama</TableTh>
|
||||
<TableTh>Spesialisasi</TableTh>
|
||||
<TableTh>Jadwal</TableTh>
|
||||
</TableTr>
|
||||
</TableThead>
|
||||
<TableTbody>
|
||||
{state.findUnique.data?.dokterdantenagamedis ? (
|
||||
{tenaga ? (
|
||||
<TableTr>
|
||||
<TableTd>{state.findUnique.data.dokterdantenagamedis.name}</TableTd>
|
||||
<TableTd>{state.findUnique.data.dokterdantenagamedis.specialist}</TableTd>
|
||||
<TableTd>{state.findUnique.data.dokterdantenagamedis.jadwal}</TableTd>
|
||||
<TableTd><Group gap="xs"><IconUser size={16} /><Text>{tenaga?.name || '-'}</Text></Group></TableTd>
|
||||
<TableTd>{tenaga?.specialist || '-'}</TableTd>
|
||||
<TableTd>{tenaga?.jadwal || '-'}</TableTd>
|
||||
</TableTr>
|
||||
) : (
|
||||
<TableTr>
|
||||
<TableTd colSpan={3} style={{ textAlign: 'center' }}>Tidak ada data dokter/tenaga medis</TableTd>
|
||||
<TableTd colSpan={3}>
|
||||
<Group justify="center" gap="xs" c="dimmed">
|
||||
<IconSearch size={18} />
|
||||
<Text>Tidak ada data tenaga medis.</Text>
|
||||
</Group>
|
||||
</TableTd>
|
||||
</TableTr>
|
||||
)}
|
||||
</TableTbody>
|
||||
</Table>
|
||||
</Box>
|
||||
{/* Fasilitas Pendukung */}
|
||||
<Text fz={'h4'} fw={"bold"}>
|
||||
Fasilitas Pendukung
|
||||
</Text>
|
||||
</Stack>
|
||||
</Card>
|
||||
</Stack>
|
||||
</Grid.Col>
|
||||
</Grid>
|
||||
</Box>
|
||||
|
||||
<Box px={{ base: 'md', md: 100 }}>
|
||||
<Grid gutter="lg">
|
||||
<Grid.Col span={{ base: 12, md: 8 }}>
|
||||
<Card radius="xl" p="lg" withBorder>
|
||||
<Stack gap="md">
|
||||
<Title order={3}>Fasilitas Pendukung</Title>
|
||||
<Divider />
|
||||
<Text fz={"lg"} dangerouslySetInnerHTML={{ __html: state.findUnique.data?.fasilitaspendukung?.content }} />
|
||||
{/* Dokter */}
|
||||
<Text fz={'h4'} fw={"bold"}>
|
||||
Layanan & Tarif
|
||||
</Text>
|
||||
{fasilitasPendukungHtml ? (
|
||||
<Text fz="md" style={{ lineHeight: 1.7 }} dangerouslySetInnerHTML={{ __html: fasilitasPendukungHtml }} />
|
||||
) : (
|
||||
<Paper withBorder radius="md" p="md">
|
||||
<Group gap="sm">
|
||||
<IconMoodEmpty />
|
||||
<Text>Belum ada informasi fasilitas pendukung.</Text>
|
||||
</Group>
|
||||
</Paper>
|
||||
)}
|
||||
</Stack>
|
||||
</Card>
|
||||
</Grid.Col>
|
||||
<Grid.Col span={{ base: 12, md: 4 }}>
|
||||
<Card radius="xl" p="lg" withBorder>
|
||||
<Stack gap="md">
|
||||
<Title order={3}>Layanan & Tarif</Title>
|
||||
<Divider />
|
||||
<Table highlightOnHover withTableBorder withColumnBorders>
|
||||
<Table highlightOnHover withTableBorder withColumnBorders aria-label="Tabel Layanan dan Tarif">
|
||||
<TableThead>
|
||||
<TableTr>
|
||||
<TableTh fz={'h4'}>Layanan</TableTh>
|
||||
<TableTh fz={'h4'}>Tarif</TableTh>
|
||||
<TableTh>Layanan</TableTh>
|
||||
<TableTh>Tarif</TableTh>
|
||||
</TableTr>
|
||||
</TableThead>
|
||||
<TableTbody>
|
||||
<TableTr>
|
||||
<TableTd>{state.findUnique?.data?.tarifdanlayanan.layanan}</TableTd>
|
||||
<TableTd>{state.findUnique?.data?.tarifdanlayanan.tarif}</TableTd>
|
||||
</TableTr>
|
||||
{tarif ? (
|
||||
<TableTr>
|
||||
<TableTd>{tarif?.layanan || '-'}</TableTd>
|
||||
<TableTd>{formatRupiah(tarif?.tarif)}</TableTd>
|
||||
</TableTr>
|
||||
) : (
|
||||
<TableTr>
|
||||
<TableTd colSpan={2}>
|
||||
<Group justify="center" gap="xs" c="dimmed">
|
||||
<IconSearch size={18} />
|
||||
<Text>Tidak ada data tarif.</Text>
|
||||
</Group>
|
||||
</TableTd>
|
||||
</TableTr>
|
||||
)}
|
||||
</TableTbody>
|
||||
</Table>
|
||||
<Text fz={'h6'} pb={10} fw={"bold"}>
|
||||
* Gratis dengan BPJS Kesehatan
|
||||
</Text>
|
||||
{/* Prosedur Pendaftaran */}
|
||||
<Text fz={'h4'} fw={"bold"}>
|
||||
Prosedur Pendaftaran
|
||||
</Text>
|
||||
<Divider />
|
||||
<List type='ordered' pb={10} >
|
||||
<ListItem fz={'h4'}>Pendaftaran dibuka pukul 07:30 WITA</ListItem>
|
||||
<ListItem fz={'h4'}>Bawa KTP dan Kartu BPJS (jika ada)</ListItem>
|
||||
<ListItem fz={'h4'}>Ambil nomor antrian di loket pendaftaran</ListItem>
|
||||
<ListItem fz={'h4'}>Pengunjung baru wajib mengisi formulir pendaftaran</ListItem>
|
||||
<ListItem fz={'h4'}>Pendaftaran online tersedia melalui aplikasi S-Sehat</ListItem>
|
||||
</List>
|
||||
<Paper p={'lg'} bg={colors['blue-button-trans']}>
|
||||
<Text fz={'h3'} c={colors['white-1']} fw={'bold'}>Kontak Darurat</Text>
|
||||
<Text fz={'h4'} c={colors['white-1']} fw={"bold"}>
|
||||
Telepon : <Text span fz={'h4'}>(0361) 123456</Text>
|
||||
</Text>
|
||||
<Text fz={'h4'} c={colors['white-1']} fw={"bold"}>
|
||||
WhatsApp : <Text span fz={'h4'}>081234567890</Text>
|
||||
</Text>
|
||||
<Text fz={'h4'} c={colors['white-1']} fw={"bold"}>
|
||||
Email : <Text span fz={'h4'}>puskesmasabiansemal3@gmail.com</Text>
|
||||
</Text>
|
||||
</Paper>
|
||||
{/* <Paper p={'lg'} w={{ base: "100%", md: "100%" }}>
|
||||
<iframe src="https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d3945.272172359321!2d115.21836257533302!3d-8.569807186941553!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x2dd23e9d99b9395f%3A0xb002795fdcb33b30!2sUPTD%20Puskesmas%20Abiansemal%20III!5e0!3m2!1sid!2sid!4v1744792682341!5m2!1sid!2sid" width="600" height="450" style={{ border: 2, width: "100%", borderRadius: 10 }} loading="lazy"></iframe>
|
||||
</Paper>
|
||||
{gratisBpjs && (
|
||||
<Group gap="xs">
|
||||
<ThemeIcon variant="light" radius="xl"><IconCheck size={18} /></ThemeIcon>
|
||||
<Text fw={600}>Gratis dengan BPJS Kesehatan</Text>
|
||||
</Group>
|
||||
)}
|
||||
<Group>
|
||||
<Button fz={'lg'} bg={colors['blue-button']}>
|
||||
Download Brosur Layanan (PDF)
|
||||
</Button>
|
||||
</Group> */}
|
||||
<Button variant="gradient" gradient={{ from: 'blue', to: 'cyan' }} leftSection={<IconFileDownload size={18} />}>Unduh Brosur (PDF)</Button>
|
||||
</Group>
|
||||
</Stack>
|
||||
</Box>
|
||||
</Paper>
|
||||
</Stack>
|
||||
</Card>
|
||||
</Grid.Col>
|
||||
</Grid>
|
||||
</Box>
|
||||
|
||||
<Box px={{ base: 'md', md: 100 }} pb="xl">
|
||||
<Paper radius="xl" p="lg" withBorder>
|
||||
<Stack gap="md">
|
||||
<Title order={3}>Prosedur Pendaftaran</Title>
|
||||
<Divider />
|
||||
<List type="ordered" spacing="xs" icon={<ThemeIcon variant="light" radius="xl"><IconArrowRight size={16} /></ThemeIcon>}>
|
||||
<ListItem>Pendaftaran dibuka pukul 07.30 WITA</ListItem>
|
||||
<ListItem>Bawa KTP dan Kartu BPJS (jika ada)</ListItem>
|
||||
<ListItem>Ambil nomor antrian di loket pendaftaran</ListItem>
|
||||
<ListItem>Pengunjung baru mengisi formulir pendaftaran</ListItem>
|
||||
<ListItem>Pendaftaran online tersedia melalui aplikasi S-Sehat</ListItem>
|
||||
</List>
|
||||
</Stack>
|
||||
</Paper>
|
||||
</Box>
|
||||
</Stack>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
export default Page;
|
||||
|
||||
@@ -1,50 +1,100 @@
|
||||
'use client'
|
||||
import fasilitasKesehatanState from '@/app/admin/(dashboard)/_state/kesehatan/data_kesehatan_warga/fasilitasKesehatan';
|
||||
import colors from '@/con/colors';
|
||||
import { Anchor, Box, Divider, Paper, Skeleton, Stack, Text } from '@mantine/core';
|
||||
import { Anchor, Badge, Box, Card, Divider, Group, Paper, Skeleton, Stack, Text } from '@mantine/core';
|
||||
import { useShallowEffect } from '@mantine/hooks';
|
||||
import { useRouter } from 'next/navigation';
|
||||
import { useProxy } from 'valtio/utils';
|
||||
import { IconMapPin, IconClock, IconArrowRight } from '@tabler/icons-react';
|
||||
|
||||
function FasilitasKesehatanPage() {
|
||||
const state = useProxy(fasilitasKesehatanState.fasilitasKesehatan)
|
||||
const state = useProxy(fasilitasKesehatanState.fasilitasKesehatan);
|
||||
const router = useRouter();
|
||||
|
||||
useShallowEffect(() => {
|
||||
state.findMany.load()
|
||||
}, [])
|
||||
state.findMany.load();
|
||||
}, []);
|
||||
|
||||
if(!state.findMany.data){
|
||||
if (!state.findMany.data) {
|
||||
return (
|
||||
<Box py={10}>
|
||||
<Skeleton h={500} />
|
||||
<Box py="xl" px="md">
|
||||
<Stack gap="md">
|
||||
<Skeleton height={80} radius="lg" />
|
||||
<Skeleton height={80} radius="lg" />
|
||||
<Skeleton height={80} radius="lg" />
|
||||
</Stack>
|
||||
</Box>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Box>
|
||||
<Paper p={'xl'} h={'112vh'} bg={colors['white-trans-1']}>
|
||||
<Stack gap={'xs'}>
|
||||
<Text ta={'center'} fw={"bold"} fz={'h3'} c={colors['blue-button']}>Fasilitas Kesehatan</Text>
|
||||
{state.findMany.data.map((item) => (
|
||||
<Box key={item.id}>
|
||||
<Text fz={'h4'} fw={'bold'} c={colors['blue-button']}>
|
||||
{item.name}
|
||||
</Text>
|
||||
<Text fz={'h4'}>
|
||||
{item.informasiumum.alamat}
|
||||
</Text>
|
||||
<Text fz={'h4'}>
|
||||
{item.informasiumum.jamOperasional}
|
||||
</Text>
|
||||
<Anchor onClick={() => router.push(`/darmasaba/kesehatan/data-kesehatan-warga/fasilitas-kesehatan-page/${item.id}`)} c={colors['blue-button']} variant='transparent'>
|
||||
<Text c={colors['blue-button']} fz={'h4'}>
|
||||
Detail {'>>'}
|
||||
</Text>
|
||||
</Anchor>
|
||||
</Box>
|
||||
))}
|
||||
<Divider color={colors['blue-button']} px={'xl'} />
|
||||
<Paper p="xl" radius="xl" shadow="md" h="100%" bg="white">
|
||||
<Stack gap="lg">
|
||||
<Text ta="center" fw={700} fz="32px" c={colors['blue-button']}>
|
||||
Fasilitas Kesehatan
|
||||
</Text>
|
||||
<Divider size="sm" color={colors['blue-button']} />
|
||||
<Stack gap="lg">
|
||||
{state.findMany.data.map((item) => (
|
||||
<Card
|
||||
key={item.id}
|
||||
withBorder
|
||||
radius="xl"
|
||||
shadow="sm"
|
||||
p="lg"
|
||||
style={{
|
||||
background: 'linear-gradient(135deg, #fdfdfd, #f7faff)',
|
||||
transition: 'transform 0.2s ease, box-shadow 0.2s ease',
|
||||
}}
|
||||
onMouseEnter={(e) => {
|
||||
(e.currentTarget as HTMLElement).style.transform = 'translateY(-4px)';
|
||||
(e.currentTarget as HTMLElement).style.boxShadow = '0 8px 20px rgba(0,0,0,0.08)';
|
||||
}}
|
||||
onMouseLeave={(e) => {
|
||||
(e.currentTarget as HTMLElement).style.transform = 'translateY(0px)';
|
||||
(e.currentTarget as HTMLElement).style.boxShadow = '0 4px 12px rgba(0,0,0,0.05)';
|
||||
}}
|
||||
>
|
||||
<Stack gap="sm">
|
||||
<Group justify="space-between" align="center">
|
||||
<Text fw={700} fz="lg" c={colors['blue-button']}>
|
||||
{item.name}
|
||||
</Text>
|
||||
<Badge color="blue" radius="sm" variant="light" fz="xs">
|
||||
Aktif
|
||||
</Badge>
|
||||
</Group>
|
||||
<Group gap="xs">
|
||||
<IconMapPin size={18} stroke={1.5} color={colors['blue-button']} />
|
||||
<Text fz="sm" c="dimmed">
|
||||
{item.informasiumum.alamat}
|
||||
</Text>
|
||||
</Group>
|
||||
<Group gap="xs">
|
||||
<IconClock size={18} stroke={1.5} color={colors['blue-button']} />
|
||||
<Text fz="sm" c="dimmed">
|
||||
{item.informasiumum.jamOperasional}
|
||||
</Text>
|
||||
</Group>
|
||||
<Anchor
|
||||
onClick={() =>
|
||||
router.push(
|
||||
`/darmasaba/kesehatan/data-kesehatan-warga/fasilitas-kesehatan-page/${item.id}`
|
||||
)
|
||||
}
|
||||
c={colors['blue-button']}
|
||||
fz="sm"
|
||||
fw={600}
|
||||
style={{ display: 'inline-flex', alignItems: 'center', gap: '4px' }}
|
||||
>
|
||||
Lihat Detail
|
||||
<IconArrowRight size={16} stroke={1.5} />
|
||||
</Anchor>
|
||||
</Stack>
|
||||
</Card>
|
||||
))}
|
||||
</Stack>
|
||||
</Stack>
|
||||
</Paper>
|
||||
</Box>
|
||||
|
||||
@@ -2,10 +2,30 @@
|
||||
import jadwalkegiatanState from '@/app/admin/(dashboard)/_state/kesehatan/data_kesehatan_warga/jadwalKegiatan';
|
||||
import BackButton from '@/app/darmasaba/(pages)/desa/layanan/_com/BackButto';
|
||||
import colors from '@/con/colors';
|
||||
import { ActionIcon, Box, Button, CheckIcon, Combobox, ComboboxChevron, ComboboxOption, ComboboxOptions, ComboboxTarget, Divider, Group, InputBase, InputPlaceholder, Paper, Skeleton, Stack, Text, Textarea, TextInput, useCombobox } from '@mantine/core';
|
||||
import {
|
||||
ActionIcon,
|
||||
Box,
|
||||
Button,
|
||||
Combobox,
|
||||
ComboboxChevron,
|
||||
ComboboxOption,
|
||||
ComboboxOptions,
|
||||
ComboboxTarget,
|
||||
Divider,
|
||||
Group,
|
||||
InputBase,
|
||||
InputPlaceholder,
|
||||
Paper,
|
||||
Skeleton,
|
||||
Stack,
|
||||
Text,
|
||||
Textarea,
|
||||
TextInput,
|
||||
useCombobox
|
||||
} from '@mantine/core';
|
||||
import { DateInput } from '@mantine/dates';
|
||||
import { useShallowEffect } from '@mantine/hooks';
|
||||
import { IconCalendar } from '@tabler/icons-react';
|
||||
import { IconCalendar, IconDownload, IconPhone, IconMail, IconUser } from '@tabler/icons-react';
|
||||
import { useParams } from 'next/navigation';
|
||||
import { useState } from 'react';
|
||||
import { useProxy } from 'valtio/utils';
|
||||
@@ -17,6 +37,7 @@ const layanan = [
|
||||
'Konsultasi Gizi',
|
||||
'Pemeriksaan Kesehatan'
|
||||
];
|
||||
|
||||
function Page() {
|
||||
const combobox = useCombobox({
|
||||
onDropdownClose: () => combobox.resetSelectedOption(),
|
||||
@@ -30,192 +51,160 @@ function Page() {
|
||||
});
|
||||
|
||||
const [value, setValue] = useState<string | null>('');
|
||||
const [dateInputOpened, setDateInputOpened] = useState(false);
|
||||
const params = useParams();
|
||||
const state = useProxy(jadwalkegiatanState);
|
||||
|
||||
useShallowEffect(() => {
|
||||
state.findUnique.load(params?.id as string);
|
||||
}, []);
|
||||
|
||||
const options = layanan.map((item) => (
|
||||
<ComboboxOption value={item} key={item} active={item === value}>
|
||||
<Group gap="xs">
|
||||
{item === value && <CheckIcon size={12} />}
|
||||
{item === value && <IconUser size={14} stroke={2} />}
|
||||
<span>{item}</span>
|
||||
</Group>
|
||||
</ComboboxOption>
|
||||
));
|
||||
const [dateInputOpened, setDateInputOpened] = useState(false);
|
||||
|
||||
const pickerControl = (
|
||||
<ActionIcon onClick={() => setDateInputOpened(true)} variant="subtle" color="gray">
|
||||
<ActionIcon onClick={() => setDateInputOpened(true)} variant="light" color="blue">
|
||||
<IconCalendar size={18} />
|
||||
</ActionIcon>
|
||||
);
|
||||
|
||||
|
||||
const params = useParams()
|
||||
const state = useProxy(jadwalkegiatanState)
|
||||
useShallowEffect(() => {
|
||||
state.findUnique.load(params?.id as string)
|
||||
}, [])
|
||||
|
||||
if (!state.findUnique.data) {
|
||||
return (
|
||||
<Stack py={10}>
|
||||
<Skeleton h={500} />
|
||||
<Stack py="xl" px="lg">
|
||||
<Skeleton h={500} radius="lg" />
|
||||
</Stack>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Stack pos={"relative"} bg={colors.Bg} py={"xl"} gap={"22"}>
|
||||
<Stack pos="relative" bg={colors.Bg} py="xl" gap="lg">
|
||||
<Box px={{ base: 'md', md: 100 }}>
|
||||
<BackButton />
|
||||
</Box>
|
||||
<Box px={{ base: "md", md: 100 }}>
|
||||
<Stack gap={'lg'}>
|
||||
<Paper radius={10}>
|
||||
<Box style={{ borderTopLeftRadius: 10, borderTopRightRadius: 10 }} bg={colors['blue-button']}>
|
||||
<Text p={'md'} fz={{ base: "h3", md: "h2" }} c={colors['white-1']} fw={"bold"}>
|
||||
<Stack gap="lg">
|
||||
<Paper radius="xl" shadow="md">
|
||||
<Box
|
||||
style={{ borderTopLeftRadius: 16, borderTopRightRadius: 16 }}
|
||||
bg={colors['blue-button']}
|
||||
>
|
||||
<Text p="md" fz={{ base: "h3", md: "h2" }} c={colors['white-1']} fw="bold">
|
||||
Detail & Pendaftaran Kegiatan
|
||||
</Text>
|
||||
</Box>
|
||||
<Box p={'md'} >
|
||||
<Stack gap={'xs'}>
|
||||
{/* Informasi Kegiatan */}
|
||||
<Text fz={'h4'} fw={"bold"}>
|
||||
Informasi Kegiatan
|
||||
</Text>
|
||||
<Divider />
|
||||
<Text fz={'h4'} fw={"bold"}>
|
||||
Nama Kegiatan : <Text span fz={'h4'}>{state.findUnique.data.informasijadwalkegiatan.name}</Text>
|
||||
</Text>
|
||||
<Text fz={'h4'} fw={"bold"}>
|
||||
Tanggal : <Text span fz={'h4'}>{state.findUnique.data.informasijadwalkegiatan.tanggal}</Text>
|
||||
</Text>
|
||||
<Text fz={'h4'} fw={"bold"}>
|
||||
Waktu : <Text span fz={'h4'}>{state.findUnique.data.informasijadwalkegiatan.waktu}</Text>
|
||||
</Text>
|
||||
<Text pb={10} fz={'h4'} fw={"bold"}>
|
||||
Lokasi : <Text span fz={'h4'}>{state.findUnique.data.informasijadwalkegiatan.lokasi}</Text>
|
||||
</Text>
|
||||
{/* Deskripsi Kegiatan */}
|
||||
<Text fz={'h4'} fw={"bold"}>
|
||||
Deskripsi Kegiatan
|
||||
</Text>
|
||||
<Divider />
|
||||
<Text pb={10} ta={'justify'} fz={'h4'} dangerouslySetInnerHTML={{ __html: state.findUnique.data.deskripsijadwalkegiatan.deskripsi }} />
|
||||
{/* Layanan Yang Tersedia */}
|
||||
<Text fz={'h4'} fw={"bold"}>
|
||||
Layanan Yang Tersedia
|
||||
</Text>
|
||||
<Divider />
|
||||
<Text pb={10} ta={'justify'} fz={'h4'} dangerouslySetInnerHTML={{ __html: state.findUnique.data.layananjadwalkegiatan.content }} />
|
||||
{/* Syarat dan Ketentuan */}
|
||||
<Text fz={'h4'} fw={"bold"}>
|
||||
Syarat dan Ketentuan
|
||||
</Text>
|
||||
<Divider />
|
||||
<Text pb={10} ta={'justify'} fz={'h4'} dangerouslySetInnerHTML={{ __html: state.findUnique.data.syaratketentuanjadwalkegiatan.content }} />
|
||||
{/* Dokumen yang Perlu Dibawa */}
|
||||
<Text fz={'h4'} fw={"bold"}>
|
||||
Dokumen yang Perlu Dibawa
|
||||
</Text>
|
||||
<Divider />
|
||||
<Text pb={10} ta={'justify'} fz={'h4'} dangerouslySetInnerHTML={{ __html: state.findUnique.data.dokumenjadwalkegiatan.content }} />
|
||||
{/* Pendaftaran */}
|
||||
<Text fz={'h4'} fw={"bold"}>
|
||||
Pendaftaran
|
||||
</Text>
|
||||
<Divider />
|
||||
<Stack gap={'xs'} pb={20}>
|
||||
<TextInput
|
||||
styles={{ label: { fontSize: '16px', fontWeight: 'bold' }, }}
|
||||
w={{ base: '100%', md: '85%', lg: '75%', xl: '50%' }}
|
||||
label="Nama Balita"
|
||||
placeholder='Masukkan nama balita'
|
||||
/>
|
||||
<DateInput
|
||||
styles={{ label: { fontSize: '16px', fontWeight: 'bold' }, }}
|
||||
placeholder='dd/mm/yyyy'
|
||||
w={{ base: '100%', md: '85%', lg: '75%', xl: '50%' }}
|
||||
label="Tanggal Lahir"
|
||||
popoverProps={{ opened: dateInputOpened, onChange: setDateInputOpened }}
|
||||
rightSection={pickerControl}
|
||||
/>
|
||||
<TextInput
|
||||
styles={{ label: { fontSize: '16px', fontWeight: 'bold' }, }}
|
||||
w={{ base: '100%', md: '85%', lg: '75%', xl: '50%' }}
|
||||
label="Nama Orang Tua / Wali"
|
||||
placeholder='Masukkan nama orang tua / wali'
|
||||
/>
|
||||
<TextInput
|
||||
styles={{ label: { fontSize: '16px', fontWeight: 'bold' }, }}
|
||||
w={{ base: '100%', md: '85%', lg: '75%', xl: '50%' }}
|
||||
label="No. Telepon"
|
||||
placeholder='Masukkan no. telepon'
|
||||
/>
|
||||
<TextInput
|
||||
styles={{ label: { fontSize: '16px', fontWeight: 'bold' }, }}
|
||||
w={{ base: '100%', md: '85%', lg: '75%', xl: '50%' }}
|
||||
label="Alamat"
|
||||
placeholder='Masukkan alamat lengkap'
|
||||
/>
|
||||
{/* Layanan */}
|
||||
<Text fz={'16px'} fw={"bold"}>
|
||||
Layananan Yang Dibutuhkan
|
||||
</Text>
|
||||
<Box
|
||||
w={{ base: '100%', md: '85%', lg: '75%', xl: '50%' }}
|
||||
>
|
||||
<Combobox
|
||||
store={combobox}
|
||||
resetSelectionOnOptionHover
|
||||
withinPortal={false}
|
||||
onOptionSubmit={(val) => {
|
||||
setValue(val);
|
||||
combobox.updateSelectedOptionIndex('active');
|
||||
}}
|
||||
>
|
||||
<ComboboxTarget targetType="button">
|
||||
<InputBase
|
||||
component="button"
|
||||
type="button"
|
||||
pointer
|
||||
rightSection={<ComboboxChevron />}
|
||||
rightSectionPointerEvents="none"
|
||||
onClick={() => combobox.toggleDropdown()}
|
||||
>
|
||||
{value || <InputPlaceholder>Layanan</InputPlaceholder>}
|
||||
</InputBase>
|
||||
</ComboboxTarget>
|
||||
|
||||
<Combobox.Dropdown>
|
||||
<ComboboxOptions>{options}</ComboboxOptions>
|
||||
</Combobox.Dropdown>
|
||||
</Combobox>
|
||||
</Box>
|
||||
<Textarea
|
||||
pb={10}
|
||||
styles={{ label: { fontSize: '16px', fontWeight: 'bold' }, }} w={{ base: '100%', md: '85%', lg: '75%', xl: '50%' }}
|
||||
label="Catatan Khusus (Opsional)"
|
||||
placeholder='Masukkan catatan jika ada'
|
||||
/>
|
||||
<Button
|
||||
w={{ base: '100%', md: '85%', lg: '75%', xl: '50%' }}
|
||||
fz={'md'} bg={colors['blue-button']}>
|
||||
Daftar Sekarang
|
||||
</Button>
|
||||
<Box p="lg">
|
||||
<Stack gap="xl">
|
||||
<Stack gap="sm">
|
||||
<Text fz="lg" fw="bold">Informasi Kegiatan</Text>
|
||||
<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>
|
||||
</Stack>
|
||||
<Paper p={'lg'} bg={colors['blue-button-trans']}>
|
||||
<Text fz={'h3'} c={colors['white-1']} fw={'bold'}>Informasi Kontak</Text>
|
||||
<Text fz={'h4'} c={colors['white-1']} fw={"bold"}>
|
||||
Penanggung Jawab : <Text span fz={'h4'}>Bidan Komang Ayu</Text>
|
||||
</Text>
|
||||
<Text fz={'h4'} c={colors['white-1']} fw={"bold"}>
|
||||
Telepon : <Text span fz={'h4'}>081234567890</Text>
|
||||
</Text>
|
||||
<Text fz={'h4'} c={colors['white-1']} fw={"bold"}>
|
||||
Email : <Text span fz={'h4'}>puskesmasabiansemal3@gmail.com</Text>
|
||||
</Text>
|
||||
|
||||
<Stack gap="sm">
|
||||
<Text fz="lg" fw="bold">Deskripsi Kegiatan</Text>
|
||||
<Divider />
|
||||
<Text ta="justify" fz="md" dangerouslySetInnerHTML={{ __html: state.findUnique.data.deskripsijadwalkegiatan.deskripsi }} />
|
||||
</Stack>
|
||||
|
||||
<Stack gap="sm">
|
||||
<Text fz="lg" fw="bold">Layanan yang Tersedia</Text>
|
||||
<Divider />
|
||||
<Text ta="justify" fz="md" dangerouslySetInnerHTML={{ __html: state.findUnique.data.layananjadwalkegiatan.content }} />
|
||||
</Stack>
|
||||
|
||||
<Stack gap="sm">
|
||||
<Text fz="lg" fw="bold">Syarat & Ketentuan</Text>
|
||||
<Divider />
|
||||
<Text ta="justify" fz="md" dangerouslySetInnerHTML={{ __html: state.findUnique.data.syaratketentuanjadwalkegiatan.content }} />
|
||||
</Stack>
|
||||
|
||||
<Stack gap="sm">
|
||||
<Text fz="lg" fw="bold">Dokumen yang Perlu Dibawa</Text>
|
||||
<Divider />
|
||||
<Text ta="justify" fz="md" dangerouslySetInnerHTML={{ __html: state.findUnique.data.dokumenjadwalkegiatan.content }} />
|
||||
</Stack>
|
||||
|
||||
<Stack gap="sm">
|
||||
<Text fz="lg" fw="bold">Formulir Pendaftaran</Text>
|
||||
<Divider />
|
||||
<Stack gap="md">
|
||||
<TextInput label="Nama Balita" placeholder="Masukkan nama balita" size="md" />
|
||||
<DateInput
|
||||
label="Tanggal Lahir"
|
||||
placeholder="dd/mm/yyyy"
|
||||
size="md"
|
||||
w={{ base: '100%', md: '85%', lg: '75%', xl: '50%' }}
|
||||
popoverProps={{ opened: dateInputOpened, onChange: setDateInputOpened }}
|
||||
rightSection={pickerControl}
|
||||
/>
|
||||
<TextInput label="Nama Orang Tua / Wali" placeholder="Masukkan nama orang tua / wali" size="md" />
|
||||
<TextInput label="Nomor Telepon" placeholder="Masukkan nomor telepon" size="md" />
|
||||
<TextInput label="Alamat" placeholder="Masukkan alamat lengkap" size="md" />
|
||||
<Box w={{ base: '100%', md: '85%', lg: '75%', xl: '50%' }}>
|
||||
<Text fz="sm" fw="bold" pb={4}>Pilih Layanan</Text>
|
||||
<Combobox
|
||||
store={combobox}
|
||||
resetSelectionOnOptionHover
|
||||
withinPortal={false}
|
||||
onOptionSubmit={(val) => {
|
||||
setValue(val);
|
||||
combobox.updateSelectedOptionIndex('active');
|
||||
}}
|
||||
>
|
||||
<ComboboxTarget targetType="button">
|
||||
<InputBase
|
||||
component="button"
|
||||
type="button"
|
||||
pointer
|
||||
rightSection={<ComboboxChevron />}
|
||||
rightSectionPointerEvents="none"
|
||||
onClick={() => combobox.toggleDropdown()}
|
||||
>
|
||||
{value || <InputPlaceholder>Pilih layanan</InputPlaceholder>}
|
||||
</InputBase>
|
||||
</ComboboxTarget>
|
||||
<Combobox.Dropdown>
|
||||
<ComboboxOptions>{options}</ComboboxOptions>
|
||||
</Combobox.Dropdown>
|
||||
</Combobox>
|
||||
</Box>
|
||||
<Textarea label="Catatan Khusus (Opsional)" placeholder="Masukkan catatan jika ada" size="md" />
|
||||
<Button size="md" radius="lg" bg={colors['blue-button']}>
|
||||
Daftar Sekarang
|
||||
</Button>
|
||||
</Stack>
|
||||
</Stack>
|
||||
|
||||
<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">
|
||||
<IconUser size={18} color="white" />
|
||||
<Text fz="md" c={colors['white-1']}>Penanggung Jawab: <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>
|
||||
</Group>
|
||||
<Group gap="xs">
|
||||
<IconMail size={18} color="white" />
|
||||
<Text fz="md" c={colors['white-1']}>puskesmasabiansemal3@gmail.com</Text>
|
||||
</Group>
|
||||
</Stack>
|
||||
</Paper>
|
||||
|
||||
<Group>
|
||||
<Button fz={'lg'} bg={'green'}>
|
||||
Download Jadwal Posyandu 2025 (PDF)
|
||||
<Button size="md" radius="lg" leftSection={<IconDownload size={18} />} color="green">
|
||||
Unduh Jadwal Posyandu 2025 (PDF)
|
||||
</Button>
|
||||
</Group>
|
||||
</Stack>
|
||||
@@ -227,5 +216,4 @@ function Page() {
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
export default Page;
|
||||
|
||||
@@ -1,53 +1,101 @@
|
||||
'use client'
|
||||
import jadwalkegiatanState from '@/app/admin/(dashboard)/_state/kesehatan/data_kesehatan_warga/jadwalKegiatan';
|
||||
import colors from '@/con/colors';
|
||||
import { Anchor, Box, Divider, Paper, Skeleton, Stack, Text } from '@mantine/core';
|
||||
import { Box, Button, Card, Divider, Group, Paper, Skeleton, Stack, Text } from '@mantine/core';
|
||||
import { useShallowEffect } from '@mantine/hooks';
|
||||
import { IconChevronRight, IconClockHour4, IconMapPin } from '@tabler/icons-react';
|
||||
import { useRouter } from 'next/navigation';
|
||||
import { useProxy } from 'valtio/utils';
|
||||
|
||||
function JadwalKegiatanPage() {
|
||||
const state = useProxy(jadwalkegiatanState)
|
||||
const state = useProxy(jadwalkegiatanState);
|
||||
const router = useRouter();
|
||||
|
||||
useShallowEffect(()=> {
|
||||
state.findMany.load()
|
||||
}, [])
|
||||
useShallowEffect(() => {
|
||||
state.findMany.load();
|
||||
}, []);
|
||||
|
||||
if(!state.findMany.data){
|
||||
if (!state.findMany.data) {
|
||||
return (
|
||||
<Box py={10}>
|
||||
<Skeleton h={500} />
|
||||
<Box py="lg">
|
||||
<Skeleton h={500} radius="lg" />
|
||||
</Box>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Box>
|
||||
<Paper p={'xl'} h={'112vh'} bg={colors['white-trans-1']}>
|
||||
<Stack gap={'xs'}>
|
||||
<Text ta={'center'} fw={"bold"} fz={'h3'} c={colors['blue-button']}>Jadwal Kegiatan</Text>
|
||||
{state.findMany.data.map((item) => (
|
||||
<Box key={item.id}>
|
||||
<Text fz={'h4'} fw={'bold'}>
|
||||
{item.informasijadwalkegiatan.name}
|
||||
<Paper p="xl" bg={colors['white-trans-1']} radius="xl" shadow="md" h="auto" mih="100vh">
|
||||
<Stack gap="lg">
|
||||
<Text ta="center" fw={700} fz="32px" c={colors['blue-button']}>
|
||||
Jadwal Kegiatan Warga
|
||||
</Text>
|
||||
|
||||
{state.findMany.data.length === 0 ? (
|
||||
<Box py="xl" ta="center">
|
||||
<Text fz="lg" c="dimmed">
|
||||
Belum ada jadwal kegiatan yang tersedia
|
||||
</Text>
|
||||
<Text fz={'h4'}>
|
||||
{item.informasijadwalkegiatan.waktu}
|
||||
</Text>
|
||||
<Text fz={'h4'}>
|
||||
{item.informasijadwalkegiatan.lokasi}
|
||||
</Text>
|
||||
<Text fz={'h6'} fw={'bold'} c={colors['blue-button']}>
|
||||
{item.informasijadwalkegiatan.tanggal}
|
||||
</Text>
|
||||
<Anchor onClick={()=> router.push(`/darmasaba/kesehatan/data-kesehatan-warga/jadwal-kegiatan-page/${item.id}`)} c={colors['blue-button']} variant='transparent'>
|
||||
<Text c={colors['blue-button']} fz={'h4'} >
|
||||
Detail & Pendaftaran
|
||||
</Text>
|
||||
</Anchor>
|
||||
</Box>
|
||||
))}
|
||||
<Divider color={colors['blue-button']} px={'xl'} />
|
||||
) : (
|
||||
state.findMany.data.map((item) => (
|
||||
<Card
|
||||
key={item.id}
|
||||
withBorder
|
||||
radius="xl"
|
||||
shadow="sm"
|
||||
p="lg"
|
||||
style={{ backdropFilter: 'blur(8px)' }}
|
||||
>
|
||||
<Stack gap="sm">
|
||||
<Group justify="space-between">
|
||||
<Text fw={700} fz="xl">
|
||||
{item.informasijadwalkegiatan.name}
|
||||
</Text>
|
||||
<Text fw={600} fz="sm" c={colors['blue-button']}>
|
||||
{item.informasijadwalkegiatan.tanggal}
|
||||
</Text>
|
||||
</Group>
|
||||
|
||||
<Group gap="xs">
|
||||
<IconClockHour4 size={18} color={colors['blue-button']} />
|
||||
<Text fz="sm">{item.informasijadwalkegiatan.waktu}</Text>
|
||||
</Group>
|
||||
|
||||
<Group gap="xs">
|
||||
<IconMapPin size={18} color={colors['blue-button']} />
|
||||
<Text fz="sm">{item.informasijadwalkegiatan.lokasi}</Text>
|
||||
</Group>
|
||||
|
||||
<Divider my="sm" />
|
||||
|
||||
<Group justify="flex-end">
|
||||
<Button
|
||||
variant="light"
|
||||
radius="lg"
|
||||
size="sm"
|
||||
rightSection={<IconChevronRight size={18} />}
|
||||
onClick={() =>
|
||||
router.push(
|
||||
`/darmasaba/kesehatan/data-kesehatan-warga/jadwal-kegiatan-page/${item.id}`
|
||||
)
|
||||
}
|
||||
styles={{
|
||||
root: {
|
||||
background: colors['blue-button'],
|
||||
color: 'white',
|
||||
boxShadow: '0 0 12px rgba(0, 123, 255, 0.4)',
|
||||
transition: 'all 0.2s ease',
|
||||
},
|
||||
}}
|
||||
>
|
||||
Lihat Detail & Daftar
|
||||
</Button>
|
||||
</Group>
|
||||
</Stack>
|
||||
</Card>
|
||||
))
|
||||
)}
|
||||
</Stack>
|
||||
</Paper>
|
||||
</Box>
|
||||
|
||||
@@ -1,100 +1,169 @@
|
||||
'use client'
|
||||
import infoWabahPenyakit from '@/app/admin/(dashboard)/_state/kesehatan/info-wabah-penyakit/infoWabahPenyakit';
|
||||
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,
|
||||
Badge,
|
||||
HoverCard,
|
||||
Divider,
|
||||
Group,
|
||||
} from '@mantine/core';
|
||||
import { useShallowEffect } from '@mantine/hooks';
|
||||
import { IconSearch } from '@tabler/icons-react';
|
||||
import { IconSearch, IconInfoCircle } from '@tabler/icons-react';
|
||||
import { useState } from 'react';
|
||||
import { useProxy } from 'valtio/utils';
|
||||
import BackButton from '../../desa/layanan/_com/BackButto';
|
||||
|
||||
function Page() {
|
||||
const state = useProxy(infoWabahPenyakit)
|
||||
const [search, setSearch] = useState('')
|
||||
const state = useProxy(infoWabahPenyakit);
|
||||
const [search, setSearch] = useState('');
|
||||
|
||||
const {
|
||||
data,
|
||||
page,
|
||||
totalPages,
|
||||
loading,
|
||||
load,
|
||||
} = state.findMany;
|
||||
const { data, page, totalPages, loading, load } = state.findMany;
|
||||
|
||||
useShallowEffect(() => {
|
||||
load(page, 3, search)
|
||||
}, [page, search])
|
||||
load(page, 6, search);
|
||||
}, [page, search]);
|
||||
|
||||
if (loading || !data) {
|
||||
return (
|
||||
<Box py={10}>
|
||||
<Skeleton h={500} />
|
||||
<Box py="xl" px={{ base: 'md', md: 100 }}>
|
||||
<Skeleton h={500} radius="lg" />
|
||||
</Box>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Stack pos={"relative"} bg={colors.Bg} py={"xl"} gap={"22"}>
|
||||
<Stack pos="relative" bg={colors.Bg} py="xl" gap="lg">
|
||||
<Box px={{ base: 'md', md: 100 }}>
|
||||
<BackButton />
|
||||
</Box>
|
||||
<Grid align='center' px={{ base: 'md', md: 100 }}>
|
||||
<GridCol span={{ base: 12, md: 9 }}>
|
||||
<Text fz={{ base: "h1", md: "2.5rem" }} c={colors["blue-button"]} fw={"bold"}>
|
||||
Info Wabah / Penyakit
|
||||
|
||||
<Grid align="center" px={{ base: 'md', md: 100 }}>
|
||||
<GridCol span={{ base: 12, md: 8 }}>
|
||||
<Text
|
||||
fz={{ base: '1.8rem', md: '2.8rem' }}
|
||||
c={colors['blue-button']}
|
||||
fw="bold"
|
||||
lh={1.2}
|
||||
>
|
||||
Informasi Wabah & Penyakit
|
||||
</Text>
|
||||
<Text fz="md" c="dimmed" mt={4}>
|
||||
Dapatkan informasi terbaru mengenai wabah dan penyakit yang sedang
|
||||
diawasi.
|
||||
</Text>
|
||||
</GridCol>
|
||||
<GridCol span={{ base: 12, md: 3 }}>
|
||||
<GridCol span={{ base: 12, md: 4 }}>
|
||||
<TextInput
|
||||
radius={"lg"}
|
||||
placeholder='Cari Info Wabah / Penyakit'
|
||||
radius="xl"
|
||||
placeholder="Cari nama penyakit atau wabah..."
|
||||
value={search}
|
||||
onChange={(e) => setSearch(e.target.value)}
|
||||
leftSection={<IconSearch size={20} />}
|
||||
w={{ base: "50%", md: "100%" }}
|
||||
w="100%"
|
||||
size="md"
|
||||
/>
|
||||
</GridCol>
|
||||
</Grid>
|
||||
<Box px={{ base: "md", md: 100 }}>
|
||||
<Stack gap={'lg'}>
|
||||
<SimpleGrid
|
||||
cols={{
|
||||
base: 1,
|
||||
md: 3,
|
||||
}}
|
||||
>
|
||||
{data.map((v, k) => {
|
||||
return (
|
||||
<Paper key={k} p={'xl'} bg={colors['white-trans-1']}>
|
||||
<Stack gap={'xs'}>
|
||||
<Box>
|
||||
<Text fw={"bold"} fz={'h3'} c={colors['blue-button']}>{v.name}</Text>
|
||||
<Image w={330} h={200} fit='contain' pt={5} src={v.image.link} alt={v.name} />
|
||||
<Text fz={'h4'} fw={'bold'} >
|
||||
{v.name}
|
||||
|
||||
<Box px={{ base: 'md', md: 100 }}>
|
||||
{data.length === 0 ? (
|
||||
<Center py="6xl">
|
||||
<Stack align="center" gap="sm">
|
||||
<IconInfoCircle size={50} color={colors['blue-button']} />
|
||||
<Text fz="lg" fw={500} c="dimmed">
|
||||
Tidak ada data yang cocok dengan pencarian Anda.
|
||||
</Text>
|
||||
</Stack>
|
||||
</Center>
|
||||
) : (
|
||||
<SimpleGrid cols={{ base: 1, sm: 2, md: 3 }} spacing="lg">
|
||||
{data.map((v, k) => (
|
||||
<Paper
|
||||
key={k}
|
||||
radius="lg"
|
||||
shadow="md"
|
||||
p="lg"
|
||||
withBorder
|
||||
bg={colors['white-trans-1']}
|
||||
style={{
|
||||
transition: 'transform 200ms ease, box-shadow 200ms ease',
|
||||
}}
|
||||
>
|
||||
<Stack gap="sm">
|
||||
<Image
|
||||
radius="md"
|
||||
h={180}
|
||||
src={v.image.link}
|
||||
alt={v.name}
|
||||
fit="cover"
|
||||
/>
|
||||
<Group justify="space-between" mt="sm">
|
||||
<Text fw={700} fz="lg" c={colors['blue-button']}>
|
||||
{v.name}
|
||||
</Text>
|
||||
<Badge color="blue" variant="light" radius="sm">
|
||||
Wabah
|
||||
</Badge>
|
||||
</Group>
|
||||
<Text fz="sm" c="dimmed">
|
||||
Diposting: 12 Februari 2025 · Dinas Kesehatan
|
||||
</Text>
|
||||
<Divider />
|
||||
<Text fz="sm" lh={1.5}>
|
||||
{v.deskripsiSingkat}
|
||||
</Text>
|
||||
<HoverCard shadow="md" position="bottom" radius="md" width={300}>
|
||||
<HoverCard.Target>
|
||||
<Text
|
||||
fz="sm"
|
||||
fw={500}
|
||||
c={colors['blue-button']}
|
||||
style={{ cursor: 'pointer' }}
|
||||
>
|
||||
Lihat detail lengkap
|
||||
</Text>
|
||||
<Text fz={'h6'} pb={10}>
|
||||
Diposting: 12 Februari 2025 | Dinas Kesehatan
|
||||
</Text>
|
||||
<Text fz={'h4'} pb={10}>
|
||||
{v.deskripsiSingkat}
|
||||
</Text>
|
||||
<Text fz={'h4'} pb={10} dangerouslySetInnerHTML={{ __html: v.deskripsiLengkap }} />
|
||||
</Box>
|
||||
</Stack>
|
||||
</Paper>
|
||||
)
|
||||
})}
|
||||
</HoverCard.Target>
|
||||
<HoverCard.Dropdown>
|
||||
<Text
|
||||
fz="sm"
|
||||
lh={1.6}
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: v.deskripsiLengkap,
|
||||
}}
|
||||
/>
|
||||
</HoverCard.Dropdown>
|
||||
</HoverCard>
|
||||
</Stack>
|
||||
</Paper>
|
||||
))}
|
||||
</SimpleGrid>
|
||||
</Stack>
|
||||
)}
|
||||
</Box>
|
||||
<Center>
|
||||
<Pagination
|
||||
value={page}
|
||||
onChange={(newPage) => load(newPage)} // ini penting!
|
||||
total={totalPages}
|
||||
mt="md"
|
||||
mb="md"
|
||||
/>
|
||||
</Center>
|
||||
|
||||
{totalPages > 1 && (
|
||||
<Center>
|
||||
<Pagination
|
||||
value={page}
|
||||
onChange={(newPage) => load(newPage)}
|
||||
total={totalPages}
|
||||
radius="xl"
|
||||
size="md"
|
||||
mt="lg"
|
||||
/>
|
||||
</Center>
|
||||
)}
|
||||
</Stack>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,106 +1,150 @@
|
||||
'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 { useProxy } from 'valtio/utils';
|
||||
import { useState } from 'react';
|
||||
|
||||
import { useProxy } from 'valtio/utils';
|
||||
import { useShallowEffect } from '@mantine/hooks';
|
||||
import {
|
||||
Box,
|
||||
Center,
|
||||
Grid,
|
||||
GridCol,
|
||||
Image,
|
||||
Pagination,
|
||||
Paper,
|
||||
SimpleGrid,
|
||||
Skeleton,
|
||||
Stack,
|
||||
Text,
|
||||
TextInput,
|
||||
Tooltip,
|
||||
Badge,
|
||||
} from '@mantine/core';
|
||||
import { IconSearch, IconPhone } from '@tabler/icons-react';
|
||||
import BackButton from '../../desa/layanan/_com/BackButto';
|
||||
import kontakDarurat from '@/app/admin/(dashboard)/_state/kesehatan/kontak-darurat/kontakDarurat';
|
||||
import { IconSearch } from '@tabler/icons-react';
|
||||
import colors from '@/con/colors';
|
||||
|
||||
function Page() {
|
||||
const state = useProxy(kontakDarurat)
|
||||
const [search, setSearch] = useState('')
|
||||
const state = useProxy(kontakDarurat);
|
||||
const [search, setSearch] = useState('');
|
||||
|
||||
const {
|
||||
data,
|
||||
page,
|
||||
totalPages,
|
||||
loading,
|
||||
load,
|
||||
} = state.findMany;
|
||||
const { data, page, totalPages, loading, load } = state.findMany;
|
||||
|
||||
useShallowEffect(() => {
|
||||
load(page, 3, search)
|
||||
}, [page, search])
|
||||
load(page, 6, search);
|
||||
}, [page, search]);
|
||||
|
||||
if (loading || !data) {
|
||||
return (
|
||||
<Box py={10}>
|
||||
<Skeleton h={500} />
|
||||
<Box py="xl" px={{ base: 'md', md: 100 }}>
|
||||
<Skeleton height={500} radius="lg" />
|
||||
</Box>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Stack pos={"relative"} bg={colors.Bg} py={"xl"} gap={"22"}>
|
||||
<Stack pos="relative" bg={colors.Bg} py="xl" gap="lg">
|
||||
<Box px={{ base: 'md', md: 100 }}>
|
||||
<BackButton />
|
||||
</Box>
|
||||
<Grid align='center' px={{ base: 'md', md: 100 }}>
|
||||
<GridCol span={{ base: 12, md: 9 }}>
|
||||
<Text fz={{ base: "h1", md: "2.5rem" }} c={colors["blue-button"]} fw={"bold"}>
|
||||
Penanganan Darurat
|
||||
|
||||
<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}>
|
||||
Kontak Darurat
|
||||
</Text>
|
||||
<Text c="dimmed" fz="md" mt={4}>
|
||||
Hubungi layanan penting dengan cepat dan mudah
|
||||
</Text>
|
||||
</GridCol>
|
||||
<GridCol span={{ base: 12, md: 3 }}>
|
||||
<TextInput
|
||||
radius={"lg"}
|
||||
placeholder='Cari Penanganan Darurat'
|
||||
value={search}
|
||||
onChange={(e) => setSearch(e.target.value)}
|
||||
leftSection={<IconSearch size={20} />}
|
||||
w={{ base: "50%", md: "100%" }}
|
||||
/>
|
||||
<GridCol span={{ base: 12, md: 4 }}>
|
||||
<Tooltip label="Cari berdasarkan nama atau deskripsi" withArrow>
|
||||
<TextInput
|
||||
radius="xl"
|
||||
size="md"
|
||||
placeholder="Cari kontak darurat..."
|
||||
value={search}
|
||||
onChange={(e) => setSearch(e.target.value)}
|
||||
leftSection={<IconSearch size={20} />}
|
||||
w="100%"
|
||||
/>
|
||||
</Tooltip>
|
||||
</GridCol>
|
||||
</Grid>
|
||||
<Box px={{ base: "md", md: 100 }}>
|
||||
<Stack gap={'lg'}>
|
||||
<SimpleGrid
|
||||
pb={10}
|
||||
cols={{
|
||||
base: 1,
|
||||
md: 3,
|
||||
}}>
|
||||
{data.map((v, k) => {
|
||||
return (
|
||||
<Paper radius={10} key={k} bg={colors["white-trans-1"]}>
|
||||
<Stack gap={'xs'}>
|
||||
<Center py={40}>
|
||||
<Image
|
||||
src={v.image.link}
|
||||
alt={v.name}
|
||||
w={200}
|
||||
h={200}
|
||||
fit='contain'
|
||||
/>
|
||||
</Center>
|
||||
<Box px={'lg'}>
|
||||
<Box pb={20}>
|
||||
<Text pb={10} c={colors["blue-button"]} fw={"bold"} fz={"h3"}>
|
||||
{v.name}
|
||||
</Text>
|
||||
<Box px={10}>
|
||||
<Text fz={"h4"} dangerouslySetInnerHTML={{ __html: v.deskripsi }} />
|
||||
</Box>
|
||||
</Box>
|
||||
</Box>
|
||||
</Stack>
|
||||
</Paper>
|
||||
)
|
||||
})}
|
||||
|
||||
<Box px={{ base: 'md', md: 100 }}>
|
||||
{data.length === 0 ? (
|
||||
<Center mih={300}>
|
||||
<Stack align="center" gap="xs">
|
||||
<IconSearch size={50} color={colors['blue-button']} />
|
||||
<Text fz="lg" fw={600} c={colors['blue-button']}>
|
||||
Tidak ada kontak ditemukan
|
||||
</Text>
|
||||
<Text fz="sm" c="dimmed">
|
||||
Coba kata kunci lain untuk pencarian
|
||||
</Text>
|
||||
</Stack>
|
||||
</Center>
|
||||
) : (
|
||||
<SimpleGrid cols={{ base: 1, sm: 2, md: 3 }} spacing="xl" mt="lg">
|
||||
{data.map((v, k) => (
|
||||
<Paper
|
||||
key={k}
|
||||
radius="xl"
|
||||
shadow="md"
|
||||
withBorder
|
||||
p="lg"
|
||||
bg={colors['white-trans-1']}
|
||||
style={{
|
||||
transition: 'all 200ms ease',
|
||||
cursor: 'pointer',
|
||||
}}
|
||||
>
|
||||
<Stack align="center" gap="sm">
|
||||
<Image
|
||||
src={v.image.link}
|
||||
alt={v.name}
|
||||
w={140}
|
||||
h={140}
|
||||
fit="contain"
|
||||
radius="md"
|
||||
/>
|
||||
<Text ta="center" fw={700} fz="lg" c={colors['blue-button']}>
|
||||
{v.name}
|
||||
</Text>
|
||||
<Text fz="sm" c="dimmed" ta="center" lineClamp={3}>
|
||||
<span dangerouslySetInnerHTML={{ __html: v.deskripsi }} />
|
||||
</Text>
|
||||
<Badge
|
||||
color="blue"
|
||||
leftSection={<IconPhone size={14} />}
|
||||
variant="light"
|
||||
mt="sm"
|
||||
>
|
||||
Panggil Sekarang
|
||||
</Badge>
|
||||
</Stack>
|
||||
</Paper>
|
||||
))}
|
||||
</SimpleGrid>
|
||||
</Stack>
|
||||
)}
|
||||
</Box>
|
||||
<Center>
|
||||
<Pagination
|
||||
value={page}
|
||||
onChange={(newPage) => load(newPage)} // ini penting!
|
||||
total={totalPages}
|
||||
mt="md"
|
||||
mb="md"
|
||||
/>
|
||||
</Center>
|
||||
|
||||
{totalPages > 1 && (
|
||||
<Center mt="xl">
|
||||
<Pagination
|
||||
value={page}
|
||||
onChange={(newPage) => load(newPage, 6, search)}
|
||||
total={totalPages}
|
||||
radius="xl"
|
||||
size="md"
|
||||
styles={{
|
||||
control: {
|
||||
borderRadius: '999px',
|
||||
},
|
||||
}}
|
||||
/>
|
||||
</Center>
|
||||
)}
|
||||
</Stack>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,108 +1,162 @@
|
||||
'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 { useProxy } from 'valtio/utils';
|
||||
import { useState } from 'react';
|
||||
|
||||
import { useShallowEffect } from '@mantine/hooks';
|
||||
import penangananDarurat from '@/app/admin/(dashboard)/_state/kesehatan/penanganan-darurat/penangananDarurat';
|
||||
import { IconSearch } from '@tabler/icons-react';
|
||||
import penangananDarurat from '@/app/admin/(dashboard)/_state/kesehatan/penanganan-darurat/penangananDarurat'
|
||||
import colors from '@/con/colors'
|
||||
import {
|
||||
Badge,
|
||||
Box,
|
||||
Center,
|
||||
Grid,
|
||||
GridCol,
|
||||
Image,
|
||||
Pagination,
|
||||
Paper,
|
||||
SimpleGrid,
|
||||
Skeleton,
|
||||
Stack,
|
||||
Text,
|
||||
TextInput,
|
||||
Tooltip
|
||||
} from '@mantine/core'
|
||||
import { useShallowEffect } from '@mantine/hooks'
|
||||
import { IconSearch } from '@tabler/icons-react'
|
||||
import { useState } from 'react'
|
||||
import { useProxy } from 'valtio/utils'
|
||||
import BackButton from '../../desa/layanan/_com/BackButto'
|
||||
|
||||
function Page() {
|
||||
const state = useProxy(penangananDarurat)
|
||||
const [search, setSearch] = useState('')
|
||||
|
||||
const {
|
||||
data,
|
||||
page,
|
||||
totalPages,
|
||||
loading,
|
||||
load,
|
||||
} = state.findMany;
|
||||
const { data, page, totalPages, loading, load } = state.findMany
|
||||
|
||||
useShallowEffect(() => {
|
||||
load(page, 3, search)
|
||||
load(page, 6, search)
|
||||
}, [page, search])
|
||||
|
||||
if (loading || !data) {
|
||||
return (
|
||||
<Box py={10}>
|
||||
<Skeleton h={500} />
|
||||
<Box py="xl" px={{ base: 'md', md: 100 }}>
|
||||
<Skeleton h={500} radius="lg" />
|
||||
</Box>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<Stack pos={"relative"} bg={colors.Bg} py={"xl"} gap={"22"}>
|
||||
<Stack bg={colors.Bg} py="xl" gap="xl" pos="relative">
|
||||
<Box px={{ base: 'md', md: 100 }}>
|
||||
<BackButton />
|
||||
</Box>
|
||||
<Grid align='center' px={{ base: 'md', md: 100 }}>
|
||||
|
||||
<Grid align="center" px={{ base: 'md', md: 100 }} mb="lg">
|
||||
<GridCol span={{ base: 12, md: 9 }}>
|
||||
<Text fz={{ base: "h1", md: "2.5rem" }} c={colors["blue-button"]} fw={"bold"}>
|
||||
<Text fz={{ base: 30, md: 40 }} c={colors['blue-button']} fw={800} lh={1.2}>
|
||||
Penanganan Darurat
|
||||
</Text>
|
||||
<Text fz="md" c="dimmed" mt={4}>
|
||||
Informasi cepat dan jelas untuk situasi darurat kesehatan
|
||||
</Text>
|
||||
</GridCol>
|
||||
<GridCol span={{ base: 12, md: 3 }}>
|
||||
<TextInput
|
||||
radius={"lg"}
|
||||
placeholder='Cari Penanganan Darurat'
|
||||
value={search}
|
||||
onChange={(e) => setSearch(e.target.value)}
|
||||
leftSection={<IconSearch size={20} />}
|
||||
w={{ base: "50%", md: "100%" }}
|
||||
/>
|
||||
<Tooltip label="Ketik kata kunci untuk mencari penanganan darurat">
|
||||
<TextInput
|
||||
radius="lg"
|
||||
placeholder="Cari penanganan darurat..."
|
||||
value={search}
|
||||
onChange={(e) => setSearch(e.target.value)}
|
||||
leftSection={<IconSearch size={20} />}
|
||||
w="100%"
|
||||
/>
|
||||
</Tooltip>
|
||||
</GridCol>
|
||||
</Grid>
|
||||
<Box px={{ base: "md", md: 100 }}>
|
||||
<Stack gap={'lg'}>
|
||||
|
||||
<Box px={{ base: 'md', md: 100 }}>
|
||||
{data.length === 0 ? (
|
||||
<Center py={100}>
|
||||
<Stack align="center" gap="xs">
|
||||
<Text fz="lg" fw={600} c={colors['blue-button']}>
|
||||
Tidak ada data ditemukan
|
||||
</Text>
|
||||
<Text fz="sm" c="dimmed">
|
||||
Coba gunakan kata kunci lain
|
||||
</Text>
|
||||
</Stack>
|
||||
</Center>
|
||||
) : (
|
||||
<SimpleGrid
|
||||
pb={10}
|
||||
cols={{
|
||||
base: 1,
|
||||
md: 3,
|
||||
}}>
|
||||
{data.map((v, k) => {
|
||||
return (
|
||||
<Paper radius={10} key={k} bg={colors["white-trans-1"]}>
|
||||
<Stack gap={'xs'}>
|
||||
<Center py={40}>
|
||||
<Image
|
||||
src={v.image.link}
|
||||
alt={v.name}
|
||||
w={200}
|
||||
h={200}
|
||||
fit='contain'
|
||||
cols={{ base: 1, sm: 2, md: 3 }}
|
||||
spacing="xl"
|
||||
verticalSpacing="xl"
|
||||
pb={20}
|
||||
>
|
||||
{data.map((v, k) => (
|
||||
<Paper
|
||||
key={k}
|
||||
radius="xl"
|
||||
p="md"
|
||||
shadow="sm"
|
||||
withBorder
|
||||
bg={colors['white-trans-1']}
|
||||
style={{ transition: 'all 0.3s ease' }}
|
||||
>
|
||||
<Stack align="center" gap="md">
|
||||
<Center>
|
||||
<Image
|
||||
src={v.image.link}
|
||||
alt={v.name}
|
||||
w={160}
|
||||
h={160}
|
||||
fit="contain"
|
||||
radius="md"
|
||||
/>
|
||||
</Center>
|
||||
<Stack gap={4} w="100%">
|
||||
<Text
|
||||
fz="lg"
|
||||
fw={700}
|
||||
c={colors['blue-button']}
|
||||
ta="center"
|
||||
lineClamp={2}
|
||||
>
|
||||
{v.name}
|
||||
</Text>
|
||||
<Box>
|
||||
<Text
|
||||
fz="sm"
|
||||
c="dimmed"
|
||||
lineClamp={4}
|
||||
dangerouslySetInnerHTML={{ __html: v.deskripsi }}
|
||||
/>
|
||||
</Center>
|
||||
<Box px={'lg'}>
|
||||
<Box pb={20}>
|
||||
<Text pb={10} c={colors["blue-button"]} fw={"bold"} fz={"h3"}>
|
||||
{v.name}
|
||||
</Text>
|
||||
<Box px={10}>
|
||||
<Text fz={"h4"} dangerouslySetInnerHTML={{ __html: v.deskripsi }} />
|
||||
</Box>
|
||||
</Box>
|
||||
</Box>
|
||||
</Stack>
|
||||
</Paper>
|
||||
)
|
||||
})}
|
||||
<Badge radius="md" color="blue" variant="light" mt="sm">
|
||||
Darurat
|
||||
</Badge>
|
||||
</Stack>
|
||||
</Paper>
|
||||
))}
|
||||
</SimpleGrid>
|
||||
</Stack>
|
||||
)}
|
||||
</Box>
|
||||
<Center>
|
||||
<Pagination
|
||||
value={page}
|
||||
onChange={(newPage) => load(newPage)} // ini penting!
|
||||
total={totalPages}
|
||||
mt="md"
|
||||
mb="md"
|
||||
/>
|
||||
</Center>
|
||||
|
||||
{totalPages > 1 && (
|
||||
<Center mt="xl">
|
||||
<Pagination
|
||||
value={page}
|
||||
onChange={(newPage) => load(newPage, 6, search)}
|
||||
total={totalPages}
|
||||
size="lg"
|
||||
radius="xl"
|
||||
styles={{
|
||||
control: {
|
||||
border: `1px solid ${colors['blue-button']}`,
|
||||
},
|
||||
}}
|
||||
/>
|
||||
</Center>
|
||||
)}
|
||||
</Stack>
|
||||
);
|
||||
)
|
||||
}
|
||||
|
||||
export default Page;
|
||||
export default Page
|
||||
|
||||
@@ -1,119 +1,166 @@
|
||||
'use client'
|
||||
import colors from "@/con/colors";
|
||||
import { Box, Center, Flex, Image, List, ListItem, Pagination, Paper, SimpleGrid, Skeleton, Spoiler, Stack, Text, TextInput } from "@mantine/core";
|
||||
import BackButton from "../../desa/layanan/_com/BackButto";
|
||||
// import { useTransitionRouter } from "next-view-transitions";
|
||||
import posyandustate from "@/app/admin/(dashboard)/_state/kesehatan/posyandu/posyandu";
|
||||
import colors from "@/con/colors";
|
||||
import { Badge, Box, Center, Flex, Image, List, ListItem, Pagination, Paper, SimpleGrid, Skeleton, Spoiler, Stack, Text, TextInput } from "@mantine/core";
|
||||
import { useShallowEffect } from "@mantine/hooks";
|
||||
import { useProxy } from "valtio/utils";
|
||||
import { IconCalendar, IconInfoCircle, IconPhone, IconSearch } from "@tabler/icons-react";
|
||||
import { useState } from "react";
|
||||
import { IconSearch } from "@tabler/icons-react";
|
||||
import { useProxy } from "valtio/utils";
|
||||
import BackButton from "../../desa/layanan/_com/BackButto";
|
||||
|
||||
export default function Page() {
|
||||
const state = useProxy(posyandustate)
|
||||
// const router = useTransitionRouter()
|
||||
const [search, setSearch] = useState("")
|
||||
const state = useProxy(posyandustate);
|
||||
const [search, setSearch] = useState("");
|
||||
|
||||
const {
|
||||
data,
|
||||
page,
|
||||
totalPages,
|
||||
loading,
|
||||
load,
|
||||
} = state.findMany;
|
||||
const { data, page, totalPages, loading, load } = state.findMany;
|
||||
|
||||
useShallowEffect(() => {
|
||||
load(page, 6, search);
|
||||
}, [page, search]);
|
||||
|
||||
useShallowEffect(() => {
|
||||
load(page, 3, search)
|
||||
}, [page, search])
|
||||
|
||||
if (loading || !data) {
|
||||
return (
|
||||
<Box py={10}>
|
||||
<Skeleton h={500} />
|
||||
</Box>
|
||||
)
|
||||
}
|
||||
|
||||
if (loading || !data) {
|
||||
return (
|
||||
<Stack pos={"relative"} bg={colors.Bg} py={"xl"} gap={"22"}>
|
||||
<Box px={{ base: 'md', md: 100 }}>
|
||||
<BackButton />
|
||||
<Flex mt={10} justify={"space-between"} align={"center"}>
|
||||
<Text ta={"center"} fz={{ base: "h1", md: "2.5rem" }} c={colors["blue-button"]} fw={"bold"}>
|
||||
Posyandu Darmasaba
|
||||
</Text>
|
||||
<TextInput
|
||||
placeholder="Cari Posyandu"
|
||||
radius="lg"
|
||||
leftSection={<IconSearch size={20} />}
|
||||
w={{ base: "25%", md: "30%" }}
|
||||
value={search}
|
||||
onChange={(e) => setSearch(e.currentTarget.value)}
|
||||
/>
|
||||
</Flex>
|
||||
</Box>
|
||||
<Box px={{ base: "md", md: 100 }}>
|
||||
<Stack gap={'lg'}>
|
||||
<SimpleGrid
|
||||
pb={10}
|
||||
cols={{
|
||||
base: 1,
|
||||
md: 3,
|
||||
}}>
|
||||
{data?.map((v, k) => {
|
||||
return (
|
||||
<Paper key={k} p={"xl"} bg={colors["white-trans-1"]}>
|
||||
<Stack gap={'xs'}>
|
||||
<Text c={colors["blue-button"]} fw={"bold"} fz={"h3"}>
|
||||
{v.name}
|
||||
</Text>
|
||||
<Center>
|
||||
<Image src={v.image.link} alt="" />
|
||||
</Center>
|
||||
<Text fz={'h4'}>
|
||||
No.Telp : {v.nomor}
|
||||
</Text>
|
||||
<Box>
|
||||
<Text fz={'h4'}>
|
||||
Jadwal Pelayanan
|
||||
</Text>
|
||||
<Text fz={'h4'} dangerouslySetInnerHTML={{ __html: v.jadwalPelayanan }} />
|
||||
</Box>
|
||||
<Spoiler
|
||||
maxHeight={60} // tinggi maksimum sebelum di-collapse
|
||||
showLabel="Read more"
|
||||
hideLabel="Read less"
|
||||
>
|
||||
<Text fz={'h4'} dangerouslySetInnerHTML={{ __html: v.deskripsi }} />
|
||||
</Spoiler>
|
||||
</Stack>
|
||||
</Paper>
|
||||
)
|
||||
})}
|
||||
</SimpleGrid>
|
||||
<Center>
|
||||
<Pagination
|
||||
value={page}
|
||||
onChange={(newPage) => load(newPage)} // ini penting!
|
||||
total={totalPages}
|
||||
mt="md"
|
||||
mb="md"
|
||||
/>
|
||||
</Center>
|
||||
<Text fz={'h4'} fw={"bold"}>
|
||||
Pelayanan Posyandu
|
||||
</Text>
|
||||
<List type="ordered">
|
||||
<ListItem fz={'h4'}>Penimbangan bayi dan balita</ListItem>
|
||||
<ListItem fz={'h4'}>Pemantuan status gizi</ListItem>
|
||||
<ListItem fz={'h4'}>Imunisasi dasar lengkap</ListItem>
|
||||
<ListItem fz={'h4'}>Konseling</ListItem>
|
||||
<ListItem fz={'h4'}>Pemantuan kesehatan ibu hamil</ListItem>
|
||||
</List>
|
||||
</Stack>
|
||||
</Box>
|
||||
</Stack>
|
||||
<Box py="xl" px={{ base: "md", md: 100 }}>
|
||||
<Skeleton h={500} radius="lg" />
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
)
|
||||
}
|
||||
return (
|
||||
<Stack pos="relative" bg={colors.Bg} py="xl" gap="xl">
|
||||
<Box px={{ base: "md", md: 100 }}>
|
||||
<BackButton />
|
||||
<Flex mt="md" justify="space-between" align="center" wrap="wrap" gap="md">
|
||||
<Text
|
||||
ta="left"
|
||||
fz={{ base: "1.8rem", md: "2.5rem" }}
|
||||
c={colors["blue-button"]}
|
||||
fw="bold"
|
||||
>
|
||||
Posyandu Desa Darmasaba
|
||||
</Text>
|
||||
<TextInput
|
||||
placeholder="Cari posyandu berdasarkan nama..."
|
||||
aria-label="Pencarian Posyandu"
|
||||
radius="xl"
|
||||
size="md"
|
||||
leftSection={<IconSearch size={20} />}
|
||||
w={{ base: "100%", md: "35%" }}
|
||||
value={search}
|
||||
onChange={(e) => setSearch(e.currentTarget.value)}
|
||||
/>
|
||||
</Flex>
|
||||
</Box>
|
||||
|
||||
<Box px={{ base: "md", md: 100 }}>
|
||||
<Stack gap="xl">
|
||||
<SimpleGrid
|
||||
pb="lg"
|
||||
cols={{ base: 1, sm: 2, md: 3 }}
|
||||
spacing="lg"
|
||||
>
|
||||
{data?.map((v, k) => (
|
||||
<Paper
|
||||
key={k}
|
||||
p="xl"
|
||||
radius="lg"
|
||||
shadow="md"
|
||||
withBorder
|
||||
bg={colors["white-trans-1"]}
|
||||
style={{
|
||||
transition: "transform 0.2s ease, box-shadow 0.2s ease",
|
||||
}}
|
||||
onMouseEnter={(e) => {
|
||||
(e.currentTarget as HTMLElement).style.transform = "translateY(-4px)";
|
||||
(e.currentTarget as HTMLElement).style.boxShadow =
|
||||
"0 8px 24px rgba(0,0,0,0.12)";
|
||||
}}
|
||||
onMouseLeave={(e) => {
|
||||
(e.currentTarget as HTMLElement).style.transform = "translateY(0)";
|
||||
(e.currentTarget as HTMLElement).style.boxShadow =
|
||||
"0 4px 12px rgba(0,0,0,0.08)";
|
||||
}}
|
||||
>
|
||||
<Stack gap="sm">
|
||||
<Flex justify="space-between" align="center">
|
||||
<Text c={colors["blue-button"]} fw="bold" fz="lg" lineClamp={1}>
|
||||
{v.name}
|
||||
</Text>
|
||||
<Badge color="blue" variant="light" size="sm" radius="sm">
|
||||
Aktif
|
||||
</Badge>
|
||||
</Flex>
|
||||
<Center>
|
||||
<Image
|
||||
src={v.image.link}
|
||||
alt={`Gambar ${v.name}`}
|
||||
radius="md"
|
||||
w="100%"
|
||||
h={180}
|
||||
fit="cover"
|
||||
/>
|
||||
</Center>
|
||||
<Flex align="center" gap="xs">
|
||||
<IconPhone size={18} stroke={1.5} />
|
||||
<Text fz="sm" c="dimmed">
|
||||
{v.nomor || "Tidak tersedia"}
|
||||
</Text>
|
||||
</Flex>
|
||||
<Flex align="center" gap="xs">
|
||||
<IconCalendar size={18} stroke={1.5} />
|
||||
<Text fz="sm" c="dimmed">
|
||||
Jadwal:{" "}
|
||||
<span dangerouslySetInnerHTML={{ __html: v.jadwalPelayanan }} />
|
||||
</Text>
|
||||
</Flex>
|
||||
<Spoiler
|
||||
maxHeight={70}
|
||||
showLabel="Lihat selengkapnya"
|
||||
hideLabel="Sembunyikan"
|
||||
transitionDuration={300}
|
||||
>
|
||||
<Text
|
||||
fz="sm"
|
||||
lh={1.5}
|
||||
dangerouslySetInnerHTML={{ __html: v.deskripsi }}
|
||||
/>
|
||||
</Spoiler>
|
||||
</Stack>
|
||||
</Paper>
|
||||
))}
|
||||
</SimpleGrid>
|
||||
|
||||
{totalPages > 1 && (
|
||||
<Center>
|
||||
<Pagination
|
||||
value={page}
|
||||
onChange={(newPage) => load(newPage)}
|
||||
total={totalPages}
|
||||
radius="lg"
|
||||
size="md"
|
||||
withControls
|
||||
mt="md"
|
||||
/>
|
||||
</Center>
|
||||
)}
|
||||
|
||||
<Stack gap="sm">
|
||||
<Flex align="center" gap="xs">
|
||||
<IconInfoCircle size={22} color={colors["blue-button"]} />
|
||||
<Text fz="lg" fw="bold" c={colors["blue-button"]}>
|
||||
Layanan Utama Posyandu
|
||||
</Text>
|
||||
</Flex>
|
||||
<List spacing="xs" size="sm" center>
|
||||
<ListItem>Penimbangan bayi dan balita</ListItem>
|
||||
<ListItem>Pemantauan status gizi</ListItem>
|
||||
<ListItem>Imunisasi dasar lengkap</ListItem>
|
||||
<ListItem>Konseling kesehatan</ListItem>
|
||||
<ListItem>Pemantauan kesehatan ibu hamil</ListItem>
|
||||
</List>
|
||||
</Stack>
|
||||
</Stack>
|
||||
</Box>
|
||||
</Stack>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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, Paper, Skeleton, Stack, Text } from '@mantine/core';
|
||||
import { Box, Center, Group, Image, Loader, Paper, Skeleton, Stack, Text, Tooltip } from '@mantine/core';
|
||||
import { useShallowEffect } from '@mantine/hooks';
|
||||
import { IconCalendar, IconUser } from '@tabler/icons-react';
|
||||
import { useParams } from 'next/navigation';
|
||||
@@ -18,45 +18,75 @@ function Page() {
|
||||
|
||||
if (!state.findUnique.data) {
|
||||
return (
|
||||
<div>
|
||||
<Skeleton h={500} />
|
||||
</div>
|
||||
<Center mih="60vh">
|
||||
<Stack align="center" gap="sm">
|
||||
<Loader color={colors["blue-button"]} size="lg" />
|
||||
<Text c="dimmed" fz="sm">Memuat data program kesehatan...</Text>
|
||||
</Stack>
|
||||
</Center>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<Stack pos={"relative"} bg={colors.Bg} py={"xl"} gap={"22"}>
|
||||
<Stack pos="relative" bg={colors.Bg} py="xl" gap="xl">
|
||||
<Box px={{ base: 'md', md: 100 }}>
|
||||
<BackButton />
|
||||
</Box>
|
||||
<Paper px={{ base: 'md', md: 100 }} radius={10} bg={colors["white-trans-1"]}>
|
||||
<Stack gap={'xs'}>
|
||||
<Center my={20}>
|
||||
<Image radius={"lg"} src={state.findUnique.data.image?.link} alt="" />
|
||||
<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"
|
||||
/>
|
||||
) : (
|
||||
<Skeleton h={300} w="100%" radius="xl" />
|
||||
)}
|
||||
</Center>
|
||||
<Box px={'lg'}>
|
||||
<Box>
|
||||
<Text pb={10} c={colors["blue-button"]} fw={"bold"} fz={"h3"}>
|
||||
{state.findUnique.data.name}
|
||||
</Text>
|
||||
<Text ta={'justify'} fz={'h4'} dangerouslySetInnerHTML={{ __html: state.findUnique.data.deskripsi }}></Text>
|
||||
</Box>
|
||||
<Group py={20}>
|
||||
<Group gap="xs">
|
||||
<IconCalendar size={18} />
|
||||
<Text size="sm">
|
||||
{state.findUnique.data.createdAt ? new Date(state.findUnique.data.createdAt).toLocaleDateString('id-ID', {
|
||||
day: 'numeric',
|
||||
month: 'long',
|
||||
year: 'numeric',
|
||||
}) : 'No date available'}
|
||||
</Text>
|
||||
</Group>
|
||||
<Group gap="xs">
|
||||
<IconUser size={18} />
|
||||
<Text size="sm">Admin Desa</Text>
|
||||
</Group>
|
||||
</Group>
|
||||
<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 }}
|
||||
/>
|
||||
</Box>
|
||||
<Group gap="xl">
|
||||
<Group gap="xs">
|
||||
<Tooltip label="Tanggal dibuat" withArrow>
|
||||
<IconCalendar size={20} stroke={1.5} />
|
||||
</Tooltip>
|
||||
<Text size="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>
|
||||
</Group>
|
||||
<Group gap="xs">
|
||||
<Tooltip label="Dibuat oleh" withArrow>
|
||||
<IconUser size={20} stroke={1.5} />
|
||||
</Tooltip>
|
||||
<Text size="sm" c="dimmed">Admin Desa</Text>
|
||||
</Group>
|
||||
</Group>
|
||||
</Stack>
|
||||
</Paper>
|
||||
</Stack>
|
||||
|
||||
@@ -1,7 +1,31 @@
|
||||
'use client'
|
||||
import colors from "@/con/colors";
|
||||
import { Box, Button, Center, Grid, GridCol, Group, Image, Pagination, Paper, SimpleGrid, Skeleton, Stack, Text, TextInput } from "@mantine/core";
|
||||
import { IconBarbell, IconCalendar, IconOld, IconSearch, IconUser, IconUsersGroup } from "@tabler/icons-react";
|
||||
import {
|
||||
Box,
|
||||
Button,
|
||||
Center,
|
||||
Grid,
|
||||
GridCol,
|
||||
Group,
|
||||
Image,
|
||||
Pagination,
|
||||
Paper,
|
||||
SimpleGrid,
|
||||
Skeleton,
|
||||
Stack,
|
||||
Text,
|
||||
TextInput,
|
||||
Tooltip,
|
||||
Transition,
|
||||
} from "@mantine/core";
|
||||
import {
|
||||
IconBarbell,
|
||||
IconCalendar,
|
||||
IconOld,
|
||||
IconSearch,
|
||||
IconUser,
|
||||
IconUsersGroup,
|
||||
} from "@tabler/icons-react";
|
||||
import BackButton from "../../desa/layanan/_com/BackButto";
|
||||
import { useProxy } from "valtio/utils";
|
||||
import programKesehatan from "@/app/admin/(dashboard)/_state/kesehatan/program-kesehatan/programKesehatan";
|
||||
@@ -9,104 +33,134 @@ import { useState } from "react";
|
||||
import { useShallowEffect } from "@mantine/hooks";
|
||||
import { useRouter } from "next/navigation";
|
||||
|
||||
const data2 = [
|
||||
const manfaatProgram = [
|
||||
{
|
||||
id: 1,
|
||||
icon: <IconBarbell size={50} color={colors['BG-trans']} />,
|
||||
title: "Menjaga Kesehatan Tubuh",
|
||||
desc: "Program kesehatan desa dirancang untuk memelihara kesehatan fisik masyarakat melalui aktivitas rutin, pemeriksaan kesehatan berkala, dan edukasi gaya hidup sehat.",
|
||||
icon: <IconBarbell size={40} color="#fff" />,
|
||||
title: "Menjaga Tubuh Bugar",
|
||||
desc: "Meningkatkan kesehatan fisik masyarakat melalui olahraga rutin, pemeriksaan berkala, dan edukasi gaya hidup sehat.",
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
icon: <IconUsersGroup size={50} color={colors['BG-trans']} />,
|
||||
title: "Mempererat Kebersamaan",
|
||||
desc: "Kegiatan kesehatan komunal menjadi wadah interaksi sosial yang memperkuat ikatan antar warga desa, menumbuhkan rasa kepedulian dan gotong royong.",
|
||||
icon: <IconUsersGroup size={40} color="#fff" />,
|
||||
title: "Menguatkan Kebersamaan",
|
||||
desc: "Menciptakan interaksi sosial sehat, mempererat solidaritas, dan memperkuat budaya gotong royong antar warga.",
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
icon: <IconOld size={50} color={colors['BG-trans']} />,
|
||||
title: "Medukung Lansia Aktif",
|
||||
desc: "Program khusus bagi lansia membantu menjaga kebugaran, mengurangi risiko penyakit degeneratif, dan menciptakan komunitas pendukung untuk kehidupan yang sehat dan bahagia.",
|
||||
icon: <IconOld size={40} color="#fff" />,
|
||||
title: "Dukungan untuk Lansia",
|
||||
desc: "Membantu lansia tetap aktif, sehat, dan bahagia melalui kegiatan komunitas yang aman dan menyenangkan.",
|
||||
},
|
||||
]
|
||||
];
|
||||
|
||||
export default function Page() {
|
||||
const state = useProxy(programKesehatan)
|
||||
const router = useRouter()
|
||||
const [search, setSearch] = useState('')
|
||||
const {
|
||||
data,
|
||||
page,
|
||||
totalPages,
|
||||
loading,
|
||||
load,
|
||||
} = state.findMany;
|
||||
const state = useProxy(programKesehatan);
|
||||
const router = useRouter();
|
||||
const [search, setSearch] = useState("");
|
||||
const { data, page, totalPages, loading, load } = state.findMany;
|
||||
|
||||
useShallowEffect(() => {
|
||||
load(page, 3, search)
|
||||
}, [page, search])
|
||||
load(page, 3, search);
|
||||
}, [page, search]);
|
||||
|
||||
if (loading || !data) {
|
||||
return (
|
||||
<Box py={10}>
|
||||
<Skeleton h={500} />
|
||||
<Box py="xl" px={{ base: "md", md: 100 }}>
|
||||
<Skeleton h={500} radius="lg" />
|
||||
</Box>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Stack pos={"relative"} bg={colors.Bg} py={"xl"} gap={"22"}>
|
||||
<Box px={{ base: 'md', md: 100 }}>
|
||||
<Stack bg={colors.Bg} py="xl" gap="xl">
|
||||
<Box px={{ base: "md", md: 100 }}>
|
||||
<BackButton />
|
||||
</Box>
|
||||
<Grid px={{ base: 'md', md: 100 }} align="center">
|
||||
<GridCol span={{ base: 12, md: 9 }}>
|
||||
<Text fz={{ base: "h1", md: "2.5rem" }} c={colors["blue-button"]} fw={"bold"}>
|
||||
Program Kesehatan Unggulan
|
||||
|
||||
<Grid px={{ base: "md", md: 100 }} align="center" gutter="lg">
|
||||
<GridCol span={{ base: 12, md: 8 }}>
|
||||
<Text
|
||||
fz={{ base: "2rem", md: "2.8rem" }}
|
||||
c={colors["blue-button"]}
|
||||
fw="bold"
|
||||
>
|
||||
Program Kesehatan Desa
|
||||
</Text>
|
||||
<Text fz="lg" c="dimmed" mt="xs">
|
||||
Temukan berbagai program kesehatan untuk mendukung kualitas hidup
|
||||
masyarakat Darmasaba.
|
||||
</Text>
|
||||
</GridCol>
|
||||
<GridCol span={{ base: 12, md: 3 }}>
|
||||
<GridCol span={{ base: 12, md: 4 }}>
|
||||
<TextInput
|
||||
placeholder='Cari Program Kesehatan'
|
||||
placeholder="Cari program kesehatan..."
|
||||
value={search}
|
||||
onChange={(e) => setSearch(e.target.value)}
|
||||
leftSection={<IconSearch size={20} />}
|
||||
w={{ base: "50%", md: "100%" }}
|
||||
radius="lg"
|
||||
size="md"
|
||||
aria-label="Pencarian program kesehatan"
|
||||
/>
|
||||
</GridCol>
|
||||
</Grid>
|
||||
|
||||
<Box px={{ base: "md", md: 100 }}>
|
||||
<Stack gap={'lg'}>
|
||||
<SimpleGrid
|
||||
pb={10}
|
||||
cols={{
|
||||
base: 1,
|
||||
md: 3,
|
||||
}}>
|
||||
{data.map((v, k) => {
|
||||
return (
|
||||
<Paper radius={10} key={k} bg={colors["white-trans-1"]}>
|
||||
<Stack gap={'xs'}>
|
||||
<Center>
|
||||
<Image src={v.image?.link} alt="" style={{ borderRadius: '14px 14px 0 0' }} />
|
||||
</Center>
|
||||
<Box px={'lg'}>
|
||||
<Box>
|
||||
<Text pb={10} c={colors["blue-button"]} fw={"bold"} fz={"h3"}>
|
||||
{v.name}
|
||||
</Text>
|
||||
<Text ta={'justify'} fz={'h4'} dangerouslySetInnerHTML={{ __html: v.deskripsi }}></Text>
|
||||
</Box>
|
||||
<Box py={15} onClick={() => router.push(`/darmasaba/kesehatan/program-kesehatan/${v.id}`)}>
|
||||
<Button fw={'bold'} fz={'h5'} c={colors["blue-button"]} bg={colors["BG-trans"]}>Detail Program</Button>
|
||||
</Box>
|
||||
<Group py={20}>
|
||||
<SimpleGrid cols={{ base: 1, sm: 2, md: 3 }} spacing="lg" pb="xl">
|
||||
{data.map((v, k) => (
|
||||
<Transition
|
||||
key={k}
|
||||
mounted
|
||||
transition="fade-up"
|
||||
duration={400}
|
||||
timingFunction="ease"
|
||||
>
|
||||
{(styles) => (
|
||||
<Paper
|
||||
style={styles}
|
||||
radius="xl"
|
||||
withBorder
|
||||
bg="white"
|
||||
shadow="md"
|
||||
className="hover-scale"
|
||||
>
|
||||
<Stack gap="md">
|
||||
<Image
|
||||
src={v.image?.link}
|
||||
alt={v.name}
|
||||
radius="xl"
|
||||
height={180}
|
||||
fit="cover"
|
||||
/>
|
||||
<Box px="lg" pb="lg">
|
||||
<Text
|
||||
fw="bold"
|
||||
fz="xl"
|
||||
c={colors["blue-button"]}
|
||||
mb="xs"
|
||||
>
|
||||
{v.name}
|
||||
</Text>
|
||||
<Text
|
||||
fz="sm"
|
||||
c="dimmed"
|
||||
lineClamp={3}
|
||||
dangerouslySetInnerHTML={{ __html: v.deskripsi }}
|
||||
/>
|
||||
<Group justify="space-between" mt="md">
|
||||
<Group gap="xs">
|
||||
<IconCalendar size={18} />
|
||||
<Text size="sm">
|
||||
{v.createdAt ? new Date(v.createdAt).toLocaleDateString('id-ID', {
|
||||
day: 'numeric',
|
||||
month: 'long',
|
||||
year: 'numeric',
|
||||
}) : 'No date available'}
|
||||
{v.createdAt
|
||||
? new Date(v.createdAt).toLocaleDateString(
|
||||
"id-ID",
|
||||
{
|
||||
day: "numeric",
|
||||
month: "long",
|
||||
year: "numeric",
|
||||
}
|
||||
)
|
||||
: "Tanggal tidak tersedia"}
|
||||
</Text>
|
||||
</Group>
|
||||
<Group gap="xs">
|
||||
@@ -114,61 +168,99 @@ export default function Page() {
|
||||
<Text size="sm">Admin Desa</Text>
|
||||
</Group>
|
||||
</Group>
|
||||
<Tooltip label="Lihat detail program" withArrow>
|
||||
<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>
|
||||
</Tooltip>
|
||||
</Box>
|
||||
</Stack>
|
||||
</Paper>
|
||||
)
|
||||
})}
|
||||
</SimpleGrid>
|
||||
)}
|
||||
</Transition>
|
||||
))}
|
||||
</SimpleGrid>
|
||||
|
||||
{totalPages > 1 && (
|
||||
<Center>
|
||||
<Pagination
|
||||
value={page}
|
||||
onChange={(newPage) => load(newPage)} // ini penting!
|
||||
onChange={(newPage) => load(newPage)}
|
||||
total={totalPages}
|
||||
mt="md"
|
||||
mb="md"
|
||||
size="lg"
|
||||
radius="xl"
|
||||
styles={{
|
||||
control: {
|
||||
borderRadius: "50%",
|
||||
boxShadow: "0 0 10px rgba(0,0,0,0.1)",
|
||||
},
|
||||
}}
|
||||
/>
|
||||
</Center>
|
||||
</Stack>
|
||||
)}
|
||||
</Box>
|
||||
<Box py={10} px={{ base: "md", md: 100 }}>
|
||||
<Box pb={10}>
|
||||
<Text fz={{ base: "h1", md: "2.5rem" }} c={colors["blue-button"]} fw={"bold"}>
|
||||
|
||||
<Box px={{ base: "md", md: 100 }} py="xl">
|
||||
<Stack gap="sm" mb="lg">
|
||||
<Text
|
||||
fz={{ base: "2rem", md: "2.5rem" }}
|
||||
c={colors["blue-button"]}
|
||||
fw="bold"
|
||||
>
|
||||
Manfaat Program Kesehatan
|
||||
</Text>
|
||||
<Text fz={{ base: "h4", md: "h3" }} >
|
||||
Program kesehatan di Desa Darmasaba memiliki peran penting dalam meningkatkan kesejahteraan masyarakat.
|
||||
<Text fz="lg" c="dimmed" maw={700}>
|
||||
Program kesehatan Desa Darmasaba berperan penting dalam meningkatkan
|
||||
kesejahteraan dan kualitas hidup warganya.
|
||||
</Text>
|
||||
</Box>
|
||||
<SimpleGrid
|
||||
pb={30}
|
||||
cols={{
|
||||
base: 1,
|
||||
md: 3,
|
||||
}}>
|
||||
{data2.map((v, k) => {
|
||||
return (
|
||||
<Paper key={k} px={"xl"} py={80} bg={colors['white-trans-1']} c={colors['blue-button']}>
|
||||
<Stack justify='space-between' >
|
||||
<Group justify='center'>
|
||||
<Paper p={'xl'} radius={'100'} bg={colors['blue-button']}>
|
||||
<Center >
|
||||
{v.icon}
|
||||
</Center>
|
||||
</Paper>
|
||||
</Group>
|
||||
<Text ta={"center"} fw={"bold"} fz={"h3"}>
|
||||
{v.title}
|
||||
</Text>
|
||||
<Text ta={"center"} fz={'h4'}>
|
||||
{v.desc}
|
||||
</Text>
|
||||
</Stack>
|
||||
</Paper>
|
||||
)
|
||||
})}
|
||||
</Stack>
|
||||
<SimpleGrid cols={{ base: 1, md: 3 }} spacing="lg">
|
||||
{manfaatProgram.map((v) => (
|
||||
<Paper
|
||||
key={v.id}
|
||||
px="xl"
|
||||
py="xl"
|
||||
radius="xl"
|
||||
shadow="sm"
|
||||
withBorder
|
||||
bg="white"
|
||||
className="hover-glow"
|
||||
>
|
||||
<Stack align="center" gap="md">
|
||||
<Paper
|
||||
p="lg"
|
||||
radius="50%"
|
||||
shadow="md"
|
||||
bg={colors["blue-button"]}
|
||||
className="pulse-icon"
|
||||
>
|
||||
<Center>{v.icon}</Center>
|
||||
</Paper>
|
||||
<Text ta="center" fw="bold" fz="xl" c={colors["blue-button"]}>
|
||||
{v.title}
|
||||
</Text>
|
||||
<Text ta="center" fz="sm" c="dimmed">
|
||||
{v.desc}
|
||||
</Text>
|
||||
</Stack>
|
||||
</Paper>
|
||||
))}
|
||||
</SimpleGrid>
|
||||
</Box>
|
||||
</Stack>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
'use client'
|
||||
import puskesmasState from '@/app/admin/(dashboard)/_state/kesehatan/puskesmas/puskesmas';
|
||||
import colors from '@/con/colors';
|
||||
import { BackgroundImage, Box, Grid, GridCol, Paper, SimpleGrid, Skeleton, Stack, Text, Title } from '@mantine/core';
|
||||
import { BackgroundImage, Box, Grid, GridCol, Paper, SimpleGrid, Skeleton, Stack, Text, Title, Tooltip, Badge, Divider, Group } from '@mantine/core';
|
||||
import { useShallowEffect } from '@mantine/hooks';
|
||||
import { useParams } from 'next/navigation';
|
||||
import { useProxy } from 'valtio/utils';
|
||||
import { IconClock, IconMapPin, IconPhone, IconMail, IconBuildingHospital } from '@tabler/icons-react';
|
||||
import BackButton from '../../../desa/layanan/_com/BackButto';
|
||||
|
||||
function Page() {
|
||||
@@ -17,95 +18,117 @@ function Page() {
|
||||
|
||||
if (!state.findUnique.data) {
|
||||
return (
|
||||
<Stack py={10}>
|
||||
<Skeleton h={500} />
|
||||
<Stack py="xl" px={{ base: 'md', md: 100 }}>
|
||||
<Skeleton h={500} radius="lg" />
|
||||
<Stack gap="sm">
|
||||
<Skeleton h={20} w="40%" />
|
||||
<Skeleton h={20} w="60%" />
|
||||
<Skeleton h={20} w="50%" />
|
||||
</Stack>
|
||||
</Stack>
|
||||
)
|
||||
}
|
||||
|
||||
const data = state.findUnique.data
|
||||
|
||||
return (
|
||||
<Stack pos={"relative"} bg={colors.Bg} py={"xl"} gap={"22"}>
|
||||
<Stack pos="relative" bg={colors.Bg} py="xl" gap={32}>
|
||||
<Box px={{ base: 'md', md: 100 }}>
|
||||
<BackButton />
|
||||
</Box>
|
||||
<Stack gap={'lg'} px={{ base: 'md', md: 100 }}>
|
||||
<Box>
|
||||
<Paper p={"xl"} bg={colors['white-trans-1']}>
|
||||
<Box pb={30}>
|
||||
<BackgroundImage
|
||||
pb={30}
|
||||
radius={16}
|
||||
h={{ base: 250, md: 500 }}
|
||||
src={state.findUnique.data.image.link}
|
||||
style={{ position: 'relative' }}
|
||||
|
||||
<Stack gap="xl" px={{ base: 'md', md: 100 }}>
|
||||
<Paper p="lg" radius="xl" shadow="md" bg={colors['white-trans-1']} withBorder>
|
||||
<Box pb="xl">
|
||||
<BackgroundImage
|
||||
radius="lg"
|
||||
h={{ base: 260, md: 480 }}
|
||||
src={data.image.link}
|
||||
style={{ position: 'relative', overflow: 'hidden' }}
|
||||
>
|
||||
<Box
|
||||
pos="absolute"
|
||||
w="100%"
|
||||
h="100%"
|
||||
bg={colors.trans.dark[2]}
|
||||
style={{ borderRadius: 16 }}
|
||||
/>
|
||||
<Stack
|
||||
pos="absolute"
|
||||
bottom={20}
|
||||
left={20}
|
||||
gap={6}
|
||||
>
|
||||
<Box
|
||||
style={{
|
||||
borderRadius: 16,
|
||||
zIndex: 0
|
||||
}}
|
||||
pos={"absolute"}
|
||||
w={"100%"}
|
||||
h={"100%"}
|
||||
bg={colors.trans.dark[2]}
|
||||
/>
|
||||
<Text style={{
|
||||
position: 'absolute',
|
||||
bottom: 35,
|
||||
left: 15,
|
||||
}} fw={'bold'} fz={{ base: 'md', md: 'h3' }} c={colors['white-1']}>{state.findUnique.data.name}</Text>
|
||||
<Text style={{
|
||||
position: 'absolute',
|
||||
bottom: 10,
|
||||
left: 15,
|
||||
}} fw={'bold'} fz={{ base: 'md', md: 'h4' }} c={colors['white-1']}>{state.findUnique.data.alamat}</Text>
|
||||
</BackgroundImage>
|
||||
<Grid
|
||||
py={20}>
|
||||
<GridCol span={{ base: 12, md: 6 }}>
|
||||
<Text fw="bold" fz={{ base: 'lg', md: 'h2' }} c={colors['white-1']}>
|
||||
{data.name}
|
||||
</Text>
|
||||
<Group gap={6}>
|
||||
<IconMapPin size={20} color="white" />
|
||||
<Text fz={{ base: 'sm', md: 'md' }} c={colors['white-1']}>
|
||||
{data.alamat}
|
||||
</Text>
|
||||
</Group>
|
||||
</Stack>
|
||||
</BackgroundImage>
|
||||
|
||||
<Grid mt="xl" gutter="xl">
|
||||
<GridCol span={{ base: 12, md: 6 }}>
|
||||
<Stack gap="lg">
|
||||
<Box>
|
||||
<Stack>
|
||||
<Title order={3}>Informasi</Title>
|
||||
<Box>
|
||||
<Text>Alamat: {state.findUnique.data.alamat}</Text>
|
||||
<Text>Telepon: {state.findUnique.data.kontak.kontakPuskesmas}</Text>
|
||||
<Text>Email: {state.findUnique.data.kontak.email}</Text>
|
||||
</Box>
|
||||
<Title order={3}>Jam Operasional</Title>
|
||||
<Box>
|
||||
<Text pb={10} fz={'h4'} fw={"bold"}>
|
||||
Senin - Kamis: <Text span fz={'h4'}>{state.findUnique.data?.jam.workDays} - {state.findUnique.data?.jam.weekDays}</Text>
|
||||
</Text>
|
||||
</Box>
|
||||
<Title order={3} mb={10}>Informasi Kontak</Title>
|
||||
<Stack gap={8}>
|
||||
<Group gap={8}>
|
||||
<IconPhone size={18} />
|
||||
<Text fz="md">{data.kontak.kontakPuskesmas || '-'}</Text>
|
||||
</Group>
|
||||
<Group gap={8}>
|
||||
<IconMail size={18} />
|
||||
<Text fz="md">{data.kontak.email || '-'}</Text>
|
||||
</Group>
|
||||
</Stack>
|
||||
</Box>
|
||||
</GridCol>
|
||||
<GridCol span={{ base: 12, md: 6 }}>
|
||||
<Box>
|
||||
<Paper p={"xl"} bg={'#B1C5F2'}>
|
||||
<SimpleGrid
|
||||
cols={{
|
||||
base: 1,
|
||||
md: 2
|
||||
}}>
|
||||
<Paper p={"xl"} bg={colors['white-trans-1']}>
|
||||
<Text fw={"bold"} fz={'h3'} ta={'center'}>Poliklinik Umum</Text>
|
||||
<Text ta={'center'} fz={{ base: 45, md: 65 }} fw={'bold'} c={colors['blue-button']}>26</Text>
|
||||
</Paper>
|
||||
<Paper p={"xl"} bg={colors['white-trans-1']}>
|
||||
<Text ta={'center'} fz={'h3'} fw={"bold"}>Poli Gigi</Text>
|
||||
<Text ta={'center'} fz={{ base: 45, md: 65 }} fw={'bold'} c={colors['blue-button']}>26</Text>
|
||||
</Paper>
|
||||
</SimpleGrid>
|
||||
</Paper>
|
||||
</Box>
|
||||
</GridCol>
|
||||
<Box>
|
||||
</Box>
|
||||
</Grid>
|
||||
</Box>
|
||||
|
||||
</Paper>
|
||||
</Box>
|
||||
<Divider />
|
||||
|
||||
<Box>
|
||||
<Title order={3} mb={10}>Jam Operasional</Title>
|
||||
<Group gap={8}>
|
||||
<IconClock size={18} />
|
||||
<Text fw="bold" fz="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>
|
||||
</Box>
|
||||
</Stack>
|
||||
</GridCol>
|
||||
|
||||
<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>
|
||||
<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>
|
||||
</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>
|
||||
</Stack>
|
||||
</Paper>
|
||||
</SimpleGrid>
|
||||
</Paper>
|
||||
</GridCol>
|
||||
</Grid>
|
||||
</Box>
|
||||
</Paper>
|
||||
</Stack>
|
||||
</Stack>
|
||||
);
|
||||
|
||||
@@ -1,14 +1,13 @@
|
||||
'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 } from '@mantine/core';
|
||||
import { Anchor, Box, Center, Grid, GridCol, Image, Pagination, Paper, SimpleGrid, Skeleton, Stack, Text, TextInput, Badge, Group } from '@mantine/core';
|
||||
import { useShallowEffect } from '@mantine/hooks';
|
||||
import { IconSearch } from '@tabler/icons-react';
|
||||
import { IconSearch, IconMapPin, IconPhone, IconMail } from '@tabler/icons-react';
|
||||
import { useState } from 'react';
|
||||
import { useProxy } from 'valtio/utils';
|
||||
import BackButton from '../../desa/layanan/_com/BackButto';
|
||||
|
||||
|
||||
function Page() {
|
||||
const state = useProxy(puskesmasState)
|
||||
const [search, setSearch] = useState('')
|
||||
@@ -22,76 +21,122 @@ function Page() {
|
||||
} = state.findMany;
|
||||
|
||||
useShallowEffect(() => {
|
||||
load(page, 3, search)
|
||||
load(page, 6, search)
|
||||
}, [page, search])
|
||||
|
||||
if (loading || !data) {
|
||||
return (
|
||||
<Box py={10}>
|
||||
<Skeleton h={500} />
|
||||
<Box py="xl" px={{ base: 'md', md: 100 }}>
|
||||
<SimpleGrid cols={{ base: 1, md: 3 }} spacing="lg">
|
||||
{Array.from({ length: 6 }).map((_, i) => (
|
||||
<Skeleton key={i} height={320} radius="lg" />
|
||||
))}
|
||||
</SimpleGrid>
|
||||
</Box>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<Stack pos={"relative"} bg={colors.Bg} py={"xl"} gap={"22"}>
|
||||
<Stack pos="relative" bg={colors.Bg} py="xl" gap="lg">
|
||||
<Box px={{ base: 'md', md: 100 }}>
|
||||
<BackButton />
|
||||
</Box>
|
||||
<Grid align='center' px={{ base: 'md', md: 100 }}>
|
||||
<GridCol span={{ base: 12, md: 9 }}>
|
||||
<Text fz={{ base: "h1", md: "2.5rem" }} c={colors["blue-button"]} fw={"bold"}>
|
||||
Puskesmas Darmasaba
|
||||
|
||||
<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">
|
||||
Daftar Puskesmas
|
||||
</Text>
|
||||
<Text fz="sm" c="dimmed">
|
||||
Temukan informasi lengkap mengenai layanan, kontak, dan lokasi Puskesmas Darmasaba
|
||||
</Text>
|
||||
</GridCol>
|
||||
<GridCol span={{ base: 12, md: 3 }}>
|
||||
<GridCol span={{ base: 12, md: 4 }}>
|
||||
<TextInput
|
||||
radius={"lg"}
|
||||
placeholder='Cari Puskesmas'
|
||||
radius="xl"
|
||||
placeholder="Cari nama puskesmas..."
|
||||
value={search}
|
||||
onChange={(e) => setSearch(e.target.value)}
|
||||
leftSection={<IconSearch size={20} />}
|
||||
w={{ base: "50%", md: "100%" }}
|
||||
leftSection={<IconSearch size={18} />}
|
||||
aria-label="Cari Puskesmas"
|
||||
/>
|
||||
</GridCol>
|
||||
</Grid>
|
||||
<Box px={{ base: "md", md: 100 }}>
|
||||
<SimpleGrid
|
||||
cols={{
|
||||
base: 1,
|
||||
md: 3,
|
||||
}}
|
||||
>
|
||||
{data.map((v, k) => {
|
||||
return (
|
||||
<Paper p={"xl"} bg={colors['white-trans-1']} key={k}>
|
||||
<Stack gap={"xs"}>
|
||||
<Text fw={"bold"} fz={"h3"}>{v.name}</Text>
|
||||
|
||||
<Box px={{ base: 'md', md: 100 }}>
|
||||
{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>
|
||||
</Stack>
|
||||
</Center>
|
||||
) : (
|
||||
<SimpleGrid cols={{ base: 1, sm: 2, md: 3 }} spacing="lg">
|
||||
{data.map((v, k) => (
|
||||
<Paper
|
||||
key={k}
|
||||
p="lg"
|
||||
radius="xl"
|
||||
withBorder
|
||||
shadow="md"
|
||||
bg={colors['white-trans-1']}
|
||||
style={{ transition: 'transform 200ms ease' }}
|
||||
className="hover:scale-[1.02]"
|
||||
>
|
||||
<Stack gap="sm">
|
||||
<Image
|
||||
src={v.image.link}
|
||||
alt={v.name}
|
||||
radius="md"
|
||||
height={160}
|
||||
fit="cover"
|
||||
/>
|
||||
<Box>
|
||||
<Text>Alamat: {v.alamat}</Text>
|
||||
<Text>Telepon: {v.kontak.kontakPuskesmas}</Text>
|
||||
<Text>Email: {v.kontak.email}</Text>
|
||||
</Box>
|
||||
<Anchor c={colors['blue-button']} href={`/darmasaba/kesehatan/puskesmas/${v.id}`}>Lihat Detail ></Anchor>
|
||||
<Group justify="space-between">
|
||||
<Text fw={600} fz="lg" lineClamp={1}>{v.name}</Text>
|
||||
<Badge color="blue" variant="light" radius="sm" fz="xs">Aktif</Badge>
|
||||
</Group>
|
||||
<Stack gap={4}>
|
||||
<Group gap="xs">
|
||||
<IconMapPin size={16} />
|
||||
<Text fz="sm" c="dimmed" lineClamp={2}>{v.alamat}</Text>
|
||||
</Group>
|
||||
<Group gap="xs">
|
||||
<IconPhone size={16} />
|
||||
<Text fz="sm" c="dimmed">{v.kontak.kontakPuskesmas}</Text>
|
||||
</Group>
|
||||
<Group gap="xs">
|
||||
<IconMail size={16} />
|
||||
<Text fz="sm" c="dimmed">{v.kontak.email}</Text>
|
||||
</Group>
|
||||
</Stack>
|
||||
<Anchor
|
||||
href={`/darmasaba/kesehatan/puskesmas/${v.id}`}
|
||||
fz="sm"
|
||||
fw={500}
|
||||
c={colors['blue-button']}
|
||||
>
|
||||
Lihat detail →
|
||||
</Anchor>
|
||||
</Stack>
|
||||
</Paper>
|
||||
)
|
||||
})}
|
||||
</SimpleGrid>
|
||||
))}
|
||||
</SimpleGrid>
|
||||
)}
|
||||
</Box>
|
||||
<Center>
|
||||
<Pagination
|
||||
value={page}
|
||||
onChange={(newPage) => load(newPage)} // ini penting!
|
||||
total={totalPages}
|
||||
mt="md"
|
||||
mb="md"
|
||||
/>
|
||||
</Center>
|
||||
|
||||
{totalPages > 1 && (
|
||||
<Center>
|
||||
<Pagination
|
||||
value={page}
|
||||
onChange={(newPage) => load(newPage, 6, search)}
|
||||
total={totalPages}
|
||||
size="md"
|
||||
radius="xl"
|
||||
mt="lg"
|
||||
/>
|
||||
</Center>
|
||||
)}
|
||||
</Stack>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -2,9 +2,26 @@
|
||||
|
||||
import daftarInformasiPublik from '@/app/admin/(dashboard)/_state/ppid/daftar_informasi_publik/daftarInformasiPublik';
|
||||
import colors from '@/con/colors';
|
||||
import { Box, Center, Image, Pagination, Skeleton, Stack, Table, TableTbody, TableTd, TableTh, TableThead, TableTr, Text, TextInput } from '@mantine/core';
|
||||
import {
|
||||
Box,
|
||||
Center,
|
||||
Image,
|
||||
Pagination,
|
||||
Skeleton,
|
||||
Stack,
|
||||
Table,
|
||||
TableTbody,
|
||||
TableTd,
|
||||
TableTh,
|
||||
TableThead,
|
||||
TableTr,
|
||||
Text,
|
||||
TextInput,
|
||||
Paper,
|
||||
Badge,
|
||||
} from '@mantine/core';
|
||||
import { useShallowEffect } from '@mantine/hooks';
|
||||
import { IconSearch } from '@tabler/icons-react';
|
||||
import { IconSearch, IconFileInfo, IconMail, IconBrandWhatsapp } from '@tabler/icons-react';
|
||||
import { useState } from 'react';
|
||||
import { useProxy } from 'valtio/utils';
|
||||
import BackButton from '../../desa/layanan/_com/BackButto';
|
||||
@@ -21,85 +38,122 @@ function Page() {
|
||||
load,
|
||||
} = listData.findMany
|
||||
|
||||
|
||||
useShallowEffect(() => {
|
||||
load(page, 5, search)
|
||||
}, [page, search])
|
||||
|
||||
if (loading || !data) return <Stack pos={"relative"} bg={colors.Bg} py={"xl"} gap={"22"}>
|
||||
<Box px={{ base: 'md', md: 100 }}>
|
||||
<Skeleton h={40} />
|
||||
</Box>
|
||||
<Skeleton h={40} />
|
||||
<Skeleton h={40} />
|
||||
<Box px={{ base: 'md', md: 100 }}>
|
||||
<Skeleton h={40} />
|
||||
</Box>
|
||||
</Stack>
|
||||
if (loading || !data) {
|
||||
return (
|
||||
<Stack pos="relative" bg={colors.Bg} py="xl" gap="lg">
|
||||
<Box px={{ base: 'md', md: 100 }}>
|
||||
<Skeleton h={40} radius="xl" />
|
||||
</Box>
|
||||
<Skeleton h={50} radius="xl" />
|
||||
<Skeleton h={50} radius="xl" />
|
||||
<Skeleton h={50} radius="xl" />
|
||||
</Stack>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<Stack pos={"relative"} bg={colors.Bg} py={"xl"} gap={"22"}>
|
||||
<Stack pos="relative" bg={colors.Bg} py="xl" gap="xl">
|
||||
<Box px={{ base: 'md', md: 100 }}>
|
||||
<BackButton />
|
||||
</Box>
|
||||
<Center>
|
||||
<Image src={"/darmasaba-icon.png"} w={{ base: 70, md: 100 }} alt='' />
|
||||
<Image src="/darmasaba-icon.png" w={{ base: 70, md: 100 }} alt="Logo Desa Darmasaba" />
|
||||
</Center>
|
||||
<Text ta={"center"} fz={{ base: "h1", md: "2.5rem" }} c={colors["blue-button"]} fw={"bold"}>
|
||||
<Text ta="center" fz={{ base: "1.8rem", md: "2.5rem" }} c={colors["blue-button"]} fw="bold" lh={1.4}>
|
||||
Daftar Informasi Publik Desa Darmasaba
|
||||
</Text>
|
||||
<Box px={{ base: "md", md: 100 }}>
|
||||
<Stack gap={'lmd'}>
|
||||
<Text fz={{ base: 'h3', md: 'h2' }} fw={"bold"}>Tentang Informasi Publik</Text>
|
||||
<Text fz={{ base: 'md', md: 'h3' }}>Daftar Informasi Publik Desa Darmasaba berupa kumpulan data yang dapat diakses oleh masyarakat sesuai dengan peraturan yang berlaku.</Text>
|
||||
<Stack gap="lg">
|
||||
<Paper p="lg" radius="xl" shadow="sm" withBorder>
|
||||
<Stack gap="sm">
|
||||
<Text fz={{ base: 'lg', md: 'xl' }} fw="bold" c={colors["blue-button"]}>
|
||||
Tentang Informasi Publik
|
||||
</Text>
|
||||
<Text fz={{ base: 'sm', md: 'md' }} c="dimmed">
|
||||
Daftar Informasi Publik Desa Darmasaba adalah kumpulan data yang dapat diakses oleh masyarakat sesuai dengan ketentuan peraturan yang berlaku.
|
||||
</Text>
|
||||
</Stack>
|
||||
</Paper>
|
||||
|
||||
<TextInput
|
||||
placeholder='Cari Informasi...'
|
||||
leftSection={<IconSearch size={20} />}
|
||||
placeholder="Cari informasi publik..."
|
||||
aria-label="Pencarian informasi publik"
|
||||
leftSection={<IconSearch size={20} stroke={1.5} />}
|
||||
value={search}
|
||||
onChange={(e) => setSearch(e.target.value)}
|
||||
style={{ marginBottom: 16 }}
|
||||
radius="xl"
|
||||
size="md"
|
||||
/>
|
||||
<Table withRowBorders withColumnBorders withTableBorder>
|
||||
<TableThead bg={colors['blue-button']}>
|
||||
<TableTr c={colors['white-1']}>
|
||||
<TableTh ta={'center'}>No</TableTh>
|
||||
<TableTh ta={'center'}>Jenis Informasi</TableTh>
|
||||
<TableTh ta={'center'}>Deskripsi</TableTh>
|
||||
<TableTh ta={'center'}>Tanggal Publikasi</TableTh>
|
||||
</TableTr>
|
||||
</TableThead>
|
||||
<TableTbody bg={colors['white-1']}>
|
||||
{listData.findMany.data?.map((item, index) => (
|
||||
<TableTr key={item.id}>
|
||||
<TableTd ta={'center'}>{index + 1}</TableTd>
|
||||
<TableTd>
|
||||
<Text fz={'md'}>
|
||||
{item.jenisInformasi}
|
||||
</Text>
|
||||
</TableTd>
|
||||
<TableTd>
|
||||
<Text
|
||||
fz={'md'}
|
||||
dangerouslySetInnerHTML={{ __html: item.deskripsi }}
|
||||
/>
|
||||
</TableTd>
|
||||
<TableTd style={{ width: '20%', textAlign: 'center' }}>{item.tanggal
|
||||
? new Date(item.tanggal).toLocaleDateString('id-ID')
|
||||
: '-'}</TableTd>
|
||||
|
||||
{data.length === 0 ? (
|
||||
<Center py="xl">
|
||||
<Stack align="center" gap="sm">
|
||||
<IconFileInfo size={48} stroke={1.5} color={colors["blue-button"]} />
|
||||
<Text fz="md" c="dimmed">Tidak ada informasi publik yang ditemukan.</Text>
|
||||
</Stack>
|
||||
</Center>
|
||||
) : (
|
||||
<Table withRowBorders withColumnBorders withTableBorder highlightOnHover verticalSpacing="md">
|
||||
<TableThead bg={colors['blue-button']}>
|
||||
<TableTr c={colors['white-1']}>
|
||||
<TableTh fz="sm" ta="center" w="5%">No</TableTh>
|
||||
<TableTh fz="sm" ta="center" w="25%">Jenis Informasi</TableTh>
|
||||
<TableTh fz="sm" ta="center" w="40%">Deskripsi</TableTh>
|
||||
<TableTh fz="sm" ta="center" w="20%">Tanggal Publikasi</TableTh>
|
||||
</TableTr>
|
||||
))}
|
||||
</TableTbody>
|
||||
</Table>
|
||||
</TableThead>
|
||||
<TableTbody bg={colors['white-1']}>
|
||||
{data.map((item, index) => (
|
||||
<TableTr key={item.id}>
|
||||
<TableTd ta="center">{(page - 1) * 5 + index + 1}</TableTd>
|
||||
<TableTd>
|
||||
<Badge variant="light" size="lg" color="blue">
|
||||
{item.jenisInformasi}
|
||||
</Badge>
|
||||
</TableTd>
|
||||
<TableTd>
|
||||
<Text fz="sm" c="dark" dangerouslySetInnerHTML={{ __html: item.deskripsi }} />
|
||||
</TableTd>
|
||||
<TableTd ta="center">
|
||||
{item.tanggal ? new Date(item.tanggal).toLocaleDateString('id-ID', {
|
||||
day: '2-digit',
|
||||
month: 'long',
|
||||
year: 'numeric'
|
||||
}) : '-'}
|
||||
</TableTd>
|
||||
</TableTr>
|
||||
))}
|
||||
</TableTbody>
|
||||
</Table>
|
||||
)}
|
||||
|
||||
<Center>
|
||||
<Pagination
|
||||
value={page}
|
||||
onChange={(newPage) => load(newPage, 5, search)}
|
||||
total={totalPages}
|
||||
my="lg"
|
||||
radius="xl"
|
||||
size="md"
|
||||
/>
|
||||
</Center>
|
||||
|
||||
<Paper p="lg" radius="xl" shadow="xs" withBorder>
|
||||
<Stack gap="xs">
|
||||
<Text fz="lg" fw="bold" c={colors["blue-button"]}>Kontak PPID</Text>
|
||||
<Text fz="sm" c="dimmed" lh={1.6}>
|
||||
<IconMail size={16} style={{ marginRight: 6 }} /> Email: <Text span fw="500">ppid@desadarmasaba.id</Text>
|
||||
</Text>
|
||||
<Text fz="sm" c="dimmed" lh={1.6}>
|
||||
<IconBrandWhatsapp size={16} style={{ marginRight: 6 }} /> WhatsApp: <Text span fw="500">081-xxx-xxx-xxx</Text>
|
||||
</Text>
|
||||
</Stack>
|
||||
</Paper>
|
||||
</Stack>
|
||||
<Center>
|
||||
<Pagination
|
||||
value={page}
|
||||
onChange={(newPage) => load(newPage)}
|
||||
total={totalPages}
|
||||
my={"md"}
|
||||
/>
|
||||
</Center>
|
||||
<Text pt={20} fz={'h4'} fw={"bold"}>Kontak PPID</Text>
|
||||
<Text fz={'sm'}>Email: ppid@desadarmasaba.id | WhatsApp: 081-xxx-xxx-xxx</Text>
|
||||
</Box>
|
||||
</Stack>
|
||||
);
|
||||
|
||||
@@ -1,100 +1,93 @@
|
||||
'use client'
|
||||
import stateDasarHukum from '@/app/admin/(dashboard)/_state/ppid/dasar_hukum/dasarHukum';
|
||||
import colors from '@/con/colors';
|
||||
import { Box, List, ListItem, Paper, Stack, Text } from '@mantine/core';
|
||||
import { Box, Paper, Skeleton, Stack, Text, Transition } from '@mantine/core';
|
||||
import { useShallowEffect } from '@mantine/hooks';
|
||||
import { useProxy } from 'valtio/utils';
|
||||
import { IconBook2 } from '@tabler/icons-react';
|
||||
import BackButton from '../../desa/layanan/_com/BackButto';
|
||||
|
||||
function Page() {
|
||||
const state = useProxy(stateDasarHukum);
|
||||
|
||||
useShallowEffect(() => {
|
||||
state.findById.load("1");
|
||||
}, []);
|
||||
|
||||
if (!state.findById.data) {
|
||||
return (
|
||||
<Stack p="xl" gap="md">
|
||||
<Skeleton h={70} radius="xl" />
|
||||
</Stack>
|
||||
);
|
||||
}
|
||||
|
||||
const dataArray = Array.isArray(state.findById.data)
|
||||
? state.findById.data
|
||||
: [state.findById.data];
|
||||
|
||||
return (
|
||||
<Stack pos={"relative"} bg={colors.Bg} py={"xl"} gap={"22"}>
|
||||
<Stack pos="relative" bg={colors.Bg} py="xl" gap="xl">
|
||||
<Box px={{ base: 'md', md: 100 }}>
|
||||
<BackButton />
|
||||
</Box>
|
||||
<Text ta={"center"} fz={{ base: "h1", md: "2.5rem" }} c={colors["blue-button"]} fw={"bold"}>
|
||||
Dasar Hukum
|
||||
</Text>
|
||||
<Stack align="center" gap="xs">
|
||||
<IconBook2 size={42} stroke={1.5} color={colors["blue-button"]} />
|
||||
<Text
|
||||
ta="center"
|
||||
fz={{ base: "2rem", md: "2.5rem" }}
|
||||
c={colors["blue-button"]}
|
||||
fw="bold"
|
||||
style={{ letterSpacing: "-0.5px" }}
|
||||
>
|
||||
Dasar Hukum
|
||||
</Text>
|
||||
<Text ta="center" fz="sm" c="dimmed">
|
||||
Informasi regulasi dan kebijakan resmi yang menjadi dasar hukum
|
||||
</Text>
|
||||
</Stack>
|
||||
<Box px={{ base: "md", md: 100 }}>
|
||||
<Paper p={"xl"} bg={colors['white-trans-1']}>
|
||||
<Box>
|
||||
<Text ta={"center"} fw={"bold"} fz={{ base: 'h4', md: 'h3' }}>DASAR HUKUM PEMBENTUKAN PPID DESA DARMASABA</Text>
|
||||
</Box>
|
||||
<List p={'lg'}>
|
||||
<ListItem fz={{ base: 'md', md: 'h4' }}>
|
||||
<Text ta={"justify"} fz={{ base: 'md', md: 'h4' }}>
|
||||
<Text fw={"bold"} span>
|
||||
UU Nomor 14 Tahun 2008
|
||||
</Text>
|
||||
{" "}tentang Keterbukaan Informasi Publik
|
||||
</Text>
|
||||
</ListItem>
|
||||
<ListItem fz={{ base: 'md', md: 'h4' }}>
|
||||
<Text ta={"justify"} fz={{ base: 'md', md: 'h4' }}>
|
||||
<Text fw={"bold"} span>
|
||||
PP Nomor 61 Tahun 2010
|
||||
</Text>
|
||||
{" "}tentang Pelaksanaan UU 14 Tahun 2008 tentang Keterbukaan Informasi Publik
|
||||
</Text>
|
||||
</ListItem>
|
||||
<ListItem fz={{ base: 'md', md: 'h4' }}>
|
||||
<Text ta={"justify"} fz={{ base: 'md', md: 'h4' }}>
|
||||
<Text fw={"bold"} span>
|
||||
Permendagri Nomor 3 Tahun 2017
|
||||
</Text>
|
||||
{" "}tentang Pedoman Pengelolaan Pelayanan Informasi dan Dokumentasi di Lingkungan Kemendagri
|
||||
dan Pemerintah Daerah
|
||||
</Text>
|
||||
</ListItem>
|
||||
<ListItem fz={{ base: 'md', md: 'h4' }}>
|
||||
<Text ta={"justify"} fz={{ base: 'md', md: 'h4' }}>
|
||||
<Text fw={"bold"} span>
|
||||
Peraturan Komisi Informasi Nomor 1 Tahun 2010
|
||||
</Text>
|
||||
{" "} tentang Standar Layanan Informasi Publik
|
||||
</Text>
|
||||
</ListItem>
|
||||
<ListItem fz={{ base: 'md', md: 'h4' }}>
|
||||
<Text ta={"justify"} fz={{ base: 'md', md: 'h4' }}>
|
||||
<Text fw={"bold"} span>
|
||||
Peraturan Komisi Informasi Nomor 1 Tahun 2010
|
||||
</Text>
|
||||
{" "} tentang Standar Layanan Informasi Publik
|
||||
</Text>
|
||||
</ListItem>
|
||||
<ListItem fz={{ base: 'md', md: 'h4' }}>
|
||||
<Text ta={"justify"} fz={{ base: 'md', md: 'h4' }}>
|
||||
<Text fw={"bold"} span>
|
||||
Peraturan Bupati Badung No. 42 Tahun 2017
|
||||
</Text>
|
||||
{" "}Tentang Pedoman Pengelolaan Pelayanan Informasi Publik dan Dokumentasi
|
||||
di Lingkungan Pemerintah Kabupaten Badung
|
||||
</Text>
|
||||
</ListItem>
|
||||
<ListItem fz={{ base: 'md', md: 'h4' }}>
|
||||
<Text ta={"justify"} fz={{ base: 'md', md: 'h4' }}>
|
||||
<Text fw={"bold"} span>
|
||||
Keputusan Bupati Badung Nomor 99/049/HK/2019
|
||||
</Text>
|
||||
{" "} Tentang Pengelola Layanan Informasi dan Dokumentasi Kabupaten Badung
|
||||
</Text>
|
||||
</ListItem>
|
||||
<ListItem fz={{ base: 'md', md: 'h4' }}>
|
||||
<Text ta={"justify"} fz={{ base: 'md', md: 'h4' }}>
|
||||
<Text fw={"bold"} span>
|
||||
Keputusan Perbekel Darmasaba Nomor 101 Tahun 2019
|
||||
</Text>
|
||||
{" "}tentang Penetapan Pelaksana Teknis/Administrasi Pengelola Layanan Informasi
|
||||
Dan Dokumentasi Di Desa Punggul
|
||||
</Text>
|
||||
</ListItem>
|
||||
<ListItem fz={{ base: 'md', md: 'h4' }}>
|
||||
<Text ta={"justify"} fz={{ base: 'md', md: 'h4' }}>
|
||||
<Text fw={"bold"} span>
|
||||
Peraturan Perbekel Darmasaba Nomor 12 Tahun 2019
|
||||
</Text>
|
||||
{" "}tentang Pedoman Pengelolaan Pelayanan Informasi Publik Dan Dokumentasi
|
||||
Di Lingkungan Pemerintah Desa Darmasaba
|
||||
</Text>
|
||||
</ListItem>
|
||||
</List>
|
||||
</Paper>
|
||||
<Stack gap="lg">
|
||||
{dataArray.map((item, k) => (
|
||||
<Transition
|
||||
key={k}
|
||||
mounted={true}
|
||||
transition="fade-up"
|
||||
duration={400}
|
||||
timingFunction="ease"
|
||||
>
|
||||
{(styles) => (
|
||||
<Paper
|
||||
p="xl"
|
||||
radius="xl"
|
||||
shadow="md"
|
||||
bg={colors['white-trans-1']}
|
||||
style={{
|
||||
...styles,
|
||||
backdropFilter: "blur(10px)",
|
||||
border: `1px solid ${colors["blue-button"]}20`,
|
||||
}}
|
||||
>
|
||||
<Stack gap="md">
|
||||
<Text
|
||||
ta="center"
|
||||
fw="bold"
|
||||
fz={{ base: 'lg', md: 'xl' }}
|
||||
style={{ lineHeight: 1.4 }}
|
||||
>
|
||||
{item.judul}
|
||||
</Text>
|
||||
<Text
|
||||
fz={{ base: 'sm', md: 'md' }}
|
||||
style={{ lineHeight: 1.7 }}
|
||||
dangerouslySetInnerHTML={{ __html: item.content }}
|
||||
/>
|
||||
</Stack>
|
||||
</Paper>
|
||||
)}
|
||||
</Transition>
|
||||
))}
|
||||
</Stack>
|
||||
</Box>
|
||||
</Stack>
|
||||
);
|
||||
|
||||
@@ -1,8 +1,21 @@
|
||||
'use client'
|
||||
import statePermohonanInformasi from '@/app/admin/(dashboard)/_state/ppid/permohonan_informasi_publik/permohonanInformasiPublik';
|
||||
import colors from '@/con/colors';
|
||||
import { ActionIcon, Box, Button, Center, Checkbox, Group, Paper, SimpleGrid, Stack, Text, TextInput } from '@mantine/core';
|
||||
import { IconDownload } from '@tabler/icons-react';
|
||||
import {
|
||||
ActionIcon,
|
||||
Box,
|
||||
Button,
|
||||
Center,
|
||||
Checkbox,
|
||||
Group,
|
||||
Paper,
|
||||
SimpleGrid,
|
||||
Stack,
|
||||
Text,
|
||||
TextInput,
|
||||
Tooltip,
|
||||
} from '@mantine/core';
|
||||
import { IconDownload, IconSend2 } from '@tabler/icons-react';
|
||||
import { useRouter } from 'next/navigation';
|
||||
import { useProxy } from 'valtio/utils';
|
||||
import BackButton from '../../desa/layanan/_com/BackButto';
|
||||
@@ -10,11 +23,31 @@ import JenisInformasiSelector from './jenis_infromasi/jenisInformasiSelector';
|
||||
import MemperolehInformasi from './memperoleh_informasi/memperolehInfromasi';
|
||||
import MemperolehSalinan from './salinan_informasi/salinanInformasi';
|
||||
|
||||
const data = [
|
||||
{ id: 1, number: '1', title: "Langkah 1", desc: "Pemohon informasi publik mengajukan permohonan informasi kepada badan publik baik langsung maupun melalui surat elektronik" },
|
||||
{ id: 2, number: '2', title: "Langkah 2", desc: "Isi formulir permohonan informasi dengan data diri (nama, alamat, telepon), jenis, format, dan cara penyampaian informasi, serta lampiran fotokopi kartu identitas." },
|
||||
{ id: 3, number: '3', title: "Langkah 3", desc: "PPID akan memproses permohonan sesuai dengan ketentuan" },
|
||||
{ id: 4, number: '4', title: "Langkah 4", desc: "Petugas PPID menyampaikan informasi sesuai permohonan kepada pemohon informasi." },
|
||||
const steps = [
|
||||
{
|
||||
id: 1,
|
||||
number: '1',
|
||||
title: 'Ajukan Permohonan',
|
||||
desc: 'Pemohon mengajukan permohonan informasi kepada badan publik secara langsung atau melalui surat elektronik.',
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
number: '2',
|
||||
title: 'Isi Formulir',
|
||||
desc: 'Lengkapi formulir dengan identitas (nama, alamat, telepon, email), jenis, format, serta cara memperoleh informasi, dan lampirkan fotokopi identitas.',
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
number: '3',
|
||||
title: 'Proses oleh PPID',
|
||||
desc: 'PPID akan memproses permohonan sesuai ketentuan yang berlaku.',
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
number: '4',
|
||||
title: 'Penyampaian Informasi',
|
||||
desc: 'Petugas PPID memberikan informasi sesuai permohonan kepada pemohon.',
|
||||
},
|
||||
];
|
||||
|
||||
function Page() {
|
||||
@@ -24,87 +57,219 @@ function Page() {
|
||||
const submitForms = () => {
|
||||
const { create } = permohonanInformasiPublikState.statepermohonanInformasiPublik;
|
||||
|
||||
if (create.form.name && create.form.nik && create.form.notelp && create.form.alamat && create.form.email &&
|
||||
create.form.jenisInformasiDimintaId && create.form.caraMemperolehInformasiId && create.form.caraMemperolehSalinanInformasiId) {
|
||||
if (
|
||||
create.form.name &&
|
||||
create.form.nik &&
|
||||
create.form.notelp &&
|
||||
create.form.alamat &&
|
||||
create.form.email &&
|
||||
create.form.jenisInformasiDimintaId &&
|
||||
create.form.caraMemperolehInformasiId &&
|
||||
create.form.caraMemperolehSalinanInformasiId
|
||||
) {
|
||||
create.create();
|
||||
router.push('/darmasaba/permohonan/berhasil');
|
||||
} else {
|
||||
console.log("Validasi gagal, form tidak lengkap");
|
||||
// Display error message to user
|
||||
console.log('Validasi gagal, form tidak lengkap');
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Stack pos={"relative"} bg={colors.Bg} py={"xl"} gap={"22"}>
|
||||
<Stack pos="relative" bg={colors.Bg} py="xl" gap={40}>
|
||||
<Box px={{ base: 'md', md: 100 }}>
|
||||
<BackButton />
|
||||
</Box>
|
||||
<Text ta={"center"} fz={{ base: "h1", md: "2.5rem" }} c={colors["blue-button"]} fw={"bold"}>
|
||||
|
||||
<Text
|
||||
ta="center"
|
||||
fz={{ base: '2rem', md: '2.5rem' }}
|
||||
c={colors['blue-button']}
|
||||
fw="bold"
|
||||
>
|
||||
Permohonan Informasi Publik
|
||||
</Text>
|
||||
<Box px={{ base: "md", md: 100 }}>
|
||||
<Stack gap={'lg'}>
|
||||
<Paper p={"xl"} bg={colors['white-trans-1']}>
|
||||
<Text pb={30} ta={'center'} fw={"bold"} fz={{ base: 'h3', md: 'h2' }}>Tata Cara Permohonan</Text>
|
||||
<SimpleGrid pb={30} cols={{ base: 1, md: 2, lg: 3, xl: 4 }}>
|
||||
{data.map((v, k) => (
|
||||
<Paper key={k} p={"xl"} bg={colors['blue-button']}>
|
||||
<Stack justify='space-between'>
|
||||
|
||||
<Box px={{ base: 'md', md: 100 }}>
|
||||
<Stack gap="xl">
|
||||
<Paper
|
||||
p="xl"
|
||||
radius="lg"
|
||||
withBorder
|
||||
shadow="sm"
|
||||
bg={colors['white-trans-1']}
|
||||
>
|
||||
<Text
|
||||
pb={30}
|
||||
ta="center"
|
||||
fw="bold"
|
||||
fz={{ base: 'h4', md: 'h3' }}
|
||||
c={colors['blue-button']}
|
||||
>
|
||||
Tata Cara Permohonan
|
||||
</Text>
|
||||
|
||||
<SimpleGrid pb={30} cols={{ base: 1, sm: 2, lg: 4 }} spacing="lg">
|
||||
{steps.map((v) => (
|
||||
<Paper
|
||||
key={v.id}
|
||||
p="lg"
|
||||
radius="md"
|
||||
shadow="md"
|
||||
bg={colors['blue-button']}
|
||||
>
|
||||
<Stack justify="space-between" gap="sm">
|
||||
<Center>
|
||||
<ActionIcon bg={colors['white-1']} radius={150} size={50}>
|
||||
<Text c={colors['blue-button']} ta={"center"} fw={"bold"} fz={{ base: "h3", md: "h2" }}>{v.number}</Text>
|
||||
<ActionIcon
|
||||
bg={colors['white-1']}
|
||||
radius="xl"
|
||||
size={60}
|
||||
variant="light"
|
||||
>
|
||||
<Text
|
||||
c={colors['blue-button']}
|
||||
ta="center"
|
||||
fw="bold"
|
||||
fz="h3"
|
||||
>
|
||||
{v.number}
|
||||
</Text>
|
||||
</ActionIcon>
|
||||
</Center>
|
||||
<Text ta={"center"} c={colors['white-1']} fw={"bold"} fz={"h3"}>{v.title}</Text>
|
||||
<Text ta={"center"} c={colors['white-1']} fz={'h4'}>{v.desc}</Text>
|
||||
<Text
|
||||
ta="center"
|
||||
c={colors['white-1']}
|
||||
fw="bold"
|
||||
fz="lg"
|
||||
>
|
||||
{v.title}
|
||||
</Text>
|
||||
<Text ta="center" c={colors['white-1']} fz="sm">
|
||||
{v.desc}
|
||||
</Text>
|
||||
</Stack>
|
||||
</Paper>
|
||||
))}
|
||||
</SimpleGrid>
|
||||
|
||||
<Center pb={30}>
|
||||
<Button fz={"h5"} bg={colors['blue-button']} leftSection={<IconDownload size={20} color={colors['white-1']} />}>
|
||||
Unduh Dokumen
|
||||
</Button>
|
||||
<Tooltip label="Unduh dokumen tata cara permohonan" withArrow>
|
||||
<Button
|
||||
fz="sm"
|
||||
size="md"
|
||||
radius="md"
|
||||
bg={colors['blue-button']}
|
||||
leftSection={
|
||||
<IconDownload size={20} color={colors['white-1']} />
|
||||
}
|
||||
>
|
||||
Unduh Tata Cara
|
||||
</Button>
|
||||
</Tooltip>
|
||||
</Center>
|
||||
<Group justify='center'>
|
||||
<Paper p={'xl'} bg={colors['white-1']}>
|
||||
<Stack gap={"xs"}>
|
||||
<Text fw={"bold"} fz={{ base: 'h4', md: 'h3' }} ta={"center"}>Formulir Permohonan Informasi</Text>
|
||||
<TextInput label="Nama Lengkap" placeholder="masukkan nama lengkap" onChange={(val) => {
|
||||
permohonanInformasiPublikState.statepermohonanInformasiPublik.create.form.name = val.target.value;
|
||||
}} />
|
||||
<TextInput label="NIK" placeholder="masukkan NIK" onChange={(val) => {
|
||||
permohonanInformasiPublikState.statepermohonanInformasiPublik.create.form.nik = val.target.value;
|
||||
}} />
|
||||
<TextInput label="No.Telp" placeholder="masukkan no telp" onChange={(val) => {
|
||||
permohonanInformasiPublikState.statepermohonanInformasiPublik.create.form.notelp = val.target.value;
|
||||
}} />
|
||||
<TextInput label="Alamat" placeholder="masukkan alamat" onChange={(val) => {
|
||||
permohonanInformasiPublikState.statepermohonanInformasiPublik.create.form.alamat = val.target.value;
|
||||
}} />
|
||||
<TextInput label="Email" placeholder="masukkan email" onChange={(val) => {
|
||||
permohonanInformasiPublikState.statepermohonanInformasiPublik.create.form.email = val.target.value;
|
||||
}} />
|
||||
<JenisInformasiSelector
|
||||
|
||||
<Group justify="center">
|
||||
<Paper
|
||||
p="xl"
|
||||
radius="lg"
|
||||
withBorder
|
||||
shadow="sm"
|
||||
bg={colors['white-1']}
|
||||
w="100%"
|
||||
maw={800}
|
||||
>
|
||||
<Stack gap="md">
|
||||
<Text
|
||||
fw="bold"
|
||||
fz={{ base: 'h4', md: 'h3' }}
|
||||
ta="center"
|
||||
c={colors['blue-button']}
|
||||
>
|
||||
Formulir Permohonan Informasi
|
||||
</Text>
|
||||
|
||||
<TextInput
|
||||
label="Nama Lengkap"
|
||||
placeholder="Masukkan nama lengkap Anda"
|
||||
withAsterisk
|
||||
onChange={(val) => {
|
||||
permohonanInformasiPublikState.statepermohonanInformasiPublik.create.form.jenisInformasiDimintaId = val.id;
|
||||
permohonanInformasiPublikState.statepermohonanInformasiPublik.create.form.name =
|
||||
val.target.value;
|
||||
}}
|
||||
/>
|
||||
<MemperolehInformasi
|
||||
<TextInput
|
||||
label="Nomor Induk Kependudukan (NIK)"
|
||||
placeholder="Masukkan NIK"
|
||||
withAsterisk
|
||||
onChange={(val) => {
|
||||
permohonanInformasiPublikState.statepermohonanInformasiPublik.create.form.caraMemperolehInformasiId = val.id;
|
||||
}}
|
||||
permohonanInformasiPublikState.statepermohonanInformasiPublik.create.form.nik =
|
||||
val.target.value;
|
||||
}}
|
||||
/>
|
||||
<MemperolehSalinan
|
||||
<TextInput
|
||||
label="Nomor Telepon"
|
||||
placeholder="Masukkan nomor telepon aktif"
|
||||
withAsterisk
|
||||
onChange={(val) => {
|
||||
permohonanInformasiPublikState.statepermohonanInformasiPublik.create.form.caraMemperolehSalinanInformasiId = val.id;
|
||||
}}
|
||||
permohonanInformasiPublikState.statepermohonanInformasiPublik.create.form.notelp =
|
||||
val.target.value;
|
||||
}}
|
||||
/>
|
||||
<Box py={10}>
|
||||
<Checkbox label="Saya menyatakan bahwa informasi yang saya berikan adalah benar dan akan menggunakan informasi yang diminta" />
|
||||
<TextInput
|
||||
label="Alamat Lengkap"
|
||||
placeholder="Masukkan alamat sesuai identitas"
|
||||
withAsterisk
|
||||
onChange={(val) => {
|
||||
permohonanInformasiPublikState.statepermohonanInformasiPublik.create.form.alamat =
|
||||
val.target.value;
|
||||
}}
|
||||
/>
|
||||
<TextInput
|
||||
label="Alamat Email"
|
||||
placeholder="Masukkan alamat email aktif"
|
||||
withAsterisk
|
||||
onChange={(val) => {
|
||||
permohonanInformasiPublikState.statepermohonanInformasiPublik.create.form.email =
|
||||
val.target.value;
|
||||
}}
|
||||
/>
|
||||
|
||||
<JenisInformasiSelector
|
||||
onChange={(val) => {
|
||||
permohonanInformasiPublikState.statepermohonanInformasiPublik.create.form.jenisInformasiDimintaId =
|
||||
val.id;
|
||||
}}
|
||||
/>
|
||||
<MemperolehInformasi
|
||||
onChange={(val) => {
|
||||
permohonanInformasiPublikState.statepermohonanInformasiPublik.create.form.caraMemperolehInformasiId =
|
||||
val.id;
|
||||
}}
|
||||
/>
|
||||
<MemperolehSalinan
|
||||
onChange={(val) => {
|
||||
permohonanInformasiPublikState.statepermohonanInformasiPublik.create.form.caraMemperolehSalinanInformasiId =
|
||||
val.id;
|
||||
}}
|
||||
/>
|
||||
|
||||
<Box py="sm">
|
||||
<Checkbox
|
||||
size="sm"
|
||||
color={colors['blue-button']}
|
||||
label="Saya menyatakan bahwa data yang saya berikan benar adanya dan informasi yang diminta akan digunakan sesuai ketentuan."
|
||||
/>
|
||||
</Box>
|
||||
<Group>
|
||||
<Button bg={colors['blue-button']} onClick={submitForms}>Kirim Permohonan</Button>
|
||||
|
||||
<Group justify="center" pt="sm">
|
||||
<Button
|
||||
size="md"
|
||||
radius="md"
|
||||
bg={colors['blue-button']}
|
||||
leftSection={<IconSend2 size={20} color={colors['white-1']} />}
|
||||
onClick={submitForms}
|
||||
>
|
||||
Kirim Permohonan
|
||||
</Button>
|
||||
</Group>
|
||||
</Stack>
|
||||
</Paper>
|
||||
@@ -116,4 +281,4 @@ function Page() {
|
||||
);
|
||||
}
|
||||
|
||||
export default Page;
|
||||
export default Page;
|
||||
|
||||
@@ -2,136 +2,243 @@
|
||||
import permohonanKeberatanInformasi from '@/app/admin/(dashboard)/_state/ppid/permohonan_keberatan_informasi_publik/permohonanKeberatanInformasi';
|
||||
import { PPIDTextEditor } from '@/app/admin/(dashboard)/ppid/_com/PPIDTextEditor';
|
||||
import colors from '@/con/colors';
|
||||
import { Box, Button, Center, Group, Paper, SimpleGrid, Stack, Text, TextInput } from '@mantine/core';
|
||||
import { IconFileCheck, IconForms, IconHourglassOff, IconPhoneRinging } from '@tabler/icons-react';
|
||||
import {
|
||||
Box,
|
||||
Button,
|
||||
Center,
|
||||
Group,
|
||||
Paper,
|
||||
SimpleGrid,
|
||||
Stack,
|
||||
Text,
|
||||
TextInput,
|
||||
Tooltip,
|
||||
} from '@mantine/core';
|
||||
import {
|
||||
IconFileCheck,
|
||||
IconForms,
|
||||
IconHourglassOff,
|
||||
IconPhoneRinging,
|
||||
} from '@tabler/icons-react';
|
||||
import { useRouter } from 'next/navigation';
|
||||
import { useProxy } from 'valtio/utils';
|
||||
import BackButton from '../../desa/layanan/_com/BackButto';
|
||||
|
||||
const data = [
|
||||
{
|
||||
id: 1,
|
||||
icon: <IconForms size={50} color={colors['white-1']} />,
|
||||
title: "Formulir Online",
|
||||
desc: "Isi formulir keberatan secara online.",
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
icon: <IconFileCheck size={50} color={colors['white-1']} />,
|
||||
title: "Verifikasi",
|
||||
desc: "Tim PPID akan memverifikasi permohonan Anda.",
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
icon: <IconHourglassOff size={50} color={colors['white-1']} />,
|
||||
title: "Proses Keberatan",
|
||||
desc: "Proses penyelesaian keberatan dalam waktu 30 hari kerja.",
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
icon: <IconPhoneRinging size={50} color={colors['white-1']} />,
|
||||
title: "Hasil",
|
||||
desc: "Hasil keberatan akan dikirim via email atau SMS.",
|
||||
},
|
||||
]
|
||||
{
|
||||
id: 1,
|
||||
icon: IconForms,
|
||||
title: 'Isi Formulir',
|
||||
desc: 'Lengkapi formulir keberatan secara online dengan mudah.',
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
icon: IconFileCheck,
|
||||
title: 'Verifikasi Data',
|
||||
desc: 'Tim PPID akan memeriksa dan memverifikasi permohonan Anda.',
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
icon: IconHourglassOff,
|
||||
title: 'Proses Keberatan',
|
||||
desc: 'Keberatan diproses maksimal dalam 30 hari kerja.',
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
icon: IconPhoneRinging,
|
||||
title: 'Hasil Dikirim',
|
||||
desc: 'Hasil keputusan dikirim melalui email atau WhatsApp.',
|
||||
},
|
||||
];
|
||||
|
||||
function Page() {
|
||||
const stateKeberatan = useProxy(permohonanKeberatanInformasi)
|
||||
const submit = () => {
|
||||
if (stateKeberatan.create.form.name && stateKeberatan.create.form.email && stateKeberatan.create.form.notelp && stateKeberatan.create.form.alasan) {
|
||||
stateKeberatan.create.create()
|
||||
router.push('/darmasaba/permohonan/berhasil')
|
||||
} else {
|
||||
console.log("Validasi gagal, form tidak lengkap")
|
||||
}
|
||||
const stateKeberatan = useProxy(permohonanKeberatanInformasi);
|
||||
const router = useRouter();
|
||||
|
||||
const submit = () => {
|
||||
if (
|
||||
stateKeberatan.create.form.name &&
|
||||
stateKeberatan.create.form.email &&
|
||||
stateKeberatan.create.form.notelp &&
|
||||
stateKeberatan.create.form.alasan
|
||||
) {
|
||||
stateKeberatan.create.create();
|
||||
router.push('/darmasaba/permohonan/berhasil');
|
||||
} else {
|
||||
console.log('Formulir belum lengkap');
|
||||
}
|
||||
const router = useRouter();
|
||||
return (
|
||||
<Stack pos={"relative"} bg={colors.Bg} py={"xl"} gap={"22"}>
|
||||
<Box px={{ base: 'md', md: 100 }}>
|
||||
<BackButton />
|
||||
};
|
||||
|
||||
return (
|
||||
<Stack bg={colors.Bg} py="xl" gap={40}>
|
||||
<Box px={{ base: 'md', md: 100 }}>
|
||||
<BackButton />
|
||||
</Box>
|
||||
|
||||
<Stack align="center" px={{ base: 'md', md: 100 }}>
|
||||
<Text
|
||||
ta="center"
|
||||
fz={{ base: '2rem', md: '2.8rem' }}
|
||||
c={colors['blue-button']}
|
||||
fw={800}
|
||||
style={{ letterSpacing: '-0.5px' }}
|
||||
>
|
||||
Permohonan Keberatan Informasi Publik
|
||||
</Text>
|
||||
|
||||
<Paper
|
||||
p="xl"
|
||||
radius="xl"
|
||||
bg={colors['white-trans-1']}
|
||||
shadow="sm"
|
||||
withBorder
|
||||
>
|
||||
<Stack gap="xl">
|
||||
<Box>
|
||||
<Text fw={700} fz={{ base: 'lg', md: 'xl' }} mb={8}>
|
||||
Tentang Permohonan Keberatan
|
||||
</Text>
|
||||
<Text ta="justify" fz={{ base: 'sm', md: 'md' }} lh={1.6}>
|
||||
Jika Anda merasa permohonan informasi tidak ditanggapi dengan
|
||||
baik atau ditolak, Anda berhak mengajukan keberatan melalui
|
||||
formulir berikut.
|
||||
</Text>
|
||||
</Box>
|
||||
<Text ta={"center"} fz={{ base: "h1", md: "2.5rem" }} c={colors["blue-button"]} fw={"bold"}>
|
||||
Permohonan Keberatan Informasi Publik
|
||||
</Text>
|
||||
<Box px={{ base: "md", md: 100 }}>
|
||||
<Stack gap={'lg'}>
|
||||
<Paper p={"xl"} bg={colors['white-trans-1']}>
|
||||
<Box pb={30}>
|
||||
<Text fw={"bold"} fz={{ base: 'h4', md: 'h3' }}>Tentang Permohonan Keberatan</Text>
|
||||
<Text ta={"justify"} fz={{ base: 'md', md: 'h4' }}>Jika Anda merasa permohonan informasi yang diajukan tidak mendapatkan tanggapan yang memadai atau ditolak, anda berhak mengajukan
|
||||
keberatan melalui formulir di bawah ini.</Text>
|
||||
</Box>
|
||||
<Text pb={20} ta={"center"} fw={"bold"} fz={{ base: 'h3', md: 'h2' }}>Bagaimana Mengajukan Keberatan?</Text>
|
||||
<SimpleGrid
|
||||
pb={30}
|
||||
cols={{
|
||||
base: 1,
|
||||
md: 4,
|
||||
}}>
|
||||
{data.map((v, k) => {
|
||||
return (
|
||||
<Paper key={k} p={"xl"} bg={colors['blue-button']}>
|
||||
<Stack justify='space-between'>
|
||||
<Center>
|
||||
{v.icon}
|
||||
</Center>
|
||||
<Text ta={"center"} c={colors['white-1']} fw={"bold"} fz={"h3"}>
|
||||
{v.title}
|
||||
</Text>
|
||||
<Text ta={"center"} c={colors['white-1']} fz={'h4'}>
|
||||
{v.desc}
|
||||
</Text>
|
||||
</Stack>
|
||||
</Paper>
|
||||
)
|
||||
})}
|
||||
</SimpleGrid>
|
||||
<Group justify='center'>
|
||||
<Paper p={'xl'} bg={colors['white-1']}>
|
||||
<Stack gap={"xs"}>
|
||||
<Text fw={"bold"} fz={{ base: 'h4', md: 'h3' }} ta={"center"}>Formulir Permohonan Keberatan</Text>
|
||||
<TextInput
|
||||
label="Nama"
|
||||
placeholder="masukkan nama lengkap"
|
||||
onChange={(val) => {
|
||||
stateKeberatan.create.form.name = val.target.value
|
||||
}}
|
||||
/>
|
||||
<TextInput
|
||||
label="Email"
|
||||
placeholder="masukkan email"
|
||||
onChange={(val) => {
|
||||
stateKeberatan.create.form.email = val.target.value
|
||||
}}
|
||||
/>
|
||||
<TextInput
|
||||
label="Nomor Telepon"
|
||||
placeholder="masukkan nomor telepon"
|
||||
onChange={(val) => {
|
||||
stateKeberatan.create.form.notelp = val.target.value
|
||||
}}
|
||||
/>
|
||||
<Text fz={"sm"}>Alasan Permohonan Keberatan</Text>
|
||||
<PPIDTextEditor
|
||||
showSubmit={false}
|
||||
onChange={(val) => {
|
||||
stateKeberatan.create.form.alasan = val
|
||||
}}
|
||||
|
||||
/>
|
||||
<Group>
|
||||
<Button onClick={submit} bg={'green'}>Kirim Permohonan</Button>
|
||||
</Group>
|
||||
</Stack>
|
||||
</Paper>
|
||||
</Group>
|
||||
<Text pt={20} ta={"center"} fz={'h3'} fw={"bold"}>Kontak PPID</Text>
|
||||
<Text ta={"center"} fz={"sm"}>Email: desadarmasaba@badungkab.go.id | WhatsApp: 081-xxx-xxx-xxx</Text>
|
||||
</Paper>
|
||||
|
||||
<Stack>
|
||||
<Text
|
||||
ta="center"
|
||||
fw={700}
|
||||
fz={{ base: 'xl', md: '2xl' }}
|
||||
style={{ letterSpacing: '-0.5px' }}
|
||||
>
|
||||
Alur Pengajuan Keberatan
|
||||
</Text>
|
||||
|
||||
<SimpleGrid cols={{ base: 1, md: 4 }} spacing="lg">
|
||||
{data.map((v) => (
|
||||
<Paper
|
||||
key={v.id}
|
||||
p="lg"
|
||||
radius="lg"
|
||||
bg={colors['blue-button']}
|
||||
shadow="md"
|
||||
>
|
||||
<Stack align="center" gap="sm">
|
||||
<Center>
|
||||
<v.icon size={48} color={colors['white-1']} />
|
||||
</Center>
|
||||
<Text
|
||||
ta="center"
|
||||
c={colors['white-1']}
|
||||
fw={700}
|
||||
fz="lg"
|
||||
>
|
||||
{v.title}
|
||||
</Text>
|
||||
<Text ta="center" c={colors['white-1']} fz="sm">
|
||||
{v.desc}
|
||||
</Text>
|
||||
</Stack>
|
||||
</Paper>
|
||||
))}
|
||||
</SimpleGrid>
|
||||
</Stack>
|
||||
|
||||
<Group justify="center">
|
||||
<Paper
|
||||
p="xl"
|
||||
radius="xl"
|
||||
bg={colors['white-1']}
|
||||
shadow="md"
|
||||
withBorder
|
||||
maw={600}
|
||||
w="100%"
|
||||
>
|
||||
<Stack gap="md">
|
||||
<Text
|
||||
fw={700}
|
||||
fz={{ base: 'lg', md: 'xl' }}
|
||||
ta="center"
|
||||
mb={4}
|
||||
>
|
||||
Formulir Keberatan
|
||||
</Text>
|
||||
|
||||
<TextInput
|
||||
label="Nama Lengkap"
|
||||
placeholder="Tulis nama lengkap Anda"
|
||||
radius="md"
|
||||
size="md"
|
||||
withAsterisk
|
||||
onChange={(val) =>
|
||||
(stateKeberatan.create.form.name = val.target.value)
|
||||
}
|
||||
/>
|
||||
|
||||
<TextInput
|
||||
label="Alamat Email"
|
||||
placeholder="contoh: nama@email.com"
|
||||
radius="md"
|
||||
size="md"
|
||||
type="email"
|
||||
withAsterisk
|
||||
onChange={(val) =>
|
||||
(stateKeberatan.create.form.email = val.target.value)
|
||||
}
|
||||
/>
|
||||
|
||||
<TextInput
|
||||
label="Nomor Telepon"
|
||||
placeholder="contoh: 0812-3456-7890"
|
||||
radius="md"
|
||||
size="md"
|
||||
withAsterisk
|
||||
onChange={(val) =>
|
||||
(stateKeberatan.create.form.notelp = val.target.value)
|
||||
}
|
||||
/>
|
||||
|
||||
<Box>
|
||||
<Text fw={600} fz="sm" mb={6}>
|
||||
Alasan Keberatan
|
||||
</Text>
|
||||
<PPIDTextEditor
|
||||
showSubmit={false}
|
||||
onChange={(val) =>
|
||||
(stateKeberatan.create.form.alasan = val)
|
||||
}
|
||||
/>
|
||||
</Box>
|
||||
|
||||
<Tooltip label="Pastikan semua data sudah diisi dengan benar">
|
||||
<Button
|
||||
onClick={submit}
|
||||
size="md"
|
||||
radius="md"
|
||||
fw={600}
|
||||
bg={colors['blue-button']}
|
||||
>
|
||||
Kirim Permohonan
|
||||
</Button>
|
||||
</Tooltip>
|
||||
</Stack>
|
||||
</Box>
|
||||
</Stack>
|
||||
);
|
||||
</Paper>
|
||||
</Group>
|
||||
|
||||
<Stack gap={4} pt="lg" align="center">
|
||||
<Text fw={700} fz="lg">
|
||||
Kontak PPID
|
||||
</Text>
|
||||
<Text fz="sm" c="dimmed">
|
||||
Email: desadarmasaba@badungkab.go.id | WhatsApp: 081-xxx-xxx-xxx
|
||||
</Text>
|
||||
</Stack>
|
||||
</Stack>
|
||||
</Paper>
|
||||
</Stack>
|
||||
</Stack>
|
||||
);
|
||||
}
|
||||
|
||||
export default Page;
|
||||
|
||||
@@ -1,58 +1,100 @@
|
||||
'use client'
|
||||
import stateVisiMisiPPID from '@/app/admin/(dashboard)/_state/ppid/visi_misi_ppid/visimisiPPID';
|
||||
import colors from '@/con/colors';
|
||||
import { Box, Center, Image, Paper, Skeleton, Stack, Text } from '@mantine/core';
|
||||
import { Box, Center, Image, Paper, Skeleton, Stack, Text, Divider, Transition } from '@mantine/core';
|
||||
import { useShallowEffect } from '@mantine/hooks';
|
||||
import { useProxy } from 'valtio/utils';
|
||||
import { IconSparkles } from '@tabler/icons-react';
|
||||
import BackButton from '../../desa/layanan/_com/BackButto';
|
||||
|
||||
function Page() {
|
||||
const allList = useProxy(stateVisiMisiPPID)
|
||||
const allList = useProxy(stateVisiMisiPPID);
|
||||
useShallowEffect(() => {
|
||||
allList.findById.load("1") // Assuming "1" is your default ID, adjust as needed
|
||||
}, [])
|
||||
allList.findById.load("1");
|
||||
}, []);
|
||||
|
||||
if (!allList.findById.data) return <Stack>
|
||||
{Array.from({ length: 10 }).map((v, k) => <Skeleton key={k} h={40} />)}
|
||||
</Stack>
|
||||
if (!allList.findById.data) {
|
||||
return (
|
||||
<Stack p="xl" gap="sm">
|
||||
{Array.from({ length: 6 }).map((_, k) => (
|
||||
<Skeleton key={k} h={60} radius="lg" />
|
||||
))}
|
||||
</Stack>
|
||||
);
|
||||
}
|
||||
|
||||
const dataArray = Array.isArray(allList.findById.data)
|
||||
? allList.findById.data
|
||||
: [allList.findById.data];
|
||||
|
||||
return (
|
||||
<Stack pos={"relative"} bg={colors.Bg} py={"xl"} gap={"22"}>
|
||||
<Stack bg={colors.Bg} py="xl" gap={40}>
|
||||
<Box px={{ base: 'md', md: 100 }}>
|
||||
<BackButton />
|
||||
</Box>
|
||||
|
||||
{dataArray.map((item) => (
|
||||
<Box key={item.id} px={{ base: "md", md: 100 }}>
|
||||
<Stack gap={'lg'}>
|
||||
<Paper p={"xl"} bg={colors['white-trans-1']}>
|
||||
<Box pb={30}>
|
||||
<Center>
|
||||
<Image src={"/darmasaba-icon.png"} w={{ base: 100, md: 150 }} alt='' />
|
||||
</Center>
|
||||
<Text ta={"center"} fz={{ base: "h2", md: "2.5rem" }} fw={"bold"}>
|
||||
MOTO PPID DESA DARMASABA
|
||||
</Text>
|
||||
<Text ta={"center"} fz={{ base: "h4", md: "h3" }} >
|
||||
MEMBERIKAN INFORMASI YANG CEPAT, MUDAH, TEPAT DAN TRANSPARAN
|
||||
</Text>
|
||||
</Box>
|
||||
<Box px={{ base: 20, md: 50 }} pb={30}>
|
||||
<Text ta={"center"} fz={{ base: "h3", md: "h2" }} fw={"bold"}>
|
||||
VISI PPID
|
||||
</Text>
|
||||
<Text fz={{ base: "md", md: "h3" }} ta={"justify"} dangerouslySetInnerHTML={{ __html: item.visi }} />
|
||||
</Box>
|
||||
<Box px={{ base: 20, md: 50 }}>
|
||||
<Text ta={"center"} fz={{ base: "h3", md: "h2" }} fw={"bold"}>
|
||||
MISI PPID
|
||||
</Text>
|
||||
<Text fz={{ base: "md", md: "h3" }} ta={"justify"} dangerouslySetInnerHTML={{ __html: item.misi }} />
|
||||
</Box>
|
||||
</Paper>
|
||||
</Stack>
|
||||
<Box key={item.id} px={{ base: 'md', md: 100 }}>
|
||||
<Transition mounted={true} transition="fade" duration={500} timingFunction="ease">
|
||||
{(styles) => (
|
||||
<Paper
|
||||
style={styles}
|
||||
p={{ base: 'lg', md: 'xl' }}
|
||||
radius="2xl"
|
||||
shadow="xl"
|
||||
bg={colors['white-trans-1']}
|
||||
withBorder
|
||||
>
|
||||
<Stack gap="xl">
|
||||
<Box>
|
||||
<Center mb="md">
|
||||
<Image src="/darmasaba-icon.png" w={{ base: 80, md: 130 }} alt="Logo Desa Darmasaba" />
|
||||
</Center>
|
||||
<Text
|
||||
ta="center"
|
||||
fz={{ base: 28, md: 36 }}
|
||||
fw={800}
|
||||
variant="gradient"
|
||||
gradient={{ from: colors['blue-button'], to: 'cyan', deg: 45 }}
|
||||
>
|
||||
Moto PPID Desa Darmasaba
|
||||
</Text>
|
||||
<Text ta="center" fz={{ base: 16, md: 20 }} mt="xs" c="dimmed">
|
||||
Memberikan informasi yang cepat, mudah, tepat, dan transparan
|
||||
</Text>
|
||||
</Box>
|
||||
|
||||
<Divider my="sm" labelPosition="center" label={<IconSparkles size={18} />} />
|
||||
|
||||
<Box>
|
||||
<Text ta="center" fz={{ base: 24, md: 30 }} fw={700} mb="sm">
|
||||
Visi PPID
|
||||
</Text>
|
||||
<Text
|
||||
fz={{ base: 'md', md: 'lg' }}
|
||||
lh={1.7}
|
||||
ta="justify"
|
||||
dangerouslySetInnerHTML={{ __html: item.visi }}
|
||||
/>
|
||||
</Box>
|
||||
|
||||
<Divider my="sm" />
|
||||
|
||||
<Box>
|
||||
<Text ta="center" fz={{ base: 24, md: 30 }} fw={700} mb="sm">
|
||||
Misi PPID
|
||||
</Text>
|
||||
<Text
|
||||
fz={{ base: 'md', md: 'lg' }}
|
||||
lh={1.7}
|
||||
ta="justify"
|
||||
dangerouslySetInnerHTML={{ __html: item.misi }}
|
||||
/>
|
||||
</Box>
|
||||
</Stack>
|
||||
</Paper>
|
||||
)}
|
||||
</Transition>
|
||||
</Box>
|
||||
))}
|
||||
</Stack>
|
||||
|
||||
Reference in New Issue
Block a user